Beispiel #1
0
    def build(self):
        self.inputs = {}
        self.outputs = {}
        self.points = {}
        self.interp = {}
        for k, v in self.data.items():
            x = C.Points(v[0], labels='{} geo-nu X0'.format(k))
            y = C.Points(v[1], labels='{} geo-nu Y0'.format(k))

            interp = C.InterpLinear(
                labels=('{} X insegment'.format(k),
                        '{} geo-neutrino spectra'.format(k)))
            interp.set_underflow_strategy(
                R.GNA.Interpolation.Strategy.Constant)
            interp.set_overflow_strategy(R.GNA.Interpolation.Strategy.Constant)
            interp.set_fill_value(0.0)
            interp.setXY(x, y)

            self.points[k] = (x, y)
            self.interp[k] = interp

        for idx in self.nidx.iterate():
            for k in self.data.keys():
                interp = self.interp[k]
                self.set_input('geonu_spectrum_{}'.format(k),
                               idx,
                               (interp.insegment.points, interp.interp.newx),
                               argument_number=0)
                self.set_output('geonu_spectrum_{}'.format(k), idx,
                                interp.interp.interp)
Beispiel #2
0
    def build(self):
        for idx in self.nidx:
            reac, = idx.current_values()
            name = "snf_correction" + idx.current_format()
            try:
                _snf_energy, _snf_spectra = list(
                    map(C.Points, self.snf_raw_data[reac]))
            except KeyError:
                # U238 doesn't have offequilibrium correction so just pass 1.
                _snf_energy, _snf_spectra = list(
                    map(C.Points, self.snf_raw_data['average']))

            _snf_energy.points.setLabel(
                "Original energies for SNF spectrum of {}".format(reac))

            snf_spectra = C.InterpLinear(
                labels='Correction for spectra in {}'.format(reac))
            snf_spectra.set_overflow_strategy(
                R.GNA.Interpolation.Strategy.Constant)
            snf_spectra.set_underflow_strategy(
                R.GNA.Interpolation.Strategy.Constant)

            insegment = snf_spectra.transformations.front()
            insegment.setLabel("Segments")

            interpolator_trans = snf_spectra.transformations.back()
            interpolator_trans.setLabel(
                "Interpolated SNF correction for {}".format(reac))

            passthrough = C.Identity(
                labels="Nominal spectra for {}".format(reac))
            _snf_energy >> (insegment.edges, interpolator_trans.x)
            _snf_spectra >> interpolator_trans.y

            self.set_input('snf_correction',
                           idx, (insegment.points, interpolator_trans.newx),
                           argument_number=0)
            self.set_input('snf_correction',
                           idx, (passthrough.single_input()),
                           argument_number=1)

            snap = C.Snapshot(
                passthrough.single(),
                labels='Snapshot of nominal spectra for SNF in {}'.format(
                    reac))
            product = C.Product(
                outputs=[snap.single(),
                         interpolator_trans.single()],
                labels='Product of nominal spectrum to SNF correction in {}'.
                format(reac))

            par_name = "snf_scale"
            self.reqparameter(par_name,
                              idx,
                              central=1.,
                              relsigma=1,
                              labels="SNF norm for reactor {0}".format(reac))

            outputs = [product.single()]
            weights = ['.'.join((par_name, idx.current_format()))]

            with self.namespace:
                final_sum = C.WeightedSum(
                    weights,
                    outputs,
                    labels='SNF spectrum from {0} reactor'.format(reac))

            self.context.objects[name] = final_sum
            self.set_output("snf_correction", idx, final_sum.single())
    def build(self):
        self.objects = NestedDict()
        data = self.load_data()

        # Correlated part of the energy nonlinearity factor
        # a weighted sum of input curves
        for i, itl in enumerate(self.component_idx.iterate()):
            name, = itl.current_values()
            if not name in data:
                raise self._exception(
                    'The nonlinearity curve {} is not provided'.format(name))

            try:
                x, y = data[name]
            except:
                raise Exception(
                    'Unable to get x,y for nonlinearity {}'.format(name))

            Y = C.Points(y * x)

            if i:
                label = itl.current_format('NL correction {autoindex}')
            else:
                label = itl.current_format('NL nominal ({autoindex})')

                X = C.Points(x)
                X.points.setLabel(label + ' X')
                self.set_output('lsnl_x', None, X.single())
                self.objects[('curves', name, 'X')] = X

            Y.points.setLabel(label + ' Y')
            self.set_output('lsnl_component_y', itl, Y.single())
            self.objects[('curves', name, 'Y')] = Y

        #
        # Create direct and inverse interpolators
        #
        interp_direct = C.InterpLinear(labels=('NL InSeg direct',
                                               'NL interp direct'))
        interp_inverse = C.InterpLinear(labels=('NL InSeg inverse',
                                                'NL interp inverse'))
        self.objects['interp_direct'] = interp_direct
        self.objects['interp_inverse'] = interp_inverse

        #
        # Interp_interpolator(xcoarse, ycoarse, newx)
        # x, y -> interp_direct  -> interp_direct(bin edges)
        # y, x -> interp_inverse -> interp_direct(bin edges)
        self.set_input('lsnl_interpolator',
                       None, (interp_direct.insegment.edges,
                              interp_direct.interp.x, interp_inverse.interp.y),
                       argument_number=0)
        self.set_input('lsnl_interpolator',
                       None,
                       (interp_direct.interp.y, interp_inverse.insegment.edges,
                        interp_inverse.interp.x),
                       argument_number=1)
        self.set_input(
            'lsnl_interpolator',
            None,
            (interp_direct.insegment.points, interp_direct.interp.newx,
             interp_inverse.insegment.points, interp_inverse.interp.newx),
            argument_number=2)

        self.set_output('lsnl_direct', None, interp_direct.interp.interp)
        self.set_output('lsnl_inverse', None, interp_inverse.interp.interp)

        expose_matrix = self.cfg.get('expose_matrix', False)
        with self.namespace:
            for i, itd in enumerate(self.detector_idx.iterate()):
                """Finally, original bin edges multiplied by the correction factor"""
                """Construct the nonlinearity calss"""
                nonlin = R.HistNonlinearityB(
                    expose_matrix,
                    labels=itd.current_format('NL matrix {autoindex}'))
                try:
                    nonlin.set_range(*self.cfg.nonlin_range)
                except KeyError:
                    pass

                self.objects[('nonlinearity', ) +
                             itd.current_values()] = nonlin

                self.set_input('lsnl_edges',
                               itd,
                               nonlin.matrix.Edges,
                               argument_number=0)
                interp_direct.interp.interp >> nonlin.matrix.EdgesModified
                interp_inverse.interp.interp >> nonlin.matrix.BackwardProjection
                self.set_output('lsnl_matrix', itd, nonlin.matrix.FakeMatrix)

                trans = nonlin.smear
                for j, itother in enumerate(self.nidx_minor.iterate()):
                    it = itd + itother
                    if j:
                        trans = nonlin.add_transformation()
                        nonlin.add_input()
                    trans.setLabel(it.current_format('NL {autoindex}'))

                    self.set_input('lsnl', it, trans.Ntrue, argument_number=0)
                    self.set_output('lsnl', it, trans.Nrec)
    def build(self):
        for idx in self.nidx.iterate():
            if 'isotope' in idx.names()[0]:
                iso, reac = idx.current_values()
            else:
                reac, iso = idx.current_values()
            name = "offeq_correction." + idx.current_format()
            try:
                _offeq_energy, _offeq_spectra = list(
                    map(C.Points, self.offeq_raw_spectra[iso]))
                _offeq_energy.points.setLabel(
                    "Original energies for offeq spectrum of {}".format(iso))
            except KeyError:
                # U238 doesn't have offequilibrium correction so just pass 1.
                if iso != 'U238':
                    raise
                ones = C.FillLike(
                    1.,
                    labels='Offeq correction to {0} spectrum in {1} reactor'.
                    format(iso, reac))
                self.context.objects[name] = ones
                self.set_input('offeq_correction',
                               idx,
                               ones.single_input(),
                               argument_number=0)
                self.set_output("offeq_correction", idx, ones.single())
                continue

            offeq_spectra = C.InterpLinear(
                labels='Correction for {} spectra'.format(iso))
            offeq_spectra.set_overflow_strategy(
                R.GNA.Interpolation.Strategy.Constant)
            offeq_spectra.set_underflow_strategy(
                R.GNA.Interpolation.Strategy.Constant)

            insegment = offeq_spectra.transformations.front()
            insegment.setLabel("Segments")

            interpolator_trans = offeq_spectra.transformations.back()
            interpolator_trans.setLabel(
                "Interpolated spectral correction for {}".format(iso))

            ones = C.FillLike(1., labels="Nominal spectra for {}".format(iso))
            _offeq_energy >> (insegment.edges, interpolator_trans.x)
            _offeq_spectra >> interpolator_trans.y

            self.set_input('offeq_correction',
                           idx, (insegment.points, interpolator_trans.newx,
                                 ones.single_input()),
                           argument_number=0)

            par_name = "offeq_scale"
            self.reqparameter(
                par_name,
                idx,
                central=1.,
                relsigma=0.3,
                labels="Offequilibrium norm for reactor {1} and iso "
                "{0}".format(iso, reac))
            self.reqparameter("dummy_scale",
                              idx,
                              central=1,
                              fixed=True,
                              labels="Dummy weight for reactor {1} and iso "
                              "{0} for offeq correction".format(iso, reac))

            outputs = [ones.single(), interpolator_trans.single()]
            weights = [
                '.'.join(("dummy_scale", idx.current_format())), '.'.join(
                    (par_name, idx.current_format()))
            ]

            with self.namespace:
                final_sum = C.WeightedSum(weights,
                                          outputs,
                                          labels='Offeq correction to '
                                          '{0} spectrum in {1} reactor'.format(
                                              iso, reac))

            self.context.objects[name] = final_sum
            self.set_output("offeq_correction", idx, final_sum.single())
    def build(self):
        self.objects = NestedDict()
        data, gradients = self.load_data()

        # Correlated part of the energy nonlinearity factor
        # a weighted sum of input curves
        for i, itl in enumerate(self.component_idx.iterate()):
            name, = itl.current_values()
            if not name in data:
                raise self._exception(
                    'The nonlinearity curve {} is not provided'.format(name))

            try:
                x, y = data[name]
            except:
                raise Exception(
                    'Unable to get x,y for nonlinearity {}'.format(name))

            Y = C.Points(y)
            Grad = C.Points(gradients[name])

            if i:
                label = itl.current_format('NL correction {autoindex}')
            else:
                label = itl.current_format('NL nominal ({autoindex})')

                X = C.Points(x)
                X.points.setLabel(label + ' X')
                self.set_output('lsnl_x', None, X.single())
                self.objects[('curves', name, 'X')] = X

            Y.points.setLabel(label + ' Y')
            Grad.points.setLabel(label + ' gradient')
            self.set_output('lsnl_component_y', itl, Y.single())
            self.set_output('lsnl_component_grad', itl, Grad.single())
            self.objects[('curves', name, 'Y')] = Y
            self.objects[('curves', name, 'Grad')] = Grad

        #
        # Create direct and inverse interpolators
        #
        interp_direct = C.InterpLinear(labels=('NL InSeg direct',
                                               'NL interp direct'))
        interp_inverse = C.InterpLinear(labels=('NL InSeg inverse',
                                                'NL interp inverse'))
        self.objects['interp_direct'] = interp_direct
        self.objects['interp_inverse'] = interp_inverse

        interp_evis = C.InterpLinear(labels=('NL InSeg Evis(Eq)', 'Evis(Eq)'))
        self.objects['interp_evis'] = interp_evis

        interp_deq_devis = C.InterpLinear(labels=('NL InSeg dEq/dEvis)',
                                                  'dEq/dEvis'))
        self.objects['interp_deq_devis'] = interp_deq_devis

        # Interp_interpolators
        # interp_evis acts similarly to interp_invers, but expects different interpolation points
        #
        # x, y     -> interp_direct  : interp_direct(bin edges)
        # y, x     -> interp_inverse : interp_direct(bin edges)
        # y, x     -> interp_evis    : interp_evis(integration points of Eq)
        # x, dy/dx -> interp_grad    : interp_grad(Evis(integration points of Eq))
        #
        # Arguments: Evis, Eq, E edges, E integration points
        # Distribution:
        #   Interpolator     Xorig   Yorig      Xnew
        #   interp_direct    Evis    Eq         E edges
        #   interp_inverse   Eq      Evis       E edges
        #   interp_evis      Eq      Evis       E integration points
        #   interp_grad      Evis    dEq/dEvis  interp_evis: Evis(Eq=E integration points)
        #
        arg0 = (interp_direct.insegment.edges, interp_direct.interp.x)
        arg0 = arg0 + (interp_inverse.interp.y, )
        arg0 = arg0 + (interp_evis.interp.y, )
        arg0 = arg0 + (interp_deq_devis.insegment.edges,
                       interp_deq_devis.interp.x)
        arg1 = (interp_direct.interp.y, )
        arg1 = arg1 + (interp_inverse.insegment.edges, interp_inverse.interp.x)
        arg1 = arg1 + (interp_evis.insegment.edges, interp_evis.interp.x)
        arg2 = (interp_direct.insegment.points, interp_direct.interp.newx)
        arg2 = arg2 + (interp_inverse.insegment.points,
                       interp_inverse.interp.newx)
        arg3 = (interp_evis.insegment.points, interp_evis.interp.newx)
        self.set_input('lsnl_interpolator', None, arg0, argument_number=0)
        self.set_input('lsnl_interpolator', None, arg1, argument_number=1)
        self.set_input('lsnl_interpolator', None, arg2, argument_number=2)
        self.set_input('lsnl_interpolator', None, arg3, argument_number=3)

        arg0 = interp_deq_devis.interp.y
        self.set_input('lsnl_interpolator_grad', None, arg0, argument_number=0)

        self.set_output('lsnl_direct', None, interp_direct.interp.interp)
        self.set_output('lsnl_inverse', None, interp_inverse.interp.interp)
        self.set_output('lsnl_evis', None, interp_evis.interp.interp)
        self.set_output('lsnl_interpolator_grad', None,
                        interp_deq_devis.interp.interp)

        interp_evis.interp.interp >> (interp_deq_devis.insegment.points,
                                      interp_deq_devis.interp.newx)

        expose_matrix = self.cfg.get('expose_matrix', False)
        for i, itd in enumerate(self.detector_idx.iterate()):
            """Finally, original bin edges multiplied by the correction factor"""
            """Construct the nonlinearity calss"""
            with self.namespace:
                nonlin = R.HistNonlinearityB(
                    expose_matrix,
                    labels=itd.current_format('NL matrix {autoindex}'))
            try:
                nonlin.set_range(*self.cfg.nonlin_range)
            except KeyError:
                pass

            self.objects[('nonlinearity', ) + itd.current_values()] = nonlin

            self.set_input('lsnl_edges',
                           itd,
                           nonlin.matrix.Edges,
                           argument_number=0)
            interp_direct.interp.interp >> nonlin.matrix.EdgesModified
            interp_inverse.interp.interp >> nonlin.matrix.BackwardProjection
            self.set_output('lsnl_matrix', itd, nonlin.matrix.FakeMatrix)

            trans = nonlin.smear
            for j, itother in enumerate(self.nidx_minor.iterate()):
                it = itd + itother
                if j:
                    trans = nonlin.add_transformation()
                    nonlin.add_input()
                trans.setLabel(it.current_format('NL {autoindex}'))

                self.set_input('lsnl', it, trans.Ntrue, argument_number=0)
                self.set_output('lsnl', it, trans.Nrec)
    def build(self):
        for idx in self.nidx.iterate():
            if 'isotope' in idx.names()[0]:
                iso, reac = idx.current_values()
            else:
                reac, iso = idx.current_values()
            name = "offeq_correction." + idx.current_format()
            try:
                _offeq_energy, _offeq_spectra = list(map(C.Points, self.offeq_raw_spectra[iso]))
                _offeq_energy.points.setLabel("Original energies for offeq spectrum of {}".format(iso))
            except KeyError:
            # U238 doesn't have offequilibrium correction so just pass 1.
                if iso != 'U238':
                    raise
                passthrough = C.Identity(labels='Nominal {0} spectrum in {1} reactor'.format(iso, reac))
                self.context.objects[name] = passthrough
                dummy = C.Identity() #just to serve 1 input
                self.set_input('offeq_correction', idx, dummy.single_input(), argument_number=0)
                self.set_input('offeq_correction', idx, passthrough.single_input(), argument_number=1)
                self.set_output("offeq_correction", idx, passthrough.single())
                continue

            offeq_spectra = C.InterpLinear(labels='Correction for {} spectra'.format(iso))
            offeq_spectra.set_overflow_strategy(R.GNA.Interpolation.Strategy.Constant)
            offeq_spectra.set_underflow_strategy(R.GNA.Interpolation.Strategy.Constant)

            insegment = offeq_spectra.transformations.front()
            insegment.setLabel("Offequilibrium segments")

            interpolator_trans = offeq_spectra.transformations.back()
            interpolator_trans.setLabel("Interpolated spectral correction for {}".format(iso))

            passthrough = C.Identity(labels="Nominal {0} spectrum in {1} reactor".format(iso, reac))
            _offeq_energy >> (insegment.edges, interpolator_trans.x)
            _offeq_spectra >> interpolator_trans.y

            # Enu
            self.set_input('offeq_correction', idx, (insegment.points, interpolator_trans.newx),
                            argument_number=0)
            # Anue spectra
            self.set_input('offeq_correction', idx, ( passthrough.single_input()), argument_number=1)

            par_name = "offeq_scale"
            self.reqparameter(par_name, idx, central=1., relsigma=0.3,
                    labels="Offequilibrium norm for reactor {1} and iso "
                    "{0}".format(iso, reac))
            self.reqparameter("dummy_scale", idx, central=1,
                    fixed=True, labels="Dummy weight for reactor {1} and iso "
                    "{0} for offeq correction".format(iso, reac))

            snap = C.Snapshot(passthrough.single(), labels='Snapshot of {} spectra in reac {}'.format(iso, reac))

            prod = C.Product(labels='Product of initial {} spectra and '
                             'offequilibrium corr in {} reactor'.format(iso, reac))
            prod.multiply(interpolator_trans.single())
            prod.multiply(snap.single())


            outputs = [passthrough.single(), prod.single()]
            weights = ['.'.join(("dummy_scale", idx.current_format())),
                       '.'.join((par_name, idx.current_format()))]

            with self.namespace:
                final_sum = C.WeightedSum(weights, outputs, labels='Corrected to offequilibrium '
                            '{0} spectrum in {1} reactor'.format(iso, reac))


            self.context.objects[name] = final_sum
            self.set_output("offeq_correction", idx, final_sum.single())
