TWiki> LHCb Web>LHCbStripping (revision 30)EditAttachPDF

LHCb Stripping page

What is run in production

See production page for full details on processing.

The table below provides an overview of the current processing. Users are strongly discouraged from using data that appears in the bookkeeping under Real Data + RecoX-StrippingY. This data is unmerged and will be deleted as soon as the merging is complete. For Reco04-Stripping07 please use data under Reco04-Stripping07 and for Reco05-Stripping09 the data under Reco05-Stripping09-Merged.

Production Runs Fills DaVinci version Description Prescales
Reco08-Stripping12 < < v26r3p1 Stripping for Winter 2010 reprocessing. Prescales appear in line definitions
Reco07-Stripping11   1436-   Stripping for October 2010 ($\sim18pb^{-1}$). Stream definition in Phys/StrippingSettings/Stripping11. First stripping to include $\mu$-DST$% producton for inclusive-$J/psi$ and high rate Charm lines. Prescales appear in the line definitions
Reco06-Stripping10 79571- 1364-1435 v26r1 Stripping for September 2010. Stream definition moved to Phys/StrippingSettings/Sept2010 Prescales appear in line definitions
Reco05-Stripping09 <77226 <1268 v25r7 Stripping of the first $1pb^{-1}$, Bhadron and Charm streams merged into a single Hadronic stream. See here
Reco05-Stripping-09-Prescaled 77266-77623 1268-1287 v25r7 Same reconstruction pass and DaVinci version as Reco05-Stripping09, but with additional pre-scaled lines in Charm and Bhadron stream. Bhadron and Charm streams are not merged. See here
Reco05-Stripping08 <77196 <1264 v25r5p2 Stripping version used for ICHEP processing. Pre-scales as appearing in line configuration except MicroBias which is pre-scaled by 0.01 See here

Stripping Statistics

See StrippingStatistics page

How to add a line

So far we have always included the head of the stripping selections in DaVinci. We cannot continue like that. Since the beginning of the year I have asked everyone to present their stripping selection at T&S meeting. One such talk is scheduled today. Now that we'll soon start stripping real data we also need to discuss any change to what we've been using. By default, what goes in the head of cvs will not be used in the stripping. Only what's blessed by the PPG and OPG will be used.

Practically, if you want to add a line, or change a line, you must

  1. Get the change approved by your WG.
  2. Present it at T&S. Show what is does to rates and CPU, and explain the reason. This will become critical once we have sizeable rates flowing out of the detector. Then, make sure you run the stripping with and without your line on the available data (rDST) and present the results.
  3. If agreed by the T&S meeting, the proposed change (practically, a bunch of changes) will make it to a production release. The green light has to be given by OPG and PPG to use this release in production.

Removed Stripping Selections

See StrippingSelectionsRemoved page for a list of the lines that were removed in July 2010.

Stripping Selections

See StrippingSelections page.

Stripping Workflow

See StrippingWorkFlow page.

Stripping Framework

See StrippingLines page.

Stripping DST

The stripping DST contains the full DST, plus a MicroDST partition containing the full decay tree of the stripping line selected candidates. It also contains the necessary particle to primary vertex (PV) relations in order to guarantee that the same PV is used to apply further cuts and estimate PV-dependent quantities. If PV re-fitting has been used in the selection, the re-fitted PVs are also saved. The relations point to these.


Writing of DSTs is performed using the DSTWriter pattern. It uses the Stripping Framework behind the scened, and the StrippingConf configurable to provide a list of StrippingStreams. These are passed onto a DSTWriter, which prepares a self-contained GaudiSequencer that can then be passed to DaVinci(). There is one DST per stream, and it contains all the candidates of all the lines composing that stream. By convention, the candidates are placed in a partition '/Event/' where is the name of your stream (was Strip in RecoStripping-03). It is possible to configure StrippingConf to run only one stream. It is also possible to use a sub-set of lines for each particular stream. This is achieved through the ActiveStreams and ActiveLines fields of StrippingConf respectively.
from Configurables import SelDSTWriter, DaVinci
from StrippingConf.Configuration import StrippingConf

# import some official Stripping Selections
from StrippingSelections import StreamBmuon, StreamHadron, StreamJpsi, StreamDstar

sc = StrippingConf(Streams = [,
        ] )

