<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def apply(self, func, applyto='measurement', noneval=nan, setdata=False):
 """ Apply func either to self or to associated data. If data is not already parsed, try and read it. Parameters func : callable The function either accepts a measurement object or an FCS object. Does some calculation and returns the result. applyto : ['data' | 'measurement'] * 'data' : apply to associated data * 'measurement' : apply to measurement object itself. noneval : obj Value to return if `applyto` is 'data', but no data is available. setdata : bool Used only if data is not already set. If true parsed data will be assigned to self.data Otherwise data will be discarded at end of apply. """

        applyto = applyto.lower()
        if applyto == 'data':
            if self.data is not None:
                data = self.data
            elif self.datafile is None:
                return noneval
            else:
                data = self.read_data()
                if setdata:
                    self.data = data
            return func(data)
        elif applyto == 'measurement':
            return func(self)
        else:
            raise ValueError('Encountered unsupported value "%s" for applyto parameter.' % applyto)