def check_cfg(self): if not 'name' in self.cfg: pkey = self.cfg.parent_key() if not pkey: raise Exception( '"name" option is not provided for integral_1d_v01') self.cfg.name = pkey self.idx = self.cfg.indices from gna.expression import NIndex if not isinstance(self.idx, NIndex): self.idx = NIndex(fromlist=self.cfg.indices) try: self.edges = N.ascontiguousarray(self.cfg.edges, dtype='d') except: raise Exception('Invalid binning definition: {!r}'.format( self.cfg.edges)) try: self.xorders = N.ascontiguousarray(self.cfg.xorders, dtype='P') except: raise Exception('Invalid xorders definition: {!r}'.format( self.cfg.xorders)) if len(self.cfg.variables) != 2: raise Exception('Two vairables should be provided')
def __init__(self, *args, **kwargs): TransformationBundleLegacy.__init__(self, *args, **kwargs) self.idx = self.cfg.indices from gna.expression import NIndex if not isinstance(self.idx, NIndex): self.idx = NIndex(fromlist=self.cfg.indices)
def build(self): from gna.expression import NIndex idx = self.cfg.indices if not isinstance(idx, NIndex): idx = NIndex(fromlist=self.cfg.indices) for i, key in enumerate(idx.iterate()): self.make_trans( i, key )
def define_variables(self): idx = self.cfg.indices if not isinstance(idx, NIndex): idx = NIndex(fromlist=self.cfg.indices) for name, var in self.cfg.variables.items(): for i, nidx in enumerate(idx.iterate()): self.context.set_variable(name, nidx, var)
def init_indices(self, indices='indices'): if isinstance(indices, str): self.idx = self.cfg.get(indices, []) else: self.idx = indices from gna.expression import NIndex if isinstance(self.idx, NIndex): return self.idx = NIndex(fromlist=self.idx)
def __init__(self, cfg, *args, **kwargs): from gna.expression import NIndex preprocess_bundle_cfg(cfg) self.cfg = cfg # Read bundle configuration self.bundlecfg = cfg['bundle'] # Init multidimensional index self.nidx = self.bundlecfg.get('nidx', []) if isinstance(self.nidx, (tuple, list)): self.nidx = NIndex(fromlist=self.nidx) assert isinstance(self.nidx, NIndex) # If information about major indexes is provided, split nidx into major and minor parts major = self.bundlecfg.get('major', None) if major is not None: self.nidx_major, self.nidx_minor = self.nidx.split(major) else: self.nidx_major, self.nidx_minor = self.nidx, self.nidx.get_subset( ()) # Init namespace and context context = kwargs.pop('context', None) if context is None: inputs = kwargs.pop('inputs', {}) outputs = kwargs.pop('outputs', {}) self.namespace = kwargs.pop('namespace', env.globalns) else: inputs = context.inputs outputs = context.outputs self.namespace = context.namespace() self.context = NestedDict(inputs=inputs, outputs=outputs, objects={}) self._debug = self.bundlecfg.get('debug', self._debug) self._namefunction = self._get_namefunction(self.bundlecfg) assert not kwargs, 'Unparsed kwargs: ' + str(kwargs)
class oscprob_v01(TransformationBundleLegacy): def __init__(self, *args, **kwargs): TransformationBundleLegacy.__init__(self, *args, **kwargs) self.idx = self.cfg.indices from gna.expression import NIndex if not isinstance(self.idx, NIndex): self.idx = NIndex(fromlist=self.cfg.indices) def build(self): self.comp0 = R.FillLike(1.0) self.comp0.fill.setLabel('OP comp0') for i, it in enumerate(self.idx.iterate()): dist_it = it.get_subset(('d', 'r')) dist = dist_it.current_format(name='baseline') oscprobkey = dist_it.current_format('{autoindex}')[1:] oscprob = self.objects.get(oscprobkey, None) if not oscprob: with self.common_namespace: with self.common_namespace('pmns'): oscprob = self.objects[oscprobkey] = R.OscProbPMNS( R.Neutrino.ae(), R.Neutrino.ae(), dist) component = it.get_current('c') if component == 'comp0': output = self.comp0.fill.outputs['a'] input = self.comp0.fill.inputs['a'] else: if not component in oscprob.transformations: raise Exception( 'No component %s in oscprob transformation' % component) trans = oscprob.transformations[component] trans.setLabel( it.current_format( 'OP {component}:\n{reactor}->{detector}')) output = trans[component] input = trans['Enu'] if self.context: self.set_output(output, self.cfg.name, it) self.set_input(input, self.cfg.name, it, clone=0) def define_variables(self): from gna.parameters.oscillation import reqparameters ns_pmns = self.common_namespace('pmns') reqparameters(ns_pmns) names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23']) with ns_pmns: R.OscProbPMNSExpressions(R.Neutrino.ae(), R.Neutrino.ae(), names, ns=ns_pmns) ns_pmns.materializeexpressions() for i, vname in enumerate(names): ns_pmns[vname].setLabel('Psur(ee) weight %i: %s ' % (i, vname))
class TransformationBundle(object): """ cfg = { bundle = name or { name = string # Bundle name (may contain version) version = string (optional) # Bundle version (will be added to bundle name) names = { localname: globalname, localname1: globalname1 } # Map to change the predefined names nidx = NIndex or NIndex configuration list (optional) # Multiindex, if not passed, empty index is created major = [ 'short1', 'short2', ... ] # A subset of indices considered to be major } } """ _debug = False def __init__(self, cfg, *args, **kwargs): from gna.expression import NIndex preprocess_bundle_cfg(cfg) self.cfg = cfg # Read bundle configuration self.bundlecfg = cfg['bundle'] # Init multidimensional index self.nidx = self.bundlecfg.get('nidx', []) if isinstance(self.nidx, (tuple, list)): self.nidx = NIndex(fromlist=self.nidx) assert isinstance(self.nidx, NIndex) # If information about major indexes is provided, split nidx into major and minor parts major = self.bundlecfg.get('major', None) if major is not None: self.nidx_major, self.nidx_minor = self.nidx.split(major) else: self.nidx_major, self.nidx_minor = self.nidx, self.nidx.get_subset( ()) # Init namespace and context context = kwargs.pop('context', None) if context is None: inputs = kwargs.pop('inputs', {}) outputs = kwargs.pop('outputs', {}) self.namespace = kwargs.pop('namespace', env.globalns) else: inputs = context.inputs outputs = context.outputs self.namespace = context.namespace() self.context = NestedDict(inputs=inputs, outputs=outputs, objects={}) self._debug = self.bundlecfg.get('debug', self._debug) self._namefunction = self._get_namefunction(self.bundlecfg) assert not kwargs, 'Unparsed kwargs: ' + str(kwargs) @classmethod def _get_namefunction(cls, bundlecfg): names = bundlecfg.get('names') if not names: return lambda s: s elif isinstance(names, (dict, NestedDict)): return lambda s: names.get(s, s) elif callable(names): return names cls.exception( 'option "names" should be a dictionary or a function, not {}'. format(type(names).__name__)) def execute(self): """Calls sequentially the methods to define variables and build the computational chain.""" try: self.define_variables() except Exception as e: print('Failed to define variables for bundle %s' % (type(self).__name__)) import sys raise e.with_traceback(sys.exc_info()[2]) try: self.build() except Exception as e: print('Failed to build the bundle %s' % (type(self).__name__)) import sys raise e.with_traceback(sys.exc_info()[2]) @staticmethod def _provides(cfg): print( 'Warning! Calling default bundle.provides(cfg) static method. Should be overridden.' ) print('Bundle configuration:') print(str(cfg)) return (), () # variables, objects @classmethod def provides(cls, cfg): variables, objects = cls._provides(cfg) namefcn = cls._get_namefunction(cfg['bundle']) ret = tuple((namefcn(a) for a in variables)), tuple( (namefcn(a) for a in objects)) if cfg.bundle.get('debug', False): print('Bundle', cls.__name__, 'provides') print(' variables', ret[0]) print(' objects', ret[1]) return ret def build(self): """Builds the computational chain. Should handle each namespace in namespaces.""" pass def define_variables(self): """Defines the variables necessary for the computational chain. Should handle each namespace.""" pass @classmethod def exception(cls, message): return Exception("{bundle}: {message}".format(bundle=cls.__name__, message=message)) def get_globalname(self, localname): return self._namefunction(localname) def get_path(self, localname, nidx=None, argument_number=None, join=False, extra=None): name = self.get_globalname(localname) if nidx is None: path = name, else: path = nidx.current_values(name=name) if extra: if isinstance(extra, str): path += extra, elif isinstance(extra, (list, tuple)): path += tuple(extra) else: raise Exception('Unsupported extra field: ' + str(extra)) if argument_number is not None: path += ('{:02d}'.format(int(argument_number)), ) if join: path = '.'.join(path) return path def reqparameter(self, name, nidx, *args, **kwargs): label = kwargs.get('label', '') if nidx is not None and '{' in label: kwargs['label'] = nidx.current_format(label) path = self.get_path(name, nidx, extra=kwargs.pop('extra', None)) if self._debug: print('{name} requires parameter {par}'.format( name=type(self).__name__, par=path)) return self.namespace.reqparameter(path, *args, **kwargs) def set_output(self, name, nidx, output, extra=None): path = self.get_path(name, nidx, extra=extra) if path in self.context.outputs: raise Exception('Outputs dictionary already contains ' + str(path)) if self._debug: print('{name} sets output {output}'.format( name=type(self).__name__, output=path)) self.context.outputs[path] = output def set_input(self, name, nidx, input, argument_number=None, extra=None): path = self.get_path(name, nidx, argument_number, extra=extra) if path in self.context.inputs: raise Exception('Inputs dictionary already contains ' + str(path)) if self._debug: print('{name} sets input {input}'.format(name=type(self).__name__, input=path)) self.context.inputs[path] = input def check_nidx_dim(self, dmin, dmax=float('inf'), nidx='both'): if nidx == 'both': nidx = self.nidx elif nidx == 'major': nidx = self.nidx_major elif nidx == 'minor': nidx = self.nidx_minor else: raise self.exception('Unknown nidx type ' + nidx) ndim = nidx.ndim() if not dmin <= ndim <= dmax: raise self.exception( 'Ndim {} does not satisfy requirement: {}<=ndim<={}'.format( ndim, dmin, dmax)) def _exception(self, msg): return BundleException('{}: {}'.format(type(self).__name__, msg))
class integral_2d1d_v01(TransformationBundleLegacy): def __init__(self, *args, **kwargs): TransformationBundleLegacy.__init__(self, *args, **kwargs) self.check_cfg() def check_cfg(self): if not 'name' in self.cfg: pkey = self.cfg.parent_key() if not pkey: raise Exception( '"name" option is not provided for integral_1d_v01') self.cfg.name = pkey self.idx = self.cfg.indices from gna.expression import NIndex if not isinstance(self.idx, NIndex): self.idx = NIndex(fromlist=self.cfg.indices) try: self.edges = N.ascontiguousarray(self.cfg.edges, dtype='d') except: raise Exception('Invalid binning definition: {!r}'.format( self.cfg.edges)) try: self.xorders = N.ascontiguousarray(self.cfg.xorders, dtype='P') except: raise Exception('Invalid xorders definition: {!r}'.format( self.cfg.xorders)) if len(self.cfg.variables) != 2: raise Exception('Two vairables should be provided') def build(self): if self.xorders.size > 1: if self.xorders.size + 1 != self.edges.size: raise Exception( 'Incompartible edges and xorders definition:\n {!r}\n {!r}' .format(self.edges, self.xorders)) self.integrator = R.GaussLegendre2d(self.edges, self.xorders, self.edges.size - 1, -1.0, 1.0, self.cfg.yorder) else: self.integrator = R.GaussLegendre2d(self.edges, int(self.xorders[0]), self.edges.size - 1, -1.0, 1.0, self.cfg.yorder) self.integrator.points.setLabel('Gauss-Legendre 2d') self.integrator.points.x.setLabel(self.cfg.variables[0]) self.integrator.points.xedges.setLabel('%s edges' % self.cfg.variables[0]) self.integrator.points.y.setLabel(self.cfg.variables[1]) self.set_output(self.integrator.points.x, self.cfg.variables[0]) self.set_output(self.integrator.points.xedges, '%s_edges' % self.cfg.variables[0]) self.set_output(self.integrator.points.xhist, '%s_hist' % self.cfg.variables[0]) self.set_output(self.integrator.points.y, self.cfg.variables[1]) for i, it in enumerate(self.idx.iterate()): hist = R.GaussLegendre2dHist(self.integrator) hist.hist.setLabel(it.current_format(name='hist')) self.set_input(hist.hist.f, self.cfg.name, it, clone=0) self.set_output(hist.hist.hist, self.cfg.name, it) def define_variables(self): pass