Example #1
0
def test_kisa3():

    logger = getLogger('ostap.test_kisa3')

    if 62400 <= ROOT.gROOT.GetVersionInt() < 62406:
        logger.warning('Test can fail for %s' % ROOT.gROOT.GetVersion())

    h1 = ROOT.TH1D('h1', '', 100, 0, 20)
    h1 += lambda x: x

    ## from  ostap.trees.funcs import H1DFunc
    ## xh1 = H1DFunc ( histo = h1 , xvar = 'pt' )
    ## from  ostap.trees.funcs import FuncTH1
    ## xh1 = FuncTH1 ( histo = h1 , xvar = 'pt' )

    from ostap.fitting.pyselectors import SelectorWithVars, Variable
    variables = [
        ## Variable ( 'mass1' , 'mass(mu+mu-)' , 2 , 4 , lambda s : s.mass ) ,
        Variable('mass', 'mass(mu+mu-)', 3.09, 3.11),
        Variable('c2dtf', 'chi2(dtf)', -1, 10),
        ## Variable ( 'xpt'   , 'xpt'          , -1    , 30   , xh1 ) ,
        Variable('mass2', 'mass(mu+mu-)', 1, 5, MASS()),
        Variable('mass3', 'mass(mu+mu-)', 1, 5, 'mass')
    ]

    with timing('fill it!'):
        selector = SelectorWithVars(
            variables=variables,
            selection='2<=mass && mass<4 && 0<=c2dtf && c2dtf<5',
            silence=True)
        chain = data.chain
        st = chain.pprocess(selector, silent=False, shortcut=True)
        ds = selector.data
        del selector
    logger.info('Dataset (paralell):\n%s' % ds.table(prefix='# '))
Example #2
0
def test_kisa2 () :
       
    logger = getLogger ( 'ostap.test_kisa2' )

    if 62400 <= ROOT.gROOT.GetVersionInt() < 62406 :
        logger.warning ('Test can fail for %s' % ROOT.gROOT.GetVersion() )

    from ostap.fitting.pyselectors import SelectorWithVars, Variable  
    variables = [
        Variable   ( 'mass'  , 'mass(mu+mu-)' ,  3.09 , 3.11 ) , 
        Variable   ( 'c2dtf' , 'chi2(dtf)'    , -1    , 10   ) , 
        Variable   ( 'mass2' , 'mass(mu+mu-)' , 1 , 5 , MASS()  ) , 
        Variable   ( 'mass3' , 'mass(mu+mu-)' , 1 , 5 , 'mass'  ) 
        ]
    
    from sys import version_info  as python_version
    if  python_version.major < 3 :
        variables.append ( Variable ( 'mass1' , 'mass(mu+mu-)' , 2 , 4 , lambda s : s.mass ) )
    
    ppservers = () ## 'lxplus051' , )
    ## ppservers = 'auto'
    
    nf   = len ( data.files )
    nf //= 40
    nf  += 1 
    nf   = min ( nf , 25 )
    
    with timing('%d files in sequence %s' % ( nf , len( data.chain )  ) ) :
        selector = SelectorWithVars  (
            variables = variables ,
            selection = '2<=mass && mass<4 && 0<=c2dtf && c2dtf<5' ,
            silence   = False
            )
        chain =  data.chain[:nf]
        st = chain.process ( selector , silent = False , shortcut = True )
        ds = selector.data
        del selector 
    logger.info ( 'Dataset (sequential):\n%s' % ds.table()  )
    
    with timing('%s files in parallel %s' % ( len ( data.files ) , len( data.chain ) ) ) :
        selector = SelectorWithVars  (
            variables = variables ,
            selection = '2<=mass && mass<4 && 0<=c2dtf && c2dtf<5' ,
            silence   = True 
            )
        st = data.chain.parallel_fill ( selector               ,
                                        silent     = False     ,
                                        chunk_size = -1        ,
                                        max_files  =  1        ,
                                        ppservers  = ppservers )
        ds = selector.data 
        del selector 
    logger.info ( 'Dataset (paralell):\n%s' % ds.table ( prefix = '# ' ) )
