def test_hlog(self): hlpos = trans.hlog(_xpos) hlneg = trans.hlog(_xneg) assert_almost_equal((hlpos[-1] - _ymax) / _ymax, 0, decimal=2) assert_almost_equal(hlpos, -hlneg[::-1]) # check symmetry # test that values get larger as b decreases hlpos10 = trans.hlog(_xpos, b=10) self.assertTrue(np.all(hlpos10 >= hlpos)) # check that converges to tlog for large values tlpos = trans.tlog(_xpos) i = np.where(_xpos > 1e4)[0] tlpos_large = tlpos[i] hlpos_large = hlpos10[i] d = (hlpos_large - tlpos_large) / hlpos_large assert_almost_equal(d, np.zeros(len(d)), decimal=2) # test spline option transformation = Transformation(transform='hlog', direction='forward') result1 = transformation(_xall, use_spln=True) result2 = transformation(_xall, use_spln=False) d = (result1 - result2) / result1 assert_almost_equal(d, np.zeros(len(d)), decimal=2)
def transform(self, transform, direction='forward', share_transform=True, channels=None, return_all=True, auto_range=True, use_spln=True, get_transformer=False, ID=None, apply_now=True, args=(), **kwargs): ''' Apply transform to each Measurement in the Collection. Return a new Collection with transformed data. {_containers_held_in_memory_warning} Parameters ---------- {FCMeasurement_transform_pars} ID : hashable | None ID for the resulting collection. If None is passed, the original ID is used. Returns ------- new : FCCollection New collection containing the transformed measurements. transformer : Transformation The Transformation applied to the measurements. Only returned if get_transformer=True & share_transform=True. Examples -------- {FCMeasurement_transform_examples} ''' new = self.copy() if share_transform: channel_meta = self.values()[0].channels channel_names = self.values()[0].channel_names if channels is None: channels = list(channel_names) else: channels = to_list(channels) ## create transformer if isinstance(transform, Transformation): transformer = transform else: if auto_range: # determine transformation range if 'd' in kwargs: warnings.warn('Encountered both auto_range=True and user-specified range ' 'value in parameter d.\n ' 'Range value specified in parameter d is used.') else: # the -1 below because the channel numbers begin from 1 instead of 0 (this is fragile code) ranges = [float(r['$PnR']) for i, r in channel_meta.iterrows() if channel_names[i - 1] in channels] if not np.allclose(ranges, ranges[0]): raise Exception('Not all specified channels have the same ' 'data range, therefore they cannot be ' 'transformed together.') if transform in {'hlog', 'tlog', 'hlog_inv', 'tlog_inv'}: # Hacky fix to make sure that 'd' is provided only # for hlog / tlog transformations kwargs['d'] = np.log10(ranges[0]) transformer = Transformation(transform, direction, args, **kwargs) if use_spln: xmax = self.apply(lambda x: x[channels].max().max(), applyto='data').max().max() xmin = self.apply(lambda x: x[channels].min().min(), applyto='data').min().min() transformer.set_spline(xmin, xmax) ## transform all measurements for k, v in new.iteritems(): new[k] = v.transform(transformer, channels=channels, return_all=return_all, use_spln=use_spln, apply_now=apply_now) else: for k, v in new.iteritems(): new[k] = v.transform(transform, direction=direction, channels=channels, return_all=return_all, auto_range=auto_range, get_transformer=False, use_spln=use_spln, apply_now=apply_now, args=args, **kwargs) if ID is not None: new.ID = ID if share_transform and get_transformer: return new, transformer else: return new
def transform(self, transform, direction='forward', channels=None, return_all=True, auto_range=True, use_spln=True, get_transformer=False, ID=None, apply_now=True, args=(), **kwargs): """ Applies a transformation to the specified channels. The transformation parameters are shared between all transformed channels. If different parameters need to be applied to different channels, use several calls to `transform`. Parameters ---------- {FCMeasurement_transform_pars} ID : hashable | None ID for the resulting collection. If None is passed, the original ID is used. Returns ------- new : FCMeasurement New measurement containing the transformed data. transformer : Transformation The Transformation applied to the input measurement. Only returned if get_transformer=True. Examples -------- {FCMeasurement_transform_examples} """ # Create new measurement new = self.copy() data = new.data channels = to_list(channels) if channels is None: channels = data.columns ## create transformer if isinstance(transform, Transformation): transformer = transform else: if auto_range: # determine transformation range if 'd' in kwargs: warnings.warn( 'Encountered both auto_range=True and user-specified range value in ' 'parameter d.\n Range value specified in parameter d is used.') else: channel_meta = self.channels # the -1 below because the channel numbers begin from 1 instead of 0 # (this is fragile code) ranges = [float(r['$PnR']) for i, r in channel_meta.iterrows() if self.channel_names[i - 1] in channels] if not np.allclose(ranges, ranges[0]): raise Exception("""Not all specified channels have the same data range, therefore they cannot be transformed together.\n HINT: Try transforming one channel at a time. You'll need to provide the name of the channel in the transform.""") if transform in {'hlog', 'tlog', 'hlog_inv', 'tlog_inv'}: # Hacky fix to make sure that 'd' is provided only # for hlog / tlog transformations kwargs['d'] = np.log10(ranges[0]) transformer = Transformation(transform, direction, args, **kwargs) ## create new data transformed = transformer(data[channels], use_spln) if return_all: new_data = data else: new_data = data.filter(channels) new_data[channels] = transformed ## update new Measurement new.data = new_data if ID is not None: new.ID = ID if get_transformer: return new, transformer else: return new
def transform(self, transform, direction='forward', share_transform=True, channels=None, return_all=True, auto_range=True, use_spln=True, get_transformer=False, ID=None, apply_now=True, args=(), **kwargs): ''' Apply transform to each Measurement in the Collection. Return a new Collection with transformed data. {_containers_held_in_memory_warning} Parameters ---------- {FCMeasurement_transform_pars} ID : hashable | None ID for the resulting collection. If None is passed, the original ID is used. Returns ------- new : FCCollection New collection containing the transformed measurements. transformer : Transformation The Transformation applied to the measurements. Only returned if get_transformer=True & share_transform=True. Examples -------- {FCMeasurement_transform_examples} ''' new = self.copy() if share_transform: channel_meta = self.values()[0].channels channel_names = self.values()[0].channel_names if channels is None: channels = list(channel_names) else: channels = to_list(channels) ## create transformer if isinstance(transform, Transformation): transformer = transform else: if auto_range: # determine transformation range if 'd' in kwargs: warnings.warn('Encountered both auto_range=True and user-specified range ' 'value in parameter d.\n ' 'Range value specified in parameter d is used.') else: # the -1 below because the channel numbers begin from 1 instead of 0 (this is fragile code) ranges = [float(r['$PnR']) for i, r in channel_meta.iterrows() if channel_names[i - 1] in channels] if not np.allclose(ranges, ranges[0]): raise Exception('Not all specified channels have the same ' 'data range, therefore they cannot be ' 'transformed together.') kwargs['d'] = np.log10(ranges[0]) transformer = Transformation(transform, direction, args, **kwargs) if use_spln: xmax = self.apply(lambda x: x[channels].max().max(), applyto='data').max().max() xmin = self.apply(lambda x: x[channels].min().min(), applyto='data').min().min() transformer.set_spline(xmin, xmax) ## transform all measurements for k, v in new.iteritems(): new[k] = v.transform(transformer, channels=channels, return_all=return_all, use_spln=use_spln, apply_now=apply_now) else: for k, v in new.iteritems(): new[k] = v.transform(transform, direction=direction, channels=channels, return_all=return_all, auto_range=auto_range, get_transformer=False, use_spln=use_spln, apply_now=apply_now, args=args, **kwargs) if ID is not None: new.ID = ID if share_transform and get_transformer: return new, transformer else: return new