dstWriter = SelDSTWriter("StripMC09DSTWriter",
                         SelectionSequences = sc.activeStreams(),
                         OutputFileSuffix = 'Test'
dv = DaVinci()
dv.DataType = "2010"
dv.UserAlgorithms = [ dstWriter.sequence() ]

This example will only run the 'JpsiInclusive' line of the 'Jpsi' stream. The result will be Test.Jpsi.dst. For more details, see the relevant Stripping Framework section


Since the stripping DST contains a full DST as well as the candidate's full decay tree, it is very easy to run an analysis on top of it. All that is required is that the full TES location of the particles is specified to the relevant algorithms. However, since the stripping lines within a stream are run in OR mode, it is unavoidable that there will be events with no candidates in the desired location, or with no desired location at all. In most cases, this will apply to most events, meaning that you only care about a small percentage of the events in a stripped DST. Fortunately, it is possible to filter on the stripping decision report and limit your analysis to the events that passed the line or lines you require. This is the only robust way of performing an analysis on stripped DSTs. It is very easy to produce a filter that selects events that passed a given line:

# Create a filter for events that passed the DY2MuMu2 stripping line
from Configurables import LoKi__HDRFilter   as StripFilter
filter = StripFilter( 'StripPassFilter', Code="HLT_PASS('StrippingDY2MuMu2Decision')", Location="/Event/Strip/Phys/DecReports" )

This filter can be places at the beginning of your analysis GaudiSequencer, or passed to DaVinci().EventPreFilters, if you want to completely skip events that did not pass the stripping line. This can save a large amount of time if your line has a small retention compared to the global retention rate of the stream. In any case, for robust analysis you have to use this filter, whether it is placed in front of your sequence or in the DaVinci().EventPreFilters:

# put the filter in front of your analysis algorithm or sequence
# myAlg can be a simple algorithm or a GaudiSequencer containing all the algorithms that your analysis needs
myAlg = ...
mySeq = GaudiSequencer('MyAnalysisSequencer', Members = [filter, myAlg])
DaVinci().UserAlgorithms += [mySeq]

a similar effect can be achieved using the selection toolkit, in the case where myAlg is a DVAlgorithm,

mySelSeq = SelectionSequence('MySelSeq', EventPreSelector = [filter], TopSelection = Selection('MySel', Algorithm = myAlg, RequiredSelections = [...])
DaVinci().UserAlgorithms += [mySelSeq.sequence()]

For maximum processing efficiency, add the filter to DaVinci().

# job will only run over events passing the line.
DaVinci().EventPreFilters += [filter]

Note in the example above we only care about one line. If we care about more lines, of want more sophisticated filtering, we can use the handy module PhysConf.Filters by Vanya:

# what is is about ? Get the help printed out to the terminal python $PHYSCONFROOT/python/PhysConf/

This is an example of a more sophisticated filter, using both stripping and HLT decision report information, and asking that the event contain less than three primary vertices, using some regexp:

from PhysConf.Filters import LoKi_Filters
fltrs = LoKi_Filters (
# OR of two HLT decisions
HLT_Code = " HLT_PASS_RE ('Hlt1MBMicro.*Decision') | HLT_PASS_RE ('Hlt1.*Hadron.*Decision') " ,
## OR of two stripping lines
STRIP_Code = 
" HLT_PASS ( 'StrippingDs2piPhiLineDecision' ) |
HLT_PASS_RE ('StrippingStripD2K(KP|PP)_A_LoosePID_(Sig|Bkg).*Decision')
" ,
## select one or 2 vertices
VOID_Code = 
" CONTAINS ('/Event/Rec/Vertex/Primary') < 3"
from Configurables import DaVinci
DaVinci ( DataType = '2010' , EventPreFilters = fltrs.filters ('Filters'), ...)

Run a selection on top of the stripping candidates

In the example below, we run J/Psi filter on top of the candidates saved to a DST written using only the 'JpsiInclusive' line of the the 'Jpsi' stream. For this, we use elements from the Particle Selection Framework to build SelectionSequence.
# get classes to build the SelectionSequence
from PhysSelPython.Wrappers import AutomaticData, Selection, SelectionSequence
# Get the J/Psi candidates from the DST.
# Treat particles already on the DST as data-on-demand, but give the full path.
JpsiSel = AutomaticData(Location = "/Event/Dimuon/Phys/StrippingJpsiInclusiveCombine")
# Filter the J/Psi. Replace 'ALL' by some cuts.
from Configurables import FilterDesktop
_jpsiFilter = FilterDesktop('jpsiFilter', Code = 'ALL')

# make a Selection
JpsiFilterSel = Selection(name = 'JpsiFilterSel',
                          Algorithm = _jpsiFilter,
                          RequiredSelections = [JpsiSel] )

# build the SelectionSequence
JpsiSeq = SelectionSequence('SeqJpsi',
                            TopSelection = JpsiFilterSel)

# Configure DaVinci
dv.HistogramFile = "DVHistos_Strip.root"
dv.UserAlgorithms = [JpsiSeq.sequence()] # pass the GaudiSequencer to DaVinci()
dv.Input   = ["DATAFILE='PFN:/castor/'  TYP='POOL_ROOTTREE' OPT='READ'" ]
We can add some histograms, as shown in DaVinci Tutorial 4:
from Configurables import LoKi__Hybrid__PlotTool as PlotTool

_jpsiFilter.HistoProduce = True
_jpsiFilter.addTool( PlotTool("InputPlots") )
_jpsiFilter.InputPlots.Histos = { "P/1000"  : ('momentum',0,150) ,
                                  "PT/1000" : ('pt_%1%',0,5,750) ,
                                  "M"       : ('mass in MeV_%1%_%2%_%3%',2.8*Uni
ts.GeV,3.2*Units.GeV) }
_jpsiFilter.addTool( PlotTool("OutputPlots") )
_jpsiFilter.OutputPlots.Histos = { "P/1000"  : ('momentum',0,150) ,
                                   "PT/1000" : ('pt_%1%',0,5,750) ,
                                   "M"       : ('mass in MeV_%1%_%2%_%3%',2.8*Un
its.GeV,3.2*Units.GeV) }

The selection part of the example could've been put in a python module to make a selection, as explained in the Particle Selection framework and DaVinci Tutorial 4 pages. This example will be available as DaVinci/options/ from DaVinci v24r4 onwards.

Make a DecayTreeTuple using the stripping candidates

from Gaudi.Configuration import *
from Configurables import  DaVinci, DecayTreeTuple, TupleToolTrigger

from Configurables import HltDecReportsDecoder, HltSelReportsDecoder, HltVertexReportsDecoder
DataOnDemandSvc().AlgMap["Hlt/DecReports"] = HltDecReportsDecoder(OutputLevel = 4)
DataOnDemandSvc().AlgMap["Hlt/SelReports"] = HltSelReportsDecoder(OutputLevel = 4)
DataOnDemandSvc().AlgMap["Hlt/VertexReports"] = HltVertexReportsDecoder( OutputLevel = 4)

tuple = DecayTreeTuple('MyTuple')
tuple.InputLocations = [ "/Event/Semileptonic/Phys/Bd2DstarMu" ]
tuple.ToolList +=  [  "TupleToolGeometry"
                    , "TupleToolKinematic"
                    , "TupleToolPrimaries"
                    , "TupleToolEventInfo"
                    , "TupleToolTrackInfo"
                    , "TupleToolPid"
                    , "TupleToolTrigger"
tuple.Decay = "[B~0 -> (^D*(2010)+ -> (^D0 -> ^K- ^pi+) ^pi+) ^mu-]cc"
tuple.Branches = {
     "muon"  : "[B~0]cc  -> [(D*(2010)+ -> (D0 -> K- pi+) pi+) ^mu-]cc" 
    ,"Dstar" : "[B~0]cc  -> [(^D*(2010)+ -> (D0 -> K- pi+)  pi+) mu-]cc" 
    ,"slpi"  : "[B~0]cc  -> [(D*(2010)+  -> (D0 -> K- pi+) ^pi+) mu-]cc" 
    ,"D0"    : "[B~0]cc  -> [(D*(2010)+  -> (^D0 -> K- pi+) pi+) mu-]cc" 
    ,"pion"  : "[B~0]cc  -> [(D*(2010)+  -> (D0 -> K- ^pi+) pi+) mu-]cc" 
    ,"kaon"  : "[B~0]cc  -> [(D*(2010)+  -> (D0 -> ^K- pi+) pi+) mu-]cc" 
    ,"Bd"    : "[B~0]cc : [B~0 -> (D*(2010)+ -> (D0 -> K- pi+) pi+)  mu-]cc" 

tuple.TupleToolTrigger.VerboseL0 = True
tuple.TupleToolTrigger.VerboseHlt1 = True
tuple.TupleToolTrigger.VerboseHlt2 = True
tuple.TupleToolTrigger.UseAutomaticTriggerList = True

# DaVinci settings
from Configurables import DaVinci
DaVinci().EvtMax = -1
DaVinci().PrintFreq = 100
DaVinci().DataType = "MC09"
DaVinci().UserAlgorithms = [ tuple ]
DaVinci().TupleFile = "StripTuple.root"
DaVinci().Input   = [ .... ]

Finding TES locations of stripping candidates

In the examples above, one has to know the location of the candidate particles in the DST. It is possible to query StrippingConf to get the locations for a given configuration. In standard python (UE, updated for Stripping12),

from StrippingSettings.Stripping12 import streams
_streams = streams()

for stream in _streams:
    print, "\t", stream.outputLocations()
    for line in stream.lines :
        print, "\t", line.outputLocation()

If we follow the convention that candidates are written to '/Event/' then we can see how to get the location for each line's candidates.

Finding the location of the candidates on a stripping DST

From RecoStripping04 onwards, the candidates are stores in "/Event//", where the TES location is obtained as above. One can obtain the locations for a given stream (or all streams) with some simple lines of python. Here, we make a dictionary mapping the names of the stripping line of the Leptonic stream to the DST locations of the candidates. Make sure you do that with the version of DaVinci used in the stripping.
streamname = 'Leptonic'

from StrippingSettings.Stripping12 import streams
_streams = streams()
_streamnames=[ for s in _streams]

# we will build a line name to location map
locations = {}
for line in _streams[_streamnames.index(streamname)].lines:
   locations[] = '/Event/' + streamname + '/' + line.outputLocation()
Then we can find the location if we know the line's name:
myLine = 'StrippingMicroDSTDiMuonIncLine'
print myLine, 'DST location:', locations[myLine]
or just look at everything in there:
for lineName, location in locations.iteritems() :
 print 'Line:', lineName, 'DST location:', location

And if there are no candidates?

This is the case of the Minimum Bias lines for instance. For all lines you can do
from Configurables import LoKi__HDRFilter   as StripFilter
MySequencer = GaudiSequencer('Sequence')
MySequencer.Members += [ StripFilter( 'StripPassFilter', Code="HLT_PASS('StrippingBd2KstGammaDecision')", Location="/Event/Strip/Phys/DecReports" ) ]
Note the location, that is different from the default HLT location. This StripFilter would restrict the sequence only to events that have passed the K*Gamma selection.

MicroDST framework

Here is a complete example of reading a production micro DST and saving candidates in the DecayTreeTuple
stream = 'Leptonic'
line = 'MicroDSTDiMuonIncLine'
inputType = 'MDST'

from Gaudi.Configuration import *
from Configurables import DaVinci

if inputType == 'MDST':

    # Make reading of trigger possible on MDST
    from Configurables import DataOnDemandSvc
    from Configurables import HltDecReportsDecoder, HltSelReportsDecoder
    decDecoder = HltDecReportsDecoder(InputRawEventLocation="/Event/"+stream+"/DAQ/RawEvent",
                                      OutputHltDecReportsLocation ="/Event/"+stream+"/Hlt/DecReports" )
    selDecoder = HltSelReportsDecoder(InputRawEventLocation="/Event/"+stream+"/DAQ/RawEvent",
                                      OutputHltSelReportsLocation ="/Event/"+stream+"/Hlt/SelReports" ,
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/Hlt/SelReports"] = selDecoder
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/Hlt/DecReports"] = decDecoder

    from Configurables import L0DecReportsMaker, L0SelReportsMaker
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/HltLikeL0/DecReports"]=L0DecReportsMaker(RootInTES = "/Event/"+stream+"/")
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/HltLikeL0/SelReports"]=L0SelReportsMaker(RootInTES = "/Event/"+stream+"/")
    from Configurables import L0Conf
    L0Conf().FullL0MuonDecoding = True
    L0Conf().EnableL0DecodingOnDemand = True
    from Configurables import L0MuonCandidatesFromRaw, L0CaloCandidatesFromRaw, L0DUFromRawAlg
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/Trig/L0/MuonBCSU"] = L0MuonCandidatesFromRaw("L0MuonFromRaw",RootInTES = "/Event/"+stream+"/")
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/Trig/L0/FullCalo"]= L0CaloCandidatesFromRaw("L0CaloFromRaw", RootInTES = "/Event/"+stream+"/")
    DataOnDemandSvc().AlgMap["/Event/"+stream+"/Trig/L0/L0DUReport"]= L0DUFromRawAlg("L0DUFromRaw", RootInTES = "/Event/"+stream+"/" )

    from Configurables import ANNDispatchSvc
    ANNDispatchSvc().RawEventLocation = "/Event/" + stream + "/DAQ/RawEvent"
    ApplicationMgr().ExtSvc +=  [ DataOnDemandSvc(),ANNDispatchSvc() ] 

# Setup DecayTreeTuple
from Configurables import DecayTreeTuple
tuple = DecayTreeTuple()
if inputType == 'MDST':
    tuple.RootInTES = "/Event/"+stream+"/"

tuple.InputLocations = [line]
tuple.ToolList +=  [
              , "TupleToolKinematic"
              , "TupleToolPropertime"
              , "TupleToolPrimaries"
              , "TupleToolPid"
              , "TupleToolEventInfo"
              , "TupleToolTrackInfo"
              , "TupleToolTrigger"
tuple.Decay = "[J/psi(1S) => ^mu+ ^mu-]cc"
tuple.Branches = {
    "MuPlus" : "J/psi(1S) -> ^mu+ mu-",
    "MuMinus" : "J/psi(1S) -> mu+ ^mu-",
    "Jpsi" : "J/psi(1S) : J/psi(1S) -> mu+ mu-"

from Configurables import TupleToolTISTOS, TupleToolDecay
tuple.addTool( TupleToolDecay, name = "Jpsi" )
tuple.Jpsi.ToolList += [ "TupleToolTISTOS" ]
tuple.Jpsi.addTool( TupleToolTISTOS, name = "TupleToolTISTOS" )
tuple.Jpsi.TupleToolTISTOS.VerboseL0 = True
tuple.Jpsi.TupleToolTISTOS.TriggerList = [

if inputType == 'MDST':
    from Configurables import L0TriggerTisTos, TriggerTisTos
    tuple.Jpsi.TupleToolTISTOS.addTool( L0TriggerTisTos() )
    tuple.Jpsi.TupleToolTISTOS.addTool( TriggerTisTos() )
    tuple.Jpsi.TupleToolTISTOS.L0TriggerTisTos.UseParticle2LHCbIDsMap = 2
    tuple.Jpsi.TupleToolTISTOS.TriggerTisTos.UseParticle2LHCbIDsMap = 2

DaVinci().UserAlgorithms += [ tuple ]

DaVinci().EvtMax = -1
DaVinci().DataType = "2010"
DaVinci().InputType = inputType
DaVinci().Simulation   = False
DaVinci().TupleFile = "DVNtuples.root"

Particle Selections Framework

Finding information in the bookkeeping

The situation is still not satisfactory. Some hooks are missing, but you can work your way through... Suppose you use the bookeeping GUI to look at the second stripping (MC09-Stripping01) that was run on the MB. You care about the JPSI.DST stream.

What version of which application was run on

You need the production ID. This is part of the LFN (a directory). In that case 5614. Now go to the Production monitor web page and search for production 5614. Click on a file and select "Show Details". This will give you the details of the whole production workflow. I read:
Merge Production 5614 for event type 30000000 has following parameters:

Production priority: 9
BK Config Name Version: MC MC09
BK Processing Pass Name: MC09-Stripping02
CondDB Tag: sim-20090402-vc-md100
DDDB Tag: MC09-20090602

====> DaVinci v24r4 Step0
  DaVinci Option Files:
  ExtraPackages: AppConfig.v3r20
====> Brunel v34r7 Step1
  Brunel Option Files:
  ExtraPackages: AppConfig.v2r9p1
====> DaVinci v24r4 Step2
  DaVinci Option Files:
  ExtraPackages: AppConfig.v3r20
====> LHCb v28r0 Step3
  LHCb Option Files:
BK Input Data Query:
    EventType = 30000000
    FileType = JPSI.DST
    ProductionID = 5600

BK Browsing Paths:

-- JuanPalacios - 09-Oct-2009 -- PatrickSKoppenburg - 20-Nov-2009 -- JuanPalacios - 25-Jun-2010 -- JuanPalacios - 13-Oct-2010 -- UlrikEgede - 12-Jan-2011

Edit | Attach | Watch | Print version | History: r118 | r32 < r31 < r30 < r29 | Backlinks | Raw View | Raw edit | More topic actions...
Topic revision: r30 - 2011-01-14 - UlrikEgede
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    LHCb All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback