示例#1
0
    def define_variables(self):
        from gna.parameters.oscillation import reqparameters_reactor as reqparameters
        pmnspars_kwargs = dict()
        pdgyear = self.cfg.get('pdg_year', None)
        if pdgyear:
            pmnspars_kwargs['pdg_year'] = pdgyear

        pmns_name = self.get_globalname('pmns')
        ns_pmns = self.namespace(pmns_name)
        reqparameters(ns_pmns, self.cfg.dm, **pmnspars_kwargs)

        names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23'])
        with ns_pmns:
            R.OscProbPMNSExpressions(R.Neutrino.ae(),
                                     R.Neutrino.ae(),
                                     names,
                                     ns=ns_pmns)
            ns_pmns['Delta'].setFixed()
            ns_pmns['SigmaDecohRel'].setFixed()
            ns_pmns['SinSq23'].setFixed()
            ns_pmns.materializeexpressions()

        ns_pmns.reqparameter('rho',
                             central=self.cfg.density,
                             fixed=True,
                             label='Matter density g/cm3')

        for i, vname in enumerate(names):
            ns_pmns[vname].setLabel('Psur(ee) weight %i: %s ' % (i, vname))
示例#2
0
    def define_variables(self):
        names_all = set(self.cfg.names)
        names_unc = self.cfg.fractions.keys()
        names_eval = names_all - set(names_unc)
        if len(names_eval) != 1:
            raise self.exception(
                'User should provide N-1 fractions, the last one is not independent\n'
                'all: {!s}\nfractions: {!s}'.format(self.cfg.names, names_unc))
        name_eval = names_eval.pop()

        subst = []
        names = ()
        for name, val in self.cfg.fractions.items():
            cname = self.cfg.format.format(component=name)
            names += cname,
            par = self.common_namespace.reqparameter(cname, cfg=val)
            par.setLabel('{} fraction'.format(name))
            subst.append(self.common_namespace.pathto(cname))

        label = '{} fraction: '.format(name_eval)
        label += '-'.join(('1', ) + names)

        name_eval = self.cfg.format.format(component=name_eval)
        with self.common_namespace:
            self.vd = R.VarDiff(stdvector(subst),
                                name_eval,
                                1.0,
                                ns=self.common_namespace)
            par = self.common_namespace[name_eval].get()

        par.setLabel(label)
示例#3
0
def test_tree_manager(function_name):
    from gna.env import env
    gns = env.globalns(function_name)
    ndata = 200

    with context.manager(ndata) as manager:
        ns = gns('namespace1')
        ns.defparameter('float1',   central=1, fixed=True, label='Float variable 1')
        ns.defparameter('float2',   central=2, fixed=True, label='Float variable 2')

        ns = gns('namespace2')
        ns.defparameter('angle',    central=3, label='Angle parameter', type='uniformangle')
        ns.defparameter('discrete', default='a', label='Discrete parameter', type='discrete', variants=OrderedDict([('a', 10.0), ('b', 20.0), ('c', 30.0)]))

        ns = gns('namespace3')
        from gna.parameters.oscillation import reqparameters
        reqparameters(ns)
        with ns:
            ns.materializeexpressions()
        ns['Delta'].set(N.pi*0.25)

        pars = tuple(par.getVariable() for (name,par) in ns.walknames())
        manager.setVariables(C.stdvector(pars))

    gns.printparameters(labels=True)

    allocator = manager.getAllocator()
    varray = manager.getVarArray()
    data_v = varray.vararray.points.data()
    data_a = allocator.view()
    print('Data (filled):', data_a.size, data_a.dtype, data_a)
    print('Data (vararray):', data_v.size, data_v.dtype, data_v)
    mask = data_v==data_a
    assert mask is not False and mask.all()
示例#4
0
    def define_variables(self):
        from gna.parameters.oscillation import reqparameters
        pmnspars_kwargs = dict()
        pdgyear = self.cfg.get('pdg_year', None)
        if pdgyear:
            pmnspars_kwargs['pdg_year'] = pdgyear

        for it in self.nidx_minor:
            name = it.current_values(name='pmns')
            ns_pmns = self.namespace(name)
            reqparameters(ns_pmns, **pmnspars_kwargs)

            names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23'])
            with ns_pmns:
                R.OscProbPMNSExpressions(R.Neutrino.ae(),
                                         R.Neutrino.ae(),
                                         names,
                                         ns=ns_pmns)
                ns_pmns['Delta'].setFixed()
                ns_pmns['SigmaDecohRel'].setFixed()
                ns_pmns['SinSq23'].setFixed()
                ns_pmns.materializeexpressions()

            for i, vname in enumerate(names):
                ns_pmns[vname].setLabel('Psur(ee) weight %i: %s ' % (i, vname))
示例#5
0
def test_shifting_edges_2():
    param = env.defparameter("param", central=0.1, fixed=True)
    placeholder = env.defparameter("placeholder", central=1, fixed=True)
    
    initial_binning = np.arange(1, 10, 0.5)

    initial_integrator = C.IntegratorGL(initial_binning, 4, labels = (('First Sampler', 'First Integrator')))
    print("Integration edges from first integral")
    print(initial_integrator.points.xedges.data())

    from gna.constructors import stdvector
    shifted = R.WeightedSum(-2*param.value(), stdvector(['placeholder']), stdvector(['inp']))
    shifted.sum.inp(initial_integrator.points.xedges)
    print("After shift by -2*{}".format(param.value()))
    print(shifted.sum.sum.data())
    expected = initial_binning - 2*param.value()
    assert np.allclose(expected, shifted.sum.sum.data())
示例#6
0
def test_par_06(floatprecision='double'):
    """Test nested vector"""
    assert floatprecision in ['double', 'float']
    const = N.array([1.5, 2.6, 3.7], dtype=floatprecision[0])
    var = R.parameter('vector<%s>' % floatprecision)('testpar', 2)
    var.value(0).resize(3)
    var.value(1).resize(3)
    taintflag = R.taintflag('tflag')
    var.subscribe(taintflag)
    taintflag.set(False)

    vec = C.stdvector(const)
    var.set(0, vec)
    vec = C.stdvector(const + 1.0)
    var.set(1, vec)

    check('vec 0', None, list(var.value(0)), const, taintflag)
    check('vec 1', None, list(var.value(1)), const + 1.0, taintflag, False)
示例#7
0
def test_arrayview_vector():
    size = 5
    from gna.constructors import stdvector
    a1 = N.arange(size, dtype=context.current_precision_short())
    v1 = stdvector(a1)
    view1 = R.arrayview(context.current_precision())(a1, size)

    assert view1 == v1
    assert not view1 != v1
示例#8
0
    def build(self):
        corrpars = OrderedDict()
        for name, vars in self.corr_vars.items():
            with self.common_namespace:
                corr_sigma_t = C.VarArray(vars, ns=self.common_namespace)
                corrpar_t = R.WeightedSum(1.0, C.stdvector([self.cfg.uncname]),
                                          C.stdvector(['offset']))
                corrpar_i = corrpar_t.sum.inputs
                corrpar_i['offset'](corr_sigma_t)

            corr_sigma_t.vararray.setLabel('Corr unc:\n' + name)
            corrpar_t.sum.setLabel('Corr correction:\n' + name)
            corrpars[name] = corrpar_t

            self.objects[('correlated_sigma', name)] = corr_sigma_t
            self.objects[('correlated_correction', name)] = corrpar_t

            self.transformations_out[name] = corrpar_t.transformations[0]
            self.outputs[name] = corrpar_t.single()
示例#9
0
    def bind_wsum(self, context):
        import ROOT as R
        self.set_tinit(R.WeightedSum)

        printl_debug('bind (osum: weighted) {}:'.format(type(self).__name__),
                     str(self))

        weight = self.objects[0].weight
        subobject = self.objects[0].object

        self.objects_orig = self.objects
        self.objects = [subobject]
        with nextlevel():
            IndexedContainer.bind(self, context, connect=False)

        from gna.constructors import stdvector
        with nextlevel():
            for freeidx in self.nindex.iterate():
                rindices = [ridx for ridx in self.nindex_to_reduce.iterate()]
                names = stdvector([
                    (ridx + freeidx).current_format('{autoindex}')
                    for ridx in rindices
                ])
                weights = stdvector([
                    weight.current_format(ridx + freeidx) for ridx in rindices
                ])

                tobj, newout = self.new_tobject(freeidx,
                                                weights,
                                                names,
                                                weight_label=weight.name)
                context.set_output(newout, self.name, freeidx)

                for i, (name, reduceidx) in enumerate(zip(names, rindices)):
                    fullidx = freeidx + reduceidx
                    inp = context.set_input(tobj.sum.inputs[name],
                                            self.name,
                                            freeidx,
                                            clone=i)
                    output = subobject.get_output(fullidx, context)
                    output >> inp
示例#10
0
文件: compound.py 项目: gnafit/gna
    def bind(self, context):
        printl_debug('bind (weighted) {}:'.format(type(self).__name__),
                     str(self))
        with nextlevel():
            IndexedContainer.bind(self, context, connect=False)

            from gna.constructors import stdvector
            if self.object.name is undefinedname:
                raise Exception(
                    'May not work with objects with undefined names')
            labels = stdvector([self.object.name])
            printl_debug('connect (weighted)')
            for idx in self.nindex.iterate():
                wname = self.weight.current_format(idx)
                weights = stdvector([wname])

                with context.ns:
                    tobj, newout = self.new_tobject(
                        idx, weights, labels, weight_label=self.weight.name)
                inp = tobj.transformations[0].inputs[0]
                context.set_output(newout, self.name, idx)
                context.set_input(inp, self.name, idx)
                out = self.object.get_output(idx, context)
                out >> inp
示例#11
0
def test_var_01(floatprecision='double'):
    """Test variable"""
    assert floatprecision in ['double', 'float']
    const = N.array([1.5, 2.6, 3.7], dtype=floatprecision[0])
    par = R.parameter('vector<%s>' % floatprecision)('testpar')
    par.value().resize(3)

    var = R.variable('vector<%s>' % floatprecision)(par)
    taintflag = R.taintflag('tflag')
    var.subscribe(taintflag)
    taintflag.set(False)

    vec = C.stdvector(const)
    par.set(vec)
    check('vec', None, list(var.value()), const, taintflag)
示例#12
0
文件: oscprob_v02.py 项目: gnafit/gna
    def define_variables(self):
        from gna.parameters.oscillation import reqparameters
        ns_pmns=self.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['Delta'].setFixed()
            ns_pmns['SigmaDecohRel'].setFixed()
            ns_pmns['SinSq23'].setFixed()
            ns_pmns.materializeexpressions()

        for i, vname in enumerate(names):
            ns_pmns[vname].setLabel('Psur(ee) weight %i: %s '%(i, vname))
示例#13
0
def test_par_04(floatprecision='double'):
    """Test setters"""
    assert floatprecision in ['double', 'float']
    const = N.array([1.5, 2.6, 3.7], dtype=floatprecision[0])
    var = R.parameter(floatprecision)('testpar', const.size)
    taintflag = R.taintflag('tflag')
    var.subscribe(taintflag)
    taintflag.set(False)

    var.set(const)
    check('C array', None, list(var.values()), const, taintflag)

    const += 1.0
    vec = C.stdvector(const)
    var.set(vec)
    check('std vector', None, list(var.values()), const, taintflag)
示例#14
0
    def build(self):
        with self.common_namespace:
            expose_matrix = self.cfg.get('expose_matrix', False)
            eres = self.eres = R.EnergyResolution(C.stdvector(self.names),
                                                  expose_matrix,
                                                  ns=self.common_namespace)

            eres.matrix.setLabel('Energy resolution\nmatrix')
            self.set_input(eres.matrix.Edges, 'eres_matrix', clone=0)
            self.set_output(eres.matrix.FakeMatrix, 'eres_matrix')

            trans = eres.smear
            for i, it in enumerate(self.idx.iterate()):
                if i:
                    trans = eres.add_transformation()
                    eres.add_input()
                label = it.current_format('Energy resolution\n{autoindex}')
                trans.setLabel(label)

                self.set_input(trans.inputs.back(), 'eres', it, clone=0)
                self.set_output(trans.outputs.back(), 'eres', it)