Example #3
0
##    os.remove ( trainer.output_file )

# =============================================================================
## Use trained TMVA
#  There are two alternatives
#  - usage of TMVA Reader : it can be  rather slow,
#    but it is very flexible and powerful with respect to variable transformations
#  - addTMVAResponse function : it is less flexible, but very CPU efficient
# =============================================================================

## prepare dataset with TMVA result

from ostap.fitting.pyselectors import SelectorWithVars, Variable
## 1) Book RooDataset
variables = [
    Variable('var1', 'variable#1'),
    Variable('var2', 'variable#2'),
    Variable('var3', 'variable#3'),
]

## 2) create TMVA reader
from ostap.tools.tmva import Reader
reader = Reader('MyMLP',
                variables=[('var1', lambda s: s.var1),
                           ('var2', lambda s: s.var2),
                           ('var3', lambda s: s.var3)],
                weights_files=tar_file)

methods = reader.methods[:]

## # =============================================================================
Example #4
0
from ostap.fitting.pyselectors import SelectorWithVars, Variable
import ostap.parallel.parallel_fill

# =============================================================================
## configuration of reweighting
weightings = (
    ## variable          address in DB
    Weight.Var('x', 'x-reweight'),
    Weight.Var('y', 'y-reweight'),
    Weight.Var(('x', 'y'), '2D-reweight'),
)

# =============================================================================
## variables to be used in MC-dataset
variables = [
    Variable('x', 'x-var', 0, 20),
    Variable('y', 'y-var', 0, 15),
]
selector = SelectorWithVars(variables,
                            '0<x && x<20 && 0<y && y<20',
                            silence=True)
mctree.process(selector, silent=True)
mcds_ = selector.data  ## dataset
# =============================================================================
## start reweighting iterations:
for iter in range(1, maxIter + 1):

    tag = 'Reweighting iteration #%d' % iter
    logger.info(allright(tag))

    with timing(tag + ': prepare MC-dataset:', logger=logger):
Example #5
0
## Use trained TMVA/Chopping
#  There are two alternatives
#  - usage of TMVA/Chopper Reader : it can be  rather slow,
#    but it is very flexible and powerful with respect to variable transformations
#  - addChoppingResponse function : it is less flexible, but very CPU efficient
# =============================================================================

## category function
category = lambda s: int(s.evt * 137 + 813 * s.run) % N

## prepare dataset with TMVA/Chopping result

from ostap.fitting.pyselectors import SelectorWithVars, Variable
## 1) Book RooDataset
variables = [
    Variable('var1', 'variable#1'),
    Variable('var2', 'variable#2'),
    Variable('var3', 'variable#3'),
    ## extra: needed for addChoppingResponse
    Variable('evt', 'event'),
    Variable('run', 'run'),
    ## extra: needed for cross-checks
    Variable('cat', 'category', accessor=category),
]

## 2) create TMVA/Chopping reader
from ostap.tools.chopping import Reader

reader = Reader(
    N=N,  ##  number of   categories
    categoryfunc=category,  ## category 
else:
    logger.info('Existing weights DBASE will be used')

#
## make reweighting iterations
#
from ostap.tools.reweight import Weight, makeWeights, WeightingPlot, W2Data
from ostap.fitting.pyselectors import SelectorWithVars, Variable
import ostap.parallel.parallel_fill

# =============================================================================
## weighting configuration: ## variable     address in DB
weighting = (Weight.Var('x', address='x-reweight'), )
# ============================================================================
## variables to be used in MC-dataset
variables = [Variable('x', 'x-variable', 0, 100)]

# =============================================================================
## start iterations:
for iter in range(1, maxIter + 1):

    tag = 'Reweighting iteration #%d' % iter
    logger.info(allright(tag))

    with timing(tag + ': prepare MC-dataset:', logger=logger):

        # =============================================================================
        ## 0) The weighter object
        weighter = Weight(dbname, weighting)

        # ===============================================================================
Example #7
0
def test_fitting_fill_1():
    ## if 1 < 2 :
    logger = getLogger('test_fitting_fill_1')

    ## prepare data
    with timing("Prepare test data", logger=logger):
        files = prepare_data(4, 5000)
        data = Data('S', files)

    chain = data.chain

    mJPsi = ROOT.RooRealVar('mJPsi', 'mass(J/Psi) [GeV]', 3.0 * GeV, 3.2 * GeV)

    # =========================================================================
    logger.info(attention('All trivial variables'))
    # =========================================================================

    variables = [
        Variable(mJPsi, accessor='mass'),
        Variable('massMeV', 'mass in MeV', 3000, 3200, 'mass*1000.0'),
        Variable('vv102', 'vv10[2]', -1, 100, '1.0*vv10[2]'),
        Variable('fevt', accessor='1.0*evt'), ('pt', ), ('eta', ),
        ('x', 'some variable', 0, 5000, '(mass+pt+eta)/eta')
    ]

    config = {'variables': variables, 'selection': "pt>7 && eta<3"}

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=False)
        ds1_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=False)
        ds1_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=True)
        ds1_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=True)
        ds1_4 = selector.data

    if DataSet_NEW_FILL:
        with timing(" pure-FRAME (new) ", logger=None) as t5:
            logger.info(attention(t5.name))
            ds1_5, _ = chain.make_dataset(silent=False, **config)

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    if DataSet_NEW_FILL:
        table.append((t5.name, '%.3fs' % t5.delta))

    title1 = "All trivial variables"
    table1 = T.table(table, title=title1, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title1, table1))

    if ds1_1 != ds1_2:
        logger.error('Datasets ds1_1  and ds1_2   are different!')
    if ds1_1 != ds1_3:
        logger.error('Datasets ds1_1  and ds1_3   are different!')
    if ds1_1 != ds1_4:
        logger.error('Datasets ds1_1  and ds1_4   are different!')

    if DataSet_NEW_FILL:
        if ds1_1 != ds1_5:
            logger.error('Datasets ds1_1  and ds1_5   are different!')

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=False,
                            max_files=1)
        ds1p_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=False,
                            max_files=1)
        ds1p_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=True,
                            max_files=1)
        ds1p_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=True,
                            max_files=1)
        ds1p_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title1p = "All trivial variables (parallel)"
    table1p = T.table(table, title=title1p, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title1p, table1p))

    if ds1_1 != ds1p_1:
        logger.error('Datasets ds1_1  and ds1p_1  are different!')
    if ds1_2 != ds1p_2:
        logger.error('Datasets ds1_2  and ds1p_2  are different!')
    if ds1_3 != ds1p_3:
        logger.error('Datasets ds1_3  and ds1p_3  are different!')
    if ds1_4 != ds1p_4:
        logger.error('Datasets ds1_4  and ds1p_4  are different!')

    # =========================================================================
    logger.info(attention('Trivial variables + CUT'))
    # =========================================================================

    variables = [
        Variable(mJPsi, accessor='mass'),
        Variable('massMeV', 'mass in MeV', 3000, 3200, 'mass*1000'),
        Variable('vv102', 'vv10[2]', -1, 100, '1.0*vv10[2]'),
        Variable('fevt', accessor='1.0*evt'), ('pt', ), ('eta', ),
        ('x', 'some variable', 0, 5000, '(mass+pt+eta)/eta')
    ]

    if not DILL_PY3_issue:

        config = {
            'variables': variables,
            'selection': "pt>7 && eta<3",
            'cuts': lambda s: s.pt > 3
        }  ## ATTENTION: no trivial cuts!

    else:

        logger.warning('There is an issue with dill+python3: avoid lambda!')
        config = {
            'variables': variables,
            'selection': "pt>7 && eta<3",
            'cuts': ptcut
        }  ## ATTENTION: no trivial cuts!

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=False)
        ds2_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=False)
        ds2_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=True)
        ds2_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=True)
        ds2_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title2 = "Trivial variables + CUT"
    table2 = T.table(table, title=title2, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title2, table2))

    if ds2_1 != ds2_2:
        logger.error('Datasets ds2_1  and ds2_2   are different!')
    if ds2_1 != ds2_3:
        logger.error('Datasets ds2_1  and ds2_3   are different!')
    if ds2_1 != ds2_4:
        logger.error('Datasets ds2_1  and ds2_4   are different!')

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=False,
                            maX_files=1)
        ds2p_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=False,
                            maX_files=1)
        ds2p_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=True,
                            max_files=1)
        ds2p_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=True,
                            max_files=1)
        ds2p_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title2p = "Trivial variables + CUT (parallel)"
    table2p = T.table(table, title=title2p, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title2p, table2p))

    if ds1_1 != ds2_1:
        logger.error('Datasets ds1_1  and ds2_1   are different!')

    if ds2_1 != ds2p_1:
        logger.error('Datasets ds2_1  and ds2p_1  are different!')
    if ds2_2 != ds2p_2:
        logger.error('Datasets ds2_2  and ds2p_2  are different!')
    if ds2_3 != ds2p_3:
        logger.error('Datasets ds2_3  and ds2p_3  are different!')
    if ds2_4 != ds2p_4:
        logger.error('Datasets ds2_4  and ds2p_4  are different!')

    # =========================================================================
    logger.info(attention('Non-trivial variables'))
    # =========================================================================

    if not DILL_PY3_issue:

        variables = [
            Variable(mJPsi, accessor='mass'),
            Variable('massMeV', 'mass in MeV', 3000, 3200, 'mass*1000'),
            Variable('vv102', 'vv10[2]', -1, 100, '1.0*vv10[2]'),
            Variable('fevt', accessor='1.0*evt'), ('pt', ), ('eta', ),
            ('x', 'some variable', 0, 5000, lambda s:
             (s.mass + s.pt + s.eta) / s.eta)
        ]

    else:

        logger.warning('There is an issue with dill+python3: avoid lambda!')
        variables = [
            Variable(mJPsi, accessor='mass'),
            Variable('massMeV', 'mass in MeV', 3000, 3200, 'mass*1000'),
            Variable('vv102', 'vv10[2]', -1, 100, '1.0*vv10[2]'),
            Variable('fevt', accessor='1.0*evt'), ('pt', ), ('eta', ),
            ('x', 'some variable', 0, 5000, xvar)
        ]

    config = {'variables': variables, 'selection': "pt>7 && eta<3"}

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=False)
        ds3_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=False)
        ds3_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=True)
        ds3_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=True)
        ds3_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title3 = "Non-trivial variables"
    table3 = T.table(table, title=title3, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title3, table3))

    if ds1_1 != ds3_1:
        logger.error('Datasets ds1_1  and ds3_1   are different!')

    if ds3_1 != ds3_2:
        logger.error('Datasets ds3_1  and ds2_2   are different!')
    if ds3_1 != ds3_3:
        logger.error('Datasets ds3_1  and ds2_3   are different!')
    if ds3_1 != ds3_4:
        logger.error('Datasets ds3_1  and ds2_4   are different!')

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=False,
                            max_files=1)
        ds3p_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=False,
                            max_files=1)
        ds3p_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=True,
                            max_files=1)
        ds3p_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=True,
                            max_files=1)
        ds3p_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title3p = "Non-trivial variables (parallel)"
    table3p = T.table(table, title=title3p, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title3p, table3p))

    if ds3_1 != ds3p_1:
        logger.error('Datasets ds3_1  and ds3p_1  are different!')
    if ds3_2 != ds3p_2:
        logger.error('Datasets ds3_2  and ds3p_2  are different!')
    if ds3_3 != ds3p_3:
        logger.error('Datasets ds3_3  and ds3p_3  are different!')
    if ds3_4 != ds3p_4:
        logger.error('Datasets ds3_4  and ds3p_4  are different!')

    # =========================================================================
    logger.info(attention('Non-trivial variables + CUT'))
    # =========================================================================

    if not DILL_PY3_issue:

        variables = [
            Variable(mJPsi, accessor='mass'),
            Variable('massMeV', 'mass in MeV', 3000, 3200, 'mass*1000'),
            Variable('vv102', 'vv10[2]', -1, 100, '1.0*vv10[2]'),
            Variable('fevt', accessor='1.0*evt'), ('pt', ), ('eta', ),
            ('x', 'some variable', 0, 5000, lambda s:
             (s.mass + s.pt + s.eta) / s.eta)
        ]

    else:

        logger.warning('There is an issue with dill+python3: avoid lambda!')
        variables = [
            Variable(mJPsi, accessor='mass'),
            Variable('massMeV', 'mass in MeV', 3000, 3200, 'mass*1000'),
            Variable('vv102', 'vv10[2]', -1, 100, '1.0*vv10[2]'),
            Variable('fevt', accessor='1.0*evt'), ('pt', ), ('eta', ),
            ('x', 'some variable', 0, 5000, xvar)
        ]

    if not DILL_PY3_issue:

        config = {
            'variables': variables,
            'selection': "pt>7 && eta<3",
            'cuts': lambda s: s.pt > 3
        }  ## ATTENTION: no trivial cuts!
    else:

        logger.warning('There is an issue with dill+python3: avoid lambda!')
        config = {
            'variables': variables,
            'selection': "pt>7 && eta<3",
            'cuts': ptcut
        }  ## ATTENTION: no trivial cuts!

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=False)
        ds4_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=False)
        ds4_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=False, use_frame=True)
        ds4_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.fill_dataset(selector, shortcut=True, use_frame=True)
        ds4_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title4 = "Non-trivial variables + CUT"
    table4 = T.table(table, title=title4, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title4, table4))

    if ds1_1 != ds4_1:
        logger.error('Datasets ds1_1  and ds4_1   are different!')

    if ds4_1 != ds4_2:
        logger.error('Datasets ds4_1  and ds4_2   are different!')
    if ds4_1 != ds4_3:
        logger.error('Datasets ds4_1  and ds4_3   are different!')
    if ds4_1 != ds4_4:
        logger.error('Datasets ds4_1  and ds4_4   are different!')

    with timing("No SHORTCUT, no FRAME", logger=None) as t1:
        logger.info(attention(t1.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=False,
                            max_files=1)
        ds4p_1 = selector.data
    with timing("   SHORTCUT, no FRAME", logger=None) as t2:
        logger.info(attention(t2.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=False,
                            max_files=1)
        ds4p_2 = selector.data
    with timing("No SHORTCUT,    FRAME", logger=None) as t3:
        logger.info(attention(t3.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=False,
                            use_frame=True,
                            max_files=1)
        ds4p_3 = selector.data
    with timing("   SHORTCUT,    FRAME", logger=None) as t4:
        logger.info(attention(t4.name))
        selector = SelectorWithVars(**config)
        chain.parallel_fill(selector,
                            shortcut=True,
                            use_frame=True,
                            max_files=1)
        ds4p_4 = selector.data

    table = [('Configuration', 'CPU')]

    table.append((t1.name, '%.3fs' % t1.delta))
    table.append((t2.name, '%.3fs' % t2.delta))
    table.append((t3.name, '%.3fs' % t3.delta))
    table.append((t4.name, '%.3fs' % t4.delta))

    title4p = "Non-trivial variables + CUT (parallel)"
    table4p = T.table(table, title=title4p, prefix='# ', alignment='rr')
    logger.info('%s\n%s' % (title4p, table4p))

    if ds4_1 != ds4p_1:
        logger.error('Datasets ds4_1  and ds4p_1  are different!')
    if ds4_2 != ds4p_2:
        logger.error('Datasets ds4_2  and ds4p_2  are different!')
    if ds4_3 != ds4p_3:
        logger.error('Datasets ds4_3  and ds4p_3  are different!')
    if ds4_4 != ds4p_4:
        logger.error('Datasets ds4_4  and ds4p_4  are different!')

    logger.info('%s\n%s' % (title1, table1))
    logger.info('%s\n%s' % (title1p, table1p))

    logger.info('%s\n%s' % (title2, table2))
    logger.info('%s\n%s' % (title2p, table2p))

    logger.info('%s\n%s' % (title3, table3))
    logger.info('%s\n%s' % (title3p, table3p))

    logger.info('%s\n%s' % (title4, table4))
    logger.info('%s\n%s' % (title4p, table4p))