Beispiel #7
0
    def build(self):
        with entryContext(subgraph='LSNL'):
            self.init_data()

            #
            # Initialize bin edges
            #
            self.histoffset = C.HistEdgesOffset(
                self.doubleme, labels='Offset/threshold bin edges (Evis, Te+)')
            histedges = self.histoffset.histedges

            # Declare open input
            self.set_input('evis_edges_hist',
                           None,
                           histedges.hist_in,
                           argument_number=0)

            histedges.points.setLabel('Evis (full range)')
            histedges.points_truncated.setLabel('Evis (truncated)')
            histedges.points_threshold.setLabel('Evis (threshold)')
            histedges.points_offset.setLabel('Te+')
            histedges.hist_truncated.setLabel('Hist Evis (truncated)')
            histedges.hist_threshold.setLabel('Hist Evis (threshold)')
            histedges.hist_offset.setLabel('Hist Te+')

            #
            # Birk's model integration
            #
            birks_e_input, birks_quenching_input = self.stopping_power[
                'e'], self.stopping_power['dedx']
            self.birks_e_p, self.birks_quenching_p = C.Points(
                birks_e_input,
                labels='Te (input)'), C.Points(birks_quenching_input,
                                               labels='Stopping power (dE/dx)')

            birksns = self.namespace('birks')
            with birksns:
                self.birks_integrand_raw = C.PolyRatio(
                    [],
                    list(sorted(birksns.storage.keys())),
                    labels="Birk's integrand")
            self.birks_quenching_p >> self.birks_integrand_raw.polyratio.points

            self.doubleemass_point = C.Points([-self.doubleme],
                                              labels='2me offset')

            self.integrator_ekin = C.IntegratorGL(
                self.histoffset.histedges.hist_offset,
                self.cfg.integration_order,
                labels=('Te sampler (GL)', "Birk's integrator (GL)"))

            self.birks_integrand_interpolator = C.InterpLogx(
                self.birks_e_p,
                self.integrator_ekin.points.x,
                labels=("Birk's InSegment", "Birk's interpolator"))
            self.birks_integrand_interpolated = self.birks_integrand_interpolator.add_input(
                self.birks_integrand_raw.polyratio.ratio)
            self.birks_integral = self.integrator_ekin.add_input(
                self.birks_integrand_interpolated)

            self.birks_accumulator = C.PartialSum(0.,
                                                  labels="Birk's Evis|[MeV]")
            self.birks_integral >> self.birks_accumulator.reduction

            #
            # Cherenkov model
            #
            with self.namespace('cherenkov'):
                self.cherenkov = C.Cherenkov_Borexino(labels='Npe Cherenkov')
            self.histoffset.histedges.points_offset >> self.cherenkov.cherenkov

            #
            # Electron energy model
            #
            with self.namespace:
                self.electron_model = C.WeightedSum(
                    ['kC', 'Npescint'], [
                        self.cherenkov.cherenkov.ch_npe,
                        self.birks_accumulator.reduction.out
                    ],
                    labels='Npe: electron responce')

            #
            # 2 511 keV gamma model
            #
            self.annihilation_electrons_centers = C.Points(
                self.annihilation_electrons_centers_input,
                labels='Annihilation gamma E centers')
            self.annihilation_electrons_p = C.Points(
                self.annihilation_electrons_p_input,
                labels='Annihilation gamma weights')

            self.view_lowe = C.ViewHistBased(
                self.histoffset.histedges.hist_offset,
                0.0,
                self.annihilation_electrons_edges_input[-1],
                labels=('Low E indices', 'Low E view'))
            self.ekin_edges_lowe = self.view_lowe.add_input(
                self.histoffset.histedges.points_offset)
            self.electron_model_lowe = self.view_lowe.add_input(
                self.electron_model.single())

            self.ekin_edges_lowe.setLabel('Te+ edges (low Te view)')
            self.electron_model_lowe.setLabel(
                'Npe: electron responce (low Te view)')

            self.electron_model_lowe_interpolator = C.InterpLinear(
                self.ekin_edges_lowe,
                self.annihilation_electrons_centers,
                labels=('Annihilation E InSegment',
                        'Annihilation gamma interpolator'))
            self.electron_model_lowe_interpolated = self.electron_model_lowe_interpolator.add_input(
                self.electron_model_lowe)

            with self.namespace:
                self.npe_positron_offset = C.Convolution(
                    'ngamma', labels='e+e- annihilation Evis [MeV]')
                self.electron_model_lowe_interpolated >> self.npe_positron_offset.normconvolution.fcn
                self.annihilation_electrons_p >> self.npe_positron_offset.normconvolution.weights

            #
            # Total positron model
            #
            self.positron_model = C.SumBroadcast(
                outputs=[
                    self.electron_model.sum.sum,
                    self.npe_positron_offset.normconvolution.result
                ],
                labels='Npe: positron responce')

            self.positron_model_scaled = C.FixedPointScale(
                self.histoffset.histedges.points_truncated,
                self.namespace['normalizationEnergy'],
                labels=('Fixed point index',
                        'Positron energy model|Evis, MeV'))
            self.positron_model_scaled = self.positron_model_scaled.add_input(
                self.positron_model.sum.outputs[0])
            self.positron_model_scaled_full_view = C.ViewRear(
                -1.0, labels='Positron Energy nonlinearity|full range')
            self.positron_model_scaled_full_view.determineOffset(
                self.histoffset.histedges.hist,
                self.histoffset.histedges.hist_truncated, True)
            self.histoffset.histedges.points >> self.positron_model_scaled_full_view.view.original
            self.positron_model_scaled >> self.positron_model_scaled_full_view.view.rear
            self.positron_model_scaled_full = self.positron_model_scaled_full_view.view.result

            #
            # Relative positron model
            #
            self.positron_model_relative = C.Ratio(
                self.positron_model_scaled,
                self.histoffset.histedges.points_truncated,
                labels='Positron energy nonlinearity')
            self.positron_model_relative_full_view = C.ViewRear(
                0.0, labels='Positron Energy nonlinearity|full range')
            self.positron_model_relative_full_view.determineOffset(
                self.histoffset.histedges.hist,
                self.histoffset.histedges.hist_truncated, True)
            self.histoffset.histedges.points >> self.positron_model_relative_full_view.view.original
            self.positron_model_relative >> self.positron_model_relative_full_view.view.rear
            self.positron_model_relative_full = self.positron_model_relative_full_view.view.result

        #
        # Hist Smear
        #
        self.pm_histsmear = C.HistNonlinearity(
            self.cfg.get('fill_matrix', False),
            labels=('Nonlinearity matrix', 'Nonlinearity smearing'))
        self.pm_histsmear.set_range(-0.5, 20.0)
        self.positron_model_scaled_full >> self.pm_histsmear.matrix.EdgesModified

        self.histoffset.histedges.hist >> self.pm_histsmear.matrix.Edges

        trans = self.pm_histsmear.transformations.back()
        for i, it in enumerate(self.nidx.iterate()):
            # if i:
            # trans = self.pm_histsmear.add_transformation()
            inp = self.pm_histsmear.add_input()

            trans.setLabel(
                it.current_format('Nonlinearity smearing {autoindex}'))

            self.set_input('lsnl', it, inp, argument_number=0)
            self.set_output('lsnl', it, trans.outputs.back())