示例#15
0
def test_vars_02(opts, function_name):
    print('Test inputs/outputs/variables (Dummy)')
    mat1 = N.arange(12, dtype='d').reshape(3, 4)
    mat2 = N.arange(15, dtype='d').reshape(5, 3)

    with context.manager(100) as manager:
        dummy, points1, points2, ns = gpuargs_make(function_name, mat1, mat2)
        manager.setVariables(
            C.stdvector([par.getVariable() for (name, par) in ns.walknames()]))

    dummy.dummy.switchFunction('dummy_gpuargs_h')
    dummy.add_input(points1, 'input1')
    dummy.add_input(points2, 'input2')
    dummy.add_output('out1')
    dummy.add_output('out2')

    dummy.print()

    res1 = dummy.dummy.out1.data()
    res2 = dummy.dummy.out2.data()
    dt1 = dummy.dummy.out1.datatype()
    dt2 = dummy.dummy.out2.datatype()

    assert N.allclose(res1, 0.0), "C++ and Python results doesn't match"
    assert N.allclose(res2, 1.0), "C++ and Python results doesn't match"

    print('Result (C++ Data to numpy)')
    print(res1)
    print(res2)
    print()

    print('Datatype:', str(dt1))
    print('Datatype:', str(dt2))

    print('Change 3d variable')
    ns['par3'].set(-1.0)
    res1 = dummy.dummy.out1.data()
示例#16
0
    with ns:
        oscprob = C.OscProb3(from_nu, to_nu, 'L', modecos, labels=clabels)
        unity = C.FillLike(1, labels='Unity')

        E >> (unity.fill, oscprob.comp12, oscprob.comp13, oscprob.comp23)

        ws = C.WeightedSum(weights, labels, labels='OscProb')
        unity          >> ws.sum.comp0
        oscprob.comp12 >> ws.sum.item12
        oscprob.comp13 >> ws.sum.item13
        oscprob.comp23 >> ws.sum.item23

        ns.materializeexpressions()
        pars = tuple(par.getVariable() for (name,par) in ns.walknames())
        manager.setVariables(C.stdvector(pars))

if args.graph:
    from gna.graphviz import savegraph
    savegraph(ws.sum, args.graph)

    name, ext = args.graph.rsplit('.', 1)
    savegraph(ws.sum, name+'_vars.'+ext, namespace=ns)

out = ws.sum.sum

from gna.bindings import common
fig = plt.figure()
ax = plt.subplot( 111 )
ax.minorticks_on()
ax.grid()
示例#17
0
labels = [ 'arr1', 'arr2' ]
weights = [ 'w1', 'w2' ]

"""Initialize environment"""
p1 = env.globalns.defparameter( weights[0], central=1.0, sigma=0.1 )
p2 = env.globalns.defparameter( weights[1], central=1.0, sigma=0.1 )

env.globalns.printparameters()

"""Initialize transformations"""
points1 = Points( arr1 )
points2 = Points( arr2 )

"""Mode1: a1*w1+a2*w2"""
ws = R.WeightedSum( stdvector(weights), stdvector(labels) )
ws.sum.arr1(points1.points)
ws.sum.arr2(points2.points)

print( 'Mode1: a1*w1+a2*w2' )
print( '  ', p1.value(), p2.value(), ws.sum.sum.data() )
p1.set(2)
print( '  ', p1.value(), p2.value(), ws.sum.sum.data() )
p2.set(2)
print( '  ', p1.value(), p2.value(), ws.sum.sum.data() )
p1.set(1)
p2.set(1)
print()

"""Mode2: a1*w1+a2"""
ws = R.WeightedSum( stdvector(weights[:1]), stdvector(labels) )
示例#18
0
    def define_variables(self):
        pmnspars_kwargs = dict()
        pmns_name = self.get_globalname('pmns')
        ns_pmns = self.namespace(pmns_name)

        #
        # Define oscillation parameters
        #
        pars = self.cfg['parameters']
        otherpars = dict(SinSq23=0.542, )
        labels = OrderedDict([
            ('DeltaMSq23', 'Mass splitting |Δm²₂₃|'),
            ('DeltaMSq12', 'Mass splitting |Δm²₂₁|'),
            ('SinSqDouble13', 'Reactor mixing amplitude sin²2θ₁₃ '),
            ('SinSqDouble12', 'Solar mixing amplitude sin²2θ₁₂'),
            ('SinSq23', 'Atmospheric mixing angle sin²θ₂₃'),
        ])

        allfixed = self.cfg.get('fixed', False)
        for name, label in labels.items():
            if name in pars:
                central, sigma = pars[name], None
                free = not allfixed
            else:
                central, sigma = otherpars[name], None
                free = False
            if isinstance(central, (tuple, list)):
                central, sigma = central

            if sigma:
                ns_pmns.reqparameter(name,
                                     central=central,
                                     sigma=sigma,
                                     fixed=allfixed,
                                     label=label)
            else:
                ns_pmns.reqparameter(name,
                                     central=central,
                                     free=free,
                                     fixed=not free,
                                     label=label)

        ns_pmns.reqparameter('Alpha',
                             type='discrete',
                             default='normal',
                             variants={
                                 'normal': 1.0,
                                 'inverted': -1.0
                             },
                             label='Neutrino mass ordering α')
        ns_pmns.reqparameter('Delta',
                             type='uniformangle',
                             central=0.0,
                             fixed=True,
                             label='CP violation phase δ(CP)')

        #
        # Define oscillation expressions to provide missing and conjucated oscillation parameters
        # Define PMNS oscillation parameters
        #
        with ns_pmns:
            self._expressions_pars = C.OscillationExpressions(ns=ns_pmns)
            self._expressions_pmns = C.PMNSExpressionsC(ns=ns_pmns)

        #
        # Define oscillation weights
        #
        names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23'])
        with ns_pmns:
            self._expressions_oscprob = 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))
示例#19
0
    '--mode',
    default='gl',
    choices=['gl', 'rect_left', 'rect', 'rect_right', 'trap', 'gl21'],
    help='integration mode')
parser.add_argument('-d',
                    '--dump',
                    action='store_true',
                    help='dump integrator')
parser.add_argument('--dot', help='write graphviz output')
opts = parser.parse_args()
"""Initialize the function and environment"""
ns = env.globalns
ns.defparameter('alpha', central=-0.5, sigma=0.1)
print_parameters(ns)

names = stdvector(('alpha', ))
fcn_we = R.WeightedSum(names, names)
fcn_input = fcn_we.sum.alpha

