def apply(self): # this is special, we want the actual event weights in the histo # therefor we're overwritting the apply function # normally in a stage you would implement the `apply_function` method # and not the `apply` method! if self.input_mode == 'binned': self.data.data_specs = self.output_specs for container in self.data: # calcualte errors if self.error_method in ['sumw2']: vectorizer.square(container['weights'], out=container['weights_squared']) vectorizer.sqrt(container['weights_squared'], out=container['errors']) elif self.input_mode == 'events': for container in self.data: self.data.data_specs = self.input_specs # calcualte errors if self.error_method in ['sumw2']: vectorizer.square(container['weights'], out=container['weights_squared']) self.data.data_specs = self.output_specs container.array_to_binned('weights', self.output_specs, averaged=False) if self.error_method in ['sumw2']: container.array_to_binned('weights_squared', self.output_specs, averaged=False) vectorizer.sqrt(container['weights_squared'], out=container['errors'])
def apply(self): # DO NOT USE THIS STAGE AS YOUR TEMPLATE IF YOU ARE NEW TO PISA! # -------------------------------------------------------------- # # We are overwriting the `apply` method rather than the `apply_function` method # because we are manipulating the data binning in a delicate way that doesn't # work with automatic rebinning. self.data.data_specs = self.input_specs if self.scale_errors: for container in self.data: vectorizer.pow( vals=container["errors"], pwr=2, out=container["variances"], ) input_binvols = SmartArray( self.input_specs.weighted_bin_volumes(attach_units=False).ravel()) output_binvols = SmartArray( self.output_specs.weighted_bin_volumes(attach_units=False).ravel()) for container in self.data: self.data.data_specs = self.input_specs # we want these to be SmartArrays, so no `.get(WHERE)` weights_flat_hist = container["weights"] if self.scale_errors: vars_flat_hist = container["variances"] self.data.data_specs = self.output_specs if self.rs_mode == ResampleMode.UP: # The `unroll_binning` function returns the midpoints of the bins in the # dimension `name`. fine_gridpoints = [ SmartArray( container.unroll_binning(name, self.output_specs)) for name in self.output_specs.names ] # We look up at which bin index of the input binning the midpoints of # the output binning can be found, and assign to each the content of the # bin of that index. container["weights_resampled"] = translation.lookup( fine_gridpoints, weights_flat_hist, self.input_specs, ) if self.scale_errors: container["vars_resampled"] = translation.lookup( fine_gridpoints, vars_flat_hist, self.input_specs, ) # These are the volumes of the bins we sample *from* origin_binvols = translation.lookup( fine_gridpoints, input_binvols, self.input_specs, ) # Finally, we scale the weights and variances by the ratio of the # bin volumes in place: vectorizer.imul(output_binvols, container["weights_resampled"]) vectorizer.itruediv(origin_binvols, container["weights_resampled"]) if self.scale_errors: vectorizer.imul(output_binvols, container["vars_resampled"]) vectorizer.itruediv(origin_binvols, container["vars_resampled"]) elif self.rs_mode == ResampleMode.DOWN: pass # not yet implemented if self.scale_errors: vectorizer.sqrt(vals=container["vars_resampled"], out=container["errors_resampled"])
def apply_function(self): for container in self.data: vectorizer.sqrt(vals=container["manual_variance"], out=container["errors"])