fcn_e = R.Exp()
fcn_e.exp.points(fcn_we.sum.sum)
fcn_output = fcn_e.exp.result
"""Initialize the integrator"""
# create array with bin edges
edges = N.arange(*opts.bins, dtype='d')

alpha = ns['alpha'].value()
a, b = edges[0], edges[-1]
integral = (N.exp(alpha * b) - N.exp(alpha * a)) / alpha
aa, bb = edges[:-1], edges[1:]
integrals = (N.exp(alpha * bb) - N.exp(alpha * aa)) / alpha
示例#20
0
def main(opts):
    global savefig
    cfg = NestedDict(
        bundle=dict(
            name='energy_nonlinearity_birks_cherenkov',
            version='v01',
            nidx=[('r', 'reference', ['R1', 'R2'])],
            major=[],
        ),
        stopping_power='stoppingpower.txt',
        annihilation_electrons=dict(
            file='input/hgamma2e.root',
            histogram='hgamma2e_1KeV',
            scale=1.0 / 50000  # event simulated
        ),
        pars=uncertaindict(
            [
                ('birks.Kb0', (1.0, 'fixed')),
                ('birks.Kb1', (15.2e-3, 0.1776)),
                # ('birks.Kb2',           (0.0, 'fixed')),
                ("cherenkov.E_0", (0.165, 'fixed')),
                ("cherenkov.p0", (-7.26624e+00, 'fixed')),
                ("cherenkov.p1", (1.72463e+01, 'fixed')),
                ("cherenkov.p2", (-2.18044e+01, 'fixed')),
                ("cherenkov.p3", (1.44731e+01, 'fixed')),
                ("cherenkov.p4", (3.22121e-02, 'fixed')),
                ("Npescint", (1341.38, 0.0059)),
                ("kC", (0.5, 0.4737)),
                ("normalizationEnergy", (12.0, 'fixed'))
            ],
            mode='relative'),
        integration_order=2,
        correlations_pars=['birks.Kb1', 'Npescint', 'kC'],
        correlations=[1.0, 0.94, -0.97, 0.94, 1.0, -0.985, -0.97, -0.985, 1.0],
        fill_matrix=True,
        labels=dict(normalizationEnergy='Pessimistic'),
    )

    ns = env.globalns('energy')
    quench = execute_bundle(cfg, namespace=ns)
    ns.printparameters(labels=True)
    print()
    normE = ns['normalizationEnergy'].value()

    #
    # Input bins
    #
    evis_edges_full_input = N.arange(0.0, 15.0 + 1.e-6, 0.025)
    evis_edges_full_hist = C.Histogram(evis_edges_full_input,
                                       labels='Evis bin edges')
    evis_edges_full_hist >> quench.context.inputs.evis_edges_hist['00']

    #
    # Python energy model interpolation function
    #
    from scipy.interpolate import interp1d
    lsnl_x = quench.histoffset.histedges.points_truncated.data()
    lsnl_y = quench.positron_model_relative.single().data()
    lsnl_fcn = interp1d(lsnl_x, lsnl_y, kind='quadratic')

    #
    # Energy resolution
    #
    def eres_sigma_rel(edep):
        return 0.03 / edep**0.5

    def eres_sigma_abs(edep):
        return 0.03 * edep**0.5

    #
    # Energy offset
    #
    from physlib import pc
    edep_offset = pc.DeltaNP - pc.ElectronMass

    #
    # Oscprob
    #
    baselinename = 'L'
    ns = env.ns("oscprob")
    import gna.parameters.oscillation
    gna.parameters.oscillation.reqparameters(ns)
    ns.defparameter(baselinename,
                    central=52.0,
                    fixed=True,
                    label='Baseline, km')

    #
    # Define energy range
    #
    enu_input = N.arange(1.8, 15.0, 0.001)
    edep_input = enu_input - edep_offset
    edep_lsnl = edep_input * lsnl_fcn(edep_input)

    # Initialize oscillation variables
    enu = C.Points(enu_input, labels='Neutrino energy, MeV')
    component_names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23'])
    with ns:
        R.OscProbPMNSExpressions(R.Neutrino.ae(),
                                 R.Neutrino.ae(),
                                 component_names,
                                 ns=ns)

        labels = [
            'Oscillation probability|%s' % s
            for s in ('component 12', 'component 13', 'component 23', 'full',
                      'probsum')
        ]
        oscprob = R.OscProbPMNS(R.Neutrino.ae(),
                                R.Neutrino.ae(),
                                baselinename,
                                labels=labels)

    enu >> oscprob.full_osc_prob.Enu
    enu >> (oscprob.comp12.Enu, oscprob.comp13.Enu, oscprob.comp23.Enu)

    unity = C.FillLike(1, labels='Unity')
    enu >> unity.fill.inputs[0]
    with ns:
        op_sum = C.WeightedSum(component_names, [
            unity.fill.outputs[0], oscprob.comp12.comp12,
            oscprob.comp13.comp13, oscprob.comp23.comp23
        ],
                               labels='Oscillation probability sum')

    psur = op_sum.single().data()

    from scipy.signal import argrelmin, argrelmax
    psur_minima, = argrelmin(psur)
    psur_maxima, = argrelmax(psur)

    def build_extrema(x):
        data_min_x = (x[psur_minima][:-1] + x[psur_minima][1:]) * 0.5
        data_min_y = (x[psur_minima][1:] - x[psur_minima][:-1])

        data_max_x = (x[psur_maxima][:-1] + x[psur_maxima][1:]) * 0.5
        data_max_y = (x[psur_maxima][1:] - x[psur_maxima][:-1])

        data_ext_x = N.vstack([data_max_x, data_min_x]).T.ravel()
        data_ext_y = N.vstack([data_max_y, data_min_y]).T.ravel()

        return data_ext_x, data_ext_y

    psur_ext_x_enu, psur_ext_y_enu = build_extrema(enu_input)
    psur_ext_x_edep, psur_ext_y_edep = build_extrema(edep_input)
    psur_ext_x_edep_lsnl, psur_ext_y_edep_lsnl = build_extrema(edep_lsnl)

    #
    # Plots and tests
    #
    if opts.output and opts.output.endswith('.pdf'):
        pdfpages = PdfPages(opts.output)
        pdfpagesfilename = opts.output
        savefig_old = savefig
        pdf = pdfpages.__enter__()

        def savefig(*args, **kwargs):
            if opts.individual and args and args[0]:
                savefig_old(*args, **kwargs)
            pdf.savefig()
    else:
        pdf = None
        pdfpagesfilename = ''
        pdfpages = None

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel('Evis/Edep')
    ax.set_title('Positron energy nonlineairty')
    quench.positron_model_relative.single().plot_vs(
        quench.histoffset.histedges.points_truncated, label='definition range')
    quench.positron_model_relative_full.plot_vs(
        quench.histoffset.histedges.points,
        '--',
        linewidth=1.,
        label='full range',
        zorder=0.5)
    ax.vlines(normE, 0.0, 1.0, linestyle=':')

    ax.legend(loc='lower right')
    ax.set_ylim(0.8, 1.05)
    savefig(opts.output, suffix='_total_relative')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel(r'$\sigma/E$')
    ax.set_title('Energy resolution')
    ax.plot(edep_input, eres_sigma_rel(edep_input), '-')

    savefig(opts.output, suffix='_eres_rel')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel(r'$\sigma$')
    ax.set_title('Energy resolution')
    ax.plot(edep_input, eres_sigma_abs(edep_input), '-')

    savefig(opts.output, suffix='_eres_abs')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Enu, MeV')
    ax.set_ylabel('Psur')
    ax.set_title('Survival probability')
    op_sum.single().plot_vs(enu.single(), label='full')
    ax.plot(enu_input[psur_minima],
            psur[psur_minima],
            'o',
            markerfacecolor='none',
            label='minima')
    ax.plot(enu_input[psur_maxima],
            psur[psur_maxima],
            'o',
            markerfacecolor='none',
            label='maxima')

    savefig(opts.output, suffix='_psur_enu')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel('Psur')
    ax.set_title('Survival probability')
    op_sum.single().plot_vs(edep_input, label='true')
    op_sum.single().plot_vs(edep_lsnl, label='with LSNL')

    ax.legend()

    savefig(opts.output, suffix='_psur_edep')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Enu, MeV')
    ax.set_ylabel('Dist, MeV')
    ax.set_title('Nearest peaks distance')

    ax.plot(psur_ext_x_enu, psur_ext_y_enu, 'o-', markerfacecolor='none')

    savefig(opts.output, suffix='_dist_enu')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel('Dist, MeV')
    ax.set_title('Nearest peaks distance')

    ax.plot(psur_ext_x_edep,
            psur_ext_y_edep,
            '-',
            markerfacecolor='none',
            label='true')
    ax.plot(psur_ext_x_edep_lsnl,
            psur_ext_y_edep_lsnl,
            '-',
            markerfacecolor='none',
            label='with LSNL')
    ax.plot(edep_input,
            eres_sigma_abs(edep_input),
            '-',
            markerfacecolor='none',
            label=r'$\sigma$')

    ax.legend(loc='upper left')

    savefig(opts.output, suffix='_dist')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel(r'Dist/$\sigma$')
    ax.set_title('Resolution ability')

    x1, y1 = psur_ext_x_edep, psur_ext_y_edep / eres_sigma_abs(psur_ext_x_edep)
    x2, y2 = psur_ext_x_edep_lsnl, psur_ext_y_edep_lsnl / eres_sigma_abs(
        psur_ext_x_edep_lsnl)

    ax.plot(x1, y1, '-', markerfacecolor='none', label='true')
    ax.plot(x2, y2, '-', markerfacecolor='none', label='with LSNL')

    ax.legend(loc='upper left')
    savefig(opts.output, suffix='_ability')

    ax.set_xlim(3, 4)
    ax.set_ylim(5, 8)
    savefig(opts.output, suffix='_ability_zoom')

    fig = P.figure()
    ax = P.subplot(111)
    ax.minorticks_on()
    ax.grid()
    ax.set_xlabel('Edep, MeV')
    ax.set_ylabel(r'Dist/$\sigma$')
    ax.set_title('Resolution ability difference (quenching-true)')

    y2fcn = interp1d(x2, y2)
    y2_on_x1 = y2fcn(x1)
    diff = y2_on_x1 - y1
    from scipy.signal import savgol_filter
    diff = savgol_filter(diff, 21, 3)

    ax.plot(x1, diff)

    savefig(opts.output, suffix='_ability_diff')

    if pdfpages:
        pdfpages.__exit__(None, None, None)
        print('Write output figure to', pdfpagesfilename)

    savegraph(quench.histoffset.histedges.points_truncated,
              opts.graph,
              namespace=ns)

    if opts.show:
        P.show()
示例#21
0
#!/usr/bin/env python

import gna.constructors as C

vec = C.stdvector(['str1', 'str2', 'str3'])
print(vec, list(vec))
示例#22
0
def test_oscprob():
    baselinename = 'L'
    ns = env.ns("testoscprob")
    gna.parameters.oscillation.reqparameters(ns)
    ns.defparameter(baselinename,
                    central=2.0,
                    fixed=True,
                    label='Baseline, km')

    # Define energy range
    enu_input = np.arange(1.0, 10.0, 0.01)
    enu = C.Points(enu_input, labels='Neutrino energy, MeV')

    # Initialize oscillation variables
    component_names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23'])
    with ns:
        R.OscProbPMNSExpressions(R.Neutrino.ae(),
                                 R.Neutrino.ae(),
                                 component_names,
                                 ns=ns)

    # Initialize neutrino oscillations
    with ns:
        labels = [
            'Oscillation probability|%s' % s
            for s in ('component 12', 'component 13', 'component 23', 'full',
                      'probsum')
        ]
        oscprob = C.OscProbPMNS(R.Neutrino.ae(),
                                R.Neutrino.ae(),
                                baselinename,
                                labels=labels)

    enu >> oscprob.full_osc_prob.Enu
    enu >> (oscprob.comp12.Enu, oscprob.comp13.Enu, oscprob.comp23.Enu)

    # Oscillation probability as single transformation
    op_full = oscprob.full_osc_prob.oscprob

    # Oscillation probability as weighted sum
    unity = C.FillLike(1, labels='Unity')
    enu >> unity.fill.inputs[0]
    with ns:
        op_sum = C.WeightedSum(component_names, [
            unity.fill.outputs[0], oscprob.comp12.comp12,
            oscprob.comp13.comp13, oscprob.comp23.comp23
        ],
                               labels='Oscillation probability sum')

    # Print some information
    oscprob.print()
    print()

    ns.printparameters(labels=True)

    # Print extended information
    oscprob.print(data=True, slice=slice(None, 5))

    assert np.allclose(op_full.data(), op_sum.data())

    if "pytest" not in sys.modules:
        fig = plt.figure()
        ax = plt.subplot(111)
        ax.minorticks_on()
        ax.grid()
        ax.set_xlabel('E nu, MeV')
        ax.set_ylabel('P')
        ax.set_title('Oscillation probability')

        op_full.plot_vs(enu.single(), '-', label='full oscprob')
        op_sum.plot_vs(enu.single(), '--', label='oscprob (sum)')

        ax.legend(loc='lower right')

        savefig('output/test_oscprob.pdf')
        savegraph(enu, 'output/test_oscprob_graph.dot', namespace=ns)
        savegraph(enu, 'output/test_oscprob_graph.pdf', namespace=ns)

        plt.show()
示例#23
0
def main(opts):
    global savefig

    if opts.output and opts.output.endswith('.pdf'):
        pdfpages = PdfPages(opts.output)
        pdfpagesfilename=opts.output
        savefig_old=savefig
        pdf=pdfpages.__enter__()
        def savefig(*args, **kwargs):
            close = kwargs.pop('close', False)
            if opts.individual and args and args[0]:
                savefig_old(*args, **kwargs)
            pdf.savefig()
            if close:
                P.close()
    else:
        pdf = None
        pdfpagesfilename = ''
        pdfpages = None

    cfg = NestedDict(
        bundle = dict(
            name='energy_nonlinearity_birks_cherenkov',
            version='v01',
            nidx=[ ('r', 'reference', ['R1', 'R2']) ],
            major=[],
            ),
        stopping_power='data/data_juno/energy_model/2019_birks_cherenkov_v01/stoppingpower.txt',
        annihilation_electrons=dict(
            file='data/data_juno/energy_model/2019_birks_cherenkov_v01/hgamma2e.root',
            histogram='hgamma2e_1KeV',
                            scale=1.0/50000 # events simulated
            ),
        pars = uncertaindict(
            [
                ('birks.Kb0',               (1.0, 'fixed')),
                ('birks.Kb1',           (15.2e-3, 0.1776)),
                # ('birks.Kb2',           (0.0, 'fixed')),
                ("cherenkov.E_0",         (0.165, 'fixed')),
                ("cherenkov.p0",  ( -7.26624e+00, 'fixed')),
                ("cherenkov.p1",   ( 1.72463e+01, 'fixed')),
                ("cherenkov.p2",  ( -2.18044e+01, 'fixed')),
                ("cherenkov.p3",   ( 1.44731e+01, 'fixed')),
                ("cherenkov.p4",   ( 3.22121e-02, 'fixed')),
                ("Npescint",            (1341.38, 0.0059)),
                ("kC",                      (0.5, 0.4737)),
                ("normalizationEnergy",   (11.9999999, 'fixed'))
             ],
            mode='relative'
            ),
        integration_order = 2,
        correlations_pars = [ 'birks.Kb1', 'Npescint', 'kC' ],
        correlations = [ 1.0,   0.94, -0.97,
                         0.94,  1.0,  -0.985,
                        -0.97, -0.985, 1.0   ],
        fill_matrix=True,
        labels = dict(
            normalizationEnergy = 'Pessimistic'
            ),
        )

    ns = env.globalns('energy')
    quench = execute_bundle(cfg, namespace=ns)
    print()
    normE = ns['normalizationEnergy'].value()

    #
    # Input bins
    #
    evis_edges_full_input = N.arange(0.0, 15.0+1.e-6, 0.001)
    evis_edges_full_hist = C.Histogram(evis_edges_full_input, labels='Evis bin edges')
    evis_edges_full_hist >> quench.context.inputs.evis_edges_hist['00']

    #
    # Python energy model interpolation function
    #
    lsnl_x = quench.histoffset.histedges.points_truncated.data()
    lsnl_y = quench.positron_model_relative.single().data()
    lsnl_fcn = interp1d(lsnl_x, lsnl_y, kind='quadratic', bounds_error=False, fill_value='extrapolate')

    #
    # Energy resolution
    #
    def eres_sigma_rel(edep):
        return 0.03/edep**0.5

    def eres_sigma_abs(edep):
        return 0.03*edep**0.5

    #
    # Oscprob
    #
    baselinename='L'
    ns = env.ns("oscprob")
    import gna.parameters.oscillation
    gna.parameters.oscillation.reqparameters(ns)
    ns.defparameter(baselinename, central=52.0, fixed=True, label='Baseline, km')

    #
    # Define energy range
    #
    data = Data(N.arange(1.8, 15.0, 0.001), lsnl_fcn=lsnl_fcn, eres_fcn=eres_sigma_abs)

    # Initialize oscillation variables
    enu = C.Points(data.enu, labels='Neutrino energy, MeV')
    component_names = C.stdvector(['comp0', 'comp12', 'comp13', 'comp23'])
    with ns:
        R.OscProbPMNSExpressions(R.Neutrino.ae(), R.Neutrino.ae(), component_names, ns=ns)

        labels=['Oscillation probability|%s'%s for s in ('component 12', 'component 13', 'component 23', 'full', 'probsum')]
        oscprob = R.OscProbPMNS(R.Neutrino.ae(), R.Neutrino.ae(), baselinename, labels=labels)

    enu >> oscprob.full_osc_prob.Enu
    enu >> (oscprob.comp12.Enu, oscprob.comp13.Enu, oscprob.comp23.Enu)

    unity = C.FillLike(1, labels='Unity')
    enu >> unity.fill.inputs[0]
    with ns:
        op_sum = C.WeightedSum(component_names, [unity.fill.outputs[0], oscprob.comp12.comp12, oscprob.comp13.comp13, oscprob.comp23.comp23], labels='Oscillation probability sum')

    oscprob.printtransformations()
    env.globalns.printparameters(labels=True)

    ns = env.globalns('oscprob')
    data.set_dm_par(ns['DeltaMSqEE'])
    data.set_nmo_par(ns['Alpha'])
    data.set_psur_fcn(op_sum.single().data)
    data.build()

    #
    # Plotting
    #
    xmax = 12.0

    #
    # Positron non-linearity
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='Evis/Edep', title='Positron energy nonlineairty')
    ax.minorticks_on(); ax.grid()
    quench.positron_model_relative.single().plot_vs(quench.histoffset.histedges.points_truncated, label='definition range')
    quench.positron_model_relative_full.plot_vs(quench.histoffset.histedges.points, '--', linewidth=1., label='full range', zorder=0.5)
    ax.vlines(normE, 0.0, 1.0, linestyle=':')
    ax.legend(loc='lower right')
    ax.set_ylim(0.8, 1.05)
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_total_relative', close=not opts.show_all)

    #
    # Positron non-linearity derivative
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='dEvis/dEdep', title='Positron energy nonlineairty derivative')
    ax.minorticks_on(); ax.grid()
    e = quench.histoffset.histedges.points_truncated.single().data()
    f = quench.positron_model_relative.single().data()*e
    ec = (e[1:] + e[:-1])*0.5
    df = (f[1:] - f[:-1])
    dedf = (e[1:] - e[:-1])/df
    ax.plot(ec, dedf)
    ax.legend(loc='lower right')
    ax.set_ylim(0.975, 1.01)
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_total_derivative', close=not opts.show_all)

    #
    # Positron non-linearity effect
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='Evis/Edep', title='Positron energy nonlineairty')
    ax.minorticks_on(); ax.grid()

    es = N.arange(1.0, 3.1, 0.5)
    esmod = es*lsnl_fcn(es)
    esmod_shifted = esmod*(es[-1]/esmod[-1])
    ax.vlines(es, 0.0, 1.0, linestyle='--', linewidth=2, alpha=0.5, color='green', label='Edep')
    ax.vlines(esmod, 0.0, 1.0, linestyle='-', color='red', label='Edep quenched')
    ax.legend()
    savefig(opts.output, suffix='_quenching_effect_0')

    ax.vlines(esmod_shifted, 0.0, 1.0, linestyle=':', color='blue', label='Edep quenched, scaled')
    ax.legend()
    savefig(opts.output, suffix='_quenching_effect_1', close=not opts.show_all)

    #
    # Energy resolution
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel=r'$\sigma/E$', title='Energy resolution')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.edep, eres_sigma_rel(data.edep), '-')
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_eres_rel', close=not opts.show_all)

    #
    # Energy resolution
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel= 'Edep, MeV', ylabel= r'$\sigma$', title='Energy resolution')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.edep, eres_sigma_abs(data.edep), '-')
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_eres_abs', close=not opts.show_all)

    #
    # Survival probability vs Enu
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Enu, MeV', ylabel='Psur', title='Survival probability')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.enu, data.data_no.psur[data.dmmid_idx], label=r'full NO')
    ax.plot(data.enu, data.data_io.psur[data.dmmid_idx], label=r'full IO')
    ax.plot(data.data_no.data_enu.psur_e[data.dmmid_idx], data.data_no.data_enu.psur[data.dmmid_idx], '^', markerfacecolor='none')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_psur_enu')

    ax.set_xlim(2.0, 4.5)
    savefig(opts.output, suffix='_psur_enu_zoom', close=not opts.show_all)

    #
    # Survival probability vs Edep
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='Psur', title='Survival probability')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.edep, data.data_no.psur[data.dmmid_idx], label=r'full NO')
    ax.plot(data.edep, data.data_io.psur[data.dmmid_idx], label=r'full IO')
    ax.plot(data.data_no.data_edep.psur_e[data.dmmid_idx], data.data_no.data_edep.psur[data.dmmid_idx], '^', markerfacecolor='none')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_psur_edep')

    ax.set_xlim(1.2, 3.7)
    savefig(opts.output, suffix='_psur_edep_zoom', close=not opts.show_all)

    #
    # Survival probability vs Edep_lsnl
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep quenched, MeV', ylabel='Psur', title='Survival probability')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.edep_lsnl, data.data_no.psur[data.dmmid_idx], label=r'full NO')
    ax.plot(data.edep_lsnl, data.data_io.psur[data.dmmid_idx], label=r'full IO')
    ax.plot(data.data_no.data_edep_lsnl.psur_e[data.dmmid_idx], data.data_no.data_edep_lsnl.psur[data.dmmid_idx], '^', markerfacecolor='none')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_psur_edep_lsnl')

    ax.set_xlim(1.2, 3.7)
    savefig(opts.output, suffix='_psur_edep_lsnl_zoom', close=not opts.show_all)

    #
    # Distance between nearest peaks vs Enu, single
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Enu, MeV', ylabel='Dist, MeV', title='Nearest peaks distance')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.data_no.data_enu.diff_x[data.dmmid_idx], data.data_no.data_enu.diff[data.dmmid_idx], label=r'NO')
    ax.plot(data.data_io.data_enu.diff_x[data.dmmid_idx], data.data_io.data_enu.diff[data.dmmid_idx], label=r'IO')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    ax.set_ylim(bottom=0.0)
    savefig(opts.output, suffix='_dist_enu')

    ax.set_xlim(2.0, 5.0)
    ax.set_ylim(top=0.5)
    savefig(opts.output, suffix='_dist_enu_zoom', close=not opts.show_all)

    #
    # Distance between nearest peaks vs Edep, single
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='Dist, MeV', title='Nearest peaks distance')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.data_no.data_edep.diff_x[data.dmmid_idx], data.data_no.data_edep.diff[data.dmmid_idx], label=r'NO')
    ax.plot(data.data_io.data_edep.diff_x[data.dmmid_idx], data.data_io.data_edep.diff[data.dmmid_idx], label=r'IO')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    ax.set_ylim(bottom=0.0)
    savefig(opts.output, suffix='_dist_edep')

    ax.set_xlim(1.2, 4.2)
    ax.set_ylim(top=0.5)
    savefig(opts.output, suffix='_dist_edep_zoom', close=not opts.show_all)

    #
    # Distance between nearest peaks vs Edep, single
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep quenched, MeV', ylabel='Dist, MeV', title='Nearest peaks distance')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.data_no.data_edep_lsnl.diff_x[data.dmmid_idx], data.data_no.data_edep_lsnl.diff[data.dmmid_idx], label=r'NO')
    ax.plot(data.data_io.data_edep_lsnl.diff_x[data.dmmid_idx], data.data_io.data_edep_lsnl.diff[data.dmmid_idx], label=r'IO')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    ax.set_ylim(bottom=0.0)
    savefig(opts.output, suffix='_dist_edep_lsnl')

    ax.set_xlim(1.2, 4.2)
    ax.set_ylim(top=0.5)
    savefig(opts.output, suffix='_dist_edep_lsnl_zoom')

    poly = N.polynomial.polynomial.Polynomial([0, 1, 0])
    x = data.data_no.data_edep_lsnl.diff_x[data.dmmid_idx]
    pf = poly.fit(x, data.data_no.data_edep_lsnl.diff[data.dmmid_idx], 2)
    print(pf)
    ax.plot(x, pf(x), label=r'NO fit')
    ax.legend()
    savefig(opts.output, suffix='_dist_edep_lsnl_fit', close=not opts.show_all)

    #
    # Distance between nearest peaks vs Edep, multiple
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep quenched, MeV', ylabel='Dist, MeV', title='Nearest peaks distance')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.data_no.data_edep_lsnl.diff_x[data.dmmid_idx], data.data_no.data_edep_lsnl.diff[data.dmmid_idx], label=r'NO')
    ax.plot(data.data_io.data_edep_lsnl.diff_x[data.dmmid_idx], data.data_io.data_edep_lsnl.diff[data.dmmid_idx], '--', label=r'IO')
    for idx in (0, 5, 15, 20):
        ax.plot(data.data_io.data_edep_lsnl.diff_x[idx], data.data_io.data_edep_lsnl.diff[idx], '--')
    ax.legend()
    ax.set_xlim(0.0, xmax)
    savefig(opts.output, suffix='_dist_edep_lsnl_multi', close=not opts.show_all)

    #
    # Distance between nearest peaks difference
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='Dist(IO) - Dist(NO), MeV', title='Nearest peaks distance diff: IO-NO')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.e, data.diffs.edep[data.dmmid_idx], '-', markerfacecolor='none', label='Edep')
    ax.plot(data.e, data.diffs.edep_lsnl[data.dmmid_idx], '-', markerfacecolor='none', label='Edep quenched')
    ax.plot(data.e, data.diffs.enu[data.dmmid_idx], '-', markerfacecolor='none', label='Enu')
    ax.legend()
    savefig(opts.output, suffix='_dist_diff')

    ax.plot(data.e, data.eres, '-', markerfacecolor='none', label='Resolution $\\sigma$')
    ax.legend()
    savefig(opts.output, suffix='_dist_diff_1')

    #
    # Distance between nearest peaks difference relative to sigma
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='(Dist(IO) - Dist(NO))/$\\sigma$', title='Nearest peaks distance diff: IO-NO')
    ax.minorticks_on(); ax.grid()
    ax.plot(data.e, data.diffs_rel.edep[data.dmmid_idx], '-', markerfacecolor='none', label='Edep')
    ax.plot(data.e, data.diffs_rel.edep_lsnl[data.dmmid_idx], '-', markerfacecolor='none', label='Edep quenched')

    i_edep=N.argmax(data.diffs_rel.edep[data.dmmid_idx])
    i_edep_lsnl=N.argmax(data.diffs_rel.edep_lsnl[data.dmmid_idx])
    ediff = data.e[i_edep] - data.e[i_edep_lsnl]
    ax.axvline(data.e[i_edep], linestyle='dashed', label='Max location: %.3f MeV'%(data.e[i_edep]))
    ax.axvline(data.e[i_edep_lsnl], linestyle='dashed', label='Max location: %.3f MeV'%(data.e[i_edep_lsnl]))
    ax.axvspan(data.e[i_edep], data.e[i_edep_lsnl], alpha=0.2, label='Max location diff: %.3f MeV'%(ediff))

    ax.legend()
    savefig(opts.output, suffix='_dist_diff_rel')

    #
    # Distance between nearest peaks difference relative to sigma
    #
    fig = P.figure()
    ax = P.subplot(111, xlabel='Edep, MeV', ylabel='(Dist(IO) - Dist(NO))/$\\sigma$', title='Nearest peaks distance diff: IO-NO')
    ax.minorticks_on(); ax.grid()
    ledep   = ax.plot(data.e, data.diffs_rel.edep[data.dmmid_idx],      '--', markerfacecolor='none', label='Edep')[0]
    lquench = ax.plot(data.e, data.diffs_rel.edep_lsnl[data.dmmid_idx], '-',  color=ledep.get_color(), markerfacecolor='none', label='Edep quenched')[0]

    kwargs=dict(alpha=0.8, linewidth=1.5, markerfacecolor='none')
    for idx in (0, 5, 15, 20):
        l = ax.plot(data.e, data.diffs_rel.edep[idx], '--', **kwargs)[0]
        ax.plot(data.e, data.diffs_rel.edep_lsnl[idx], '-', color=l.get_color(), **kwargs)
    ax.legend()
    savefig(opts.output, suffix='_dist_diff_rel_multi', close=not opts.show_all)

    #
    # Distance between nearest peaks difference relative to sigma
    #
    fig = P.figure()
    ax = P.subplot(111, ylabel=r'$\Delta m^2_\mathrm{ee}$', xlabel='Edep quenched, MeV',
                   title='Nearest peaks distance diff: IO-NO/$\\sigma$')
    ax.minorticks_on(); ax.grid()
    formatter = ax.yaxis.get_major_formatter()
    formatter.set_useOffset(False)
    formatter.set_powerlimits((-2,2))
    formatter.useMathText=True

    c = ax.pcolormesh(data.mesh_e.T, data.mesh_dm.T, data.diffs_rel.edep_lsnl.T)
    from mpl_tools.helpers import add_colorbar
    add_colorbar(c, rasterized=True)
    c.set_rasterized(True)
    savefig(opts.output, suffix='_dist_diff_rel_heatmap')

    if pdfpages:
        pdfpages.__exit__(None,None,None)
        print('Write output figure to', pdfpagesfilename)

    # savegraph(quench.histoffset.histedges.points_truncated, opts.graph, namespace=ns)

    if opts.show or opts.show_all:
        P.show()