From 9c10d41625056d7b6ed5af23e635a3e6a3d08812 Mon Sep 17 00:00:00 2001 From: Roel Aaij Date: Wed, 18 May 2016 17:25:58 +0200 Subject: [PATCH 1/4] Update HLT intro lesson. --- 18-hlt-intro.md | 61 +++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/18-hlt-intro.md b/18-hlt-intro.md index fbcd931..a950005 100644 --- a/18-hlt-intro.md +++ b/18-hlt-intro.md @@ -32,15 +32,24 @@ lines are saved to the raw event in a stripped-down form. One of the things that is saved are all the LHCbIDs of the final state particles of a decay tree. LHCbIDs are unique identifiers for detector hits. -We will now have a look at the LHCbIDs of some of the stored candidates. We will -use the script we [created earlier](http://lhcb.github.io/first-analysis-steps/05-interactive-dst.html) as a starting -point, and the file you [downloaded before](http://lhcb.github.io/first-analysis-steps/05-files-from-grid.html). Fire up -your favourite editor, open the script and save a copy to work on as -`tistos.py`. There are a few things in the script that we don't need and can be -removed, such as the print_decay and decay finder tools. +A new feature in Run II is the so-called Turbo stream. Since the reconstruction +available in HLT2 is the same as the offline reconstruction, physics analysis +can be done with the candidates created in HLT2. If a line is configured to be a +Turbo line, all information on the candidates that it selects is stored in the +raw event. These candidates can be resurrected later by the Tesla application and +written to a microDST. + +We will now have a look at some of the candidates stored by the HLT. We will use the script we +[used last time](http://lhcb.github.io/first-analysis-steps/05-interactive-dst.html) +as a starting point, and the file +`root://eoslhcb.cern.ch//eos/lhcb/user/r/raaij/Impactkit/00051318_00000509_1.turbo.mdst`. +This file contains some 2016 Turbo events from run 174252. Fire up your +favourite editor, open the script and save a copy to work on as +`hlt_info.py`. There are a few things in the script that we don't need and can +be removed, such as the print_decay and decay finder tools. Like the stripping, the decisions of the HLT are saved in so-called -DecReports. You can find them in `Hlt/DecReports` and `Hlt2/DecReports`, have a +DecReports. You can find them in `Hlt1/DecReports` and `Hlt2/DecReports`, have a look at what they contain. ~~~ {.python} @@ -60,28 +69,29 @@ report = reports.decReport('Hlt1TrackAllL0Decision') print report.decision() ~~~ -The HLT1 selection that was most efficient for hadronic charm and beauty decays -in Run-I was called Hlt1TrackAllL0. Use the advance function to find an event -that was accepted by that trigger selection. +The HLT1 selections that are most efficient for hadronic charm and beauty decays +in Run-II are called Hlt1TrackMVA and Hlt1TwoTrackMVA. Use the advance function +to find an event that was accepted by either of these trigger selections. The DecReports only contain the decisions, the candidates are stored in the SelReports ("Hlt{1,2}/SelReports"). Get the Hlt1 SelReports from the event store -and retrieve the one for Hlt1TrackAllL0 using the selReport function, +and retrieve the one for one of the TrackMVA selections using the selReport function, analogously to how the DecReport was retrieved above. The SelReports store candidates in a tree of sub-structures, which can be accessed using the substructure member funtion of a report. Any SelReport has at least one level of sub-structure. The sub-structure is internally stored in SmartRefs, which can be derefereced using their "data" method. Let's have a look -at a SelReport for Hlt1TrackAllL0. +at a SelReport for an TrackMVA selection. ~~~ {.python} reports = evt['Hlt1/SelReports'] -report = reports.selReport('Hlt1TrackAllL0Decision') +report = reports.selReport('Hlt1TrackMVADecision') print report report.substructure().size() -report.substructure().substructure()[0] -report.substructure().substructure()[0].data() +report.substructure()[0].substructure().size() +report.substructure()[0].substructure()[0] +report.substructure()[0].substructure()[0].data() ~~~ In addition to the LHCbIDs, some numbers are also stored, such as the momentum @@ -89,25 +99,26 @@ of the track. These are stored in the numerical info dictionary that can be retrieved using: ~~~ {.python} -report.substructure().substructure()[0].numericalInfo() +report.substructure()[0].substructure()[0].numericalInfo() ~~~ > ## Plot the transverse momentum distribution {.challenge} > > Make a plot of the total and transverse moment distributions of all candidates -> accepted by the Hlt1TrackAllL0 selection. +> accepted by the Hlt1TrackMVA selection. Then add Hlt1TwoTrackMVA and +> consider the difference. The LHCbIDs of the (in this case) track can be retrieved using: ~~~ {.python} -report.substructure().substructure()[0].lhcbIDs() +report.substructure()[0].substructure()[0].lhcbIDs() ~~~ -> ## Subdetector LHCb IDs. {.challenge} +> ## Turbo candidates {.challenge} > -> The LHCbIDs can tell you which sub-detector they belong too. Have a -> look at the doxygen to see what methods you can use (hint: find "LHCbID (LHCb) -> in the -> [class index](http://lhcb-release-area.web.cern.ch/LHCb-release-area/DOC/davinci/latest_doxygen/classes.html)). -> And get an idea of how many sub-detector hits are on the tracks. Does this match -> what you would expect? +> Now let's have a look at the same information that is stored for a candidate +> created by a Turbo line, for example Hlt2CharmHadDsp2KS0PimPipPip_KS0LLTurbo. +> Adapt the `advance_hlt` with an additional argument that allows specification +> of the location of `DecReports` it uses, then advance to an event that was selected by +> Hlt2CharmHadDsp2KS0PimPipPip_KS0LLTurbo, retrieve its `SelReport` and have a +> look at what's stored. From a1fc471ffed95b62a1e1475769aa862961417799 Mon Sep 17 00:00:00 2001 From: Roel Aaij Date: Thu, 19 May 2016 12:49:31 +0200 Subject: [PATCH 2/4] WIP first version of turbo and persist-reco lessons. --- 19-turbo.md | 60 +++++++++++++++++++++++++++++++ 20-persist-reco.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++ index.md | 22 ++++++------ 3 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 19-turbo.md create mode 100644 20-persist-reco.md diff --git a/19-turbo.md b/19-turbo.md new file mode 100644 index 0000000..edacf4d --- /dev/null +++ b/19-turbo.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Second steps in LHCb +subtitle: Turbo Stream +minutes: 30 +--- + +> ## Learning Objectives {.objectives} +> +> * Learn about persited reconstruction +> * Learn how to make new candidates from turbo candidate and other persisted objects +> * Learn how to make an NTuple from these new candidates. + +Online-offline reco the same +Online reconstructed candidates stored in raw event +Tesla pulls them out puts them back in the memory + +The file used in the [lesson about the HLT ](05-hlt-intro.html) can also be +used for this lesson: `root://eoslhcb.cern.ch//eos/lhcb/user/r/raaij/Impactkit/00051318_00000509_1.turbo.mdst`. + +Python file that defines the data: +~~~ {.python} +# data.py +from GaudiConf import IOHelper +prefix = 'root://eoslhcb.cern.ch/' +fname = '/eos/lhcb/user/r/raaij/Impactkit/00051318_00000509_1.turbo.mdst' +IOHelper('ROOT').inputFiles([prefix + fname], clear=True) +~~~ + +Basic script for making a turbo NTuple `turbo_intro.py` +~~~ {.python} +# DaVinci configuration +from Configurables import DaVinci +DaVinci().DataType = '2016' +DaVinci().EvtMax = 1000 +DaVinci().TupleFile = turbo.root' + +# Turbo locations: +turbo_loc = '/Event/Turbo/{0}/Particles' +dz_line = 'Hlt2CharmHadD02KmPipTurbo' + +# Make a DecayTreeTuple +from Configurables import DecayTreeTuple +from DecayTreeTuple import Configuration + +dtt = DecayTreeTuple('TupleD0ToKpi') +dtt.Inputs = [turbo_loc.format(dz_line)] +dtt.Decay = '[D0 -> K- pi+]CC' +dtt.addBranches({ + 'D0': '[D0 -> K- pi+]CC' +}) + +DaVinci().UserAlgorithms = [dtt] +~~~ + +Then we run it! + +```shell +lb-run DaVinci gaudirun.py turbo_persistreco.py data.py +``` diff --git a/20-persist-reco.md b/20-persist-reco.md new file mode 100644 index 0000000..b99ba02 --- /dev/null +++ b/20-persist-reco.md @@ -0,0 +1,89 @@ +--- +layout: page +title: Second steps in LHCb +subtitle: Persisted Reconstruction +minutes: 45 +--- + +> ## Learning Objectives {.objectives} +> +> * Learn about persited reconstruction +> * Learn how to make new candidates from turbo candidate and other persisted objects +> * Learn how to make an NTuple from these new candidates. + +Now we want to use the PersistReco to make something more from the candidates, +in this case a D* -> (D0 -> K pi) pi. + +Create a new script, `turbo_persistreco.py`, based on `turbo_intro.py` from the +previous lesson to contain your configuration. + +There are some general options needed to configure DaVinci to recreate the +particles created in the HLT. +~~~ {.python} +# Turbo with PersistReco +from Configurables import DstConf, TurboConf +DstConf().Turbo = True +TurboConf().PersistReco = True +~~~ + +Then we need to get the particles that we want to create the D* from and combine +them. + +> ## Persisted Particles {.challenge} +> +> Use a GaudiPython script to find out which particles are persisted from the +> online reconstruction. + +~~~ {.python} +# Get the D0 and the pions +from PhysSelPython.Wrappers import DataOnDemand, Selection, SelectionSequence +dz = DataOnDemand(turbo_loc.format(dz_line)) +pions = DataOnDemand('Phys/StdAllNoPIDsPions/Particles') + +# Combine them +from GaudiConfUtils.ConfigurableGenerators import CombineParticles +dst = CombineParticles( + DecayDescriptors = ['[D*(2010)+ -> D0 pi+]cc'], + CombinationCut = "(ADAMASS('D*(2010)+') < 80 * MeV)", + MotherCut = "VFASPF(VCHI2/VDOF) < 6 & ADMASS('D*(2010)+') < 60 * MeV" + ) +~~~ + +To run our combination, we create a selection and a selection sequence. +~~~ {.python} +dst_sel = Selection( + 'Sel_DstToD0pi', + Algorithm = dst, + RequiredSelections = [dz, pions] + ) + +dst_selseq = SelectionSequence( + 'SelSeq_DstToD0pi', + TopSelection = dst_sel + ) +~~~ + +Finally, we create the `DecayTreeTuple` for the D* and use the output of our selection +sequence as its input. + +~~~ {.python} +# D* in the tuple +dtt_dst = DecayTreeTuple('TupleDstToD0pi_D0ToKpi_PersistReco') +dtt_dst.Inputs = dst_selseq.outputLocations() +dtt_dst.Decay = '[D*(2010)+ -> ^(D0 -> ^K- ^pi+) ^pi+]CC' +dtt_dst.addBranches({ + 'Dst': '[D*(2010)+ -> (D0 -> K- pi+) pi+]CC', + 'Dst_pi': '[D*(2010)+ -> (D0 -> K- pi+) ^pi+]CC', + 'D0': '[D*(2010)+ -> ^(D0 -> K- pi+) pi+]CC', + 'D0_K': '[D*(2010)+ -> (D0 -> ^K- pi+) pi+]CC', + 'D0_pi': '[D*(2010)+ -> (D0 -> K- ^pi+) pi+]CC', +}) + +DaVinci().UserAlgorithms = [dst_selseq.sequence(), dtt_dst] +~~~ + +Then we run it! + +```shell +lb-run DaVinci gaudirun.py turbo_persistreco.py data.py +``` diff --git a/index.md b/index.md index 8862a8a..802fae9 100644 --- a/index.md +++ b/index.md @@ -3,26 +3,26 @@ layout: lesson title: Second analysis steps in LHCb --- -These are the lessons for the second-stage workshop of the [Starterkit +These are the lessons for the second-stage workshop of the [Starterkit series][starterkit]. -They build on those from [the first workshop][first-ana], teaching LHCb +They build on those from [the first workshop][first-ana], teaching LHCb software that's more advanced and more focused on specific tasks. -Unlike the first workshop, there may be some lessons here that aren't -applicable to everyone's analysis, but all the lessons should still provide a +Unlike the first workshop, there may be some lessons here that aren't +applicable to everyone's analysis, but all the lessons should still provide a useful insight in to how things work under the hood. -It may also be that some lessons don't depend on any others; the prerequisites +It may also be that some lessons don't depend on any others; the prerequisites will be clearly stated at the beginning of each lesson. -If you have any problems or questions, you can [open an -issue][second-ana-issues] on the [GitHub repository where these lessons are -developed][second-ana-repo], or you can [send an email to +If you have any problems or questions, you can [open an +issue][second-ana-issues] on the [GitHub repository where these lessons are +developed][second-ana-repo], or you can [send an email to `lhcb-starterkit@cern.ch`](mailto:lhcb-starterkit@cern.ch). > ## Prerequisites {.prereq} > -> Before starting, you should be familiar with the [first analysis -> steps](https://lhcb.github.io/first-analysis-steps/) and satisfy all of its +> Before starting, you should be familiar with the [first analysis +> steps](https://lhcb.github.io/first-analysis-steps/) and satisfy all of its > prerequisites. > @@ -36,6 +36,8 @@ developed][second-ana-repo], or you can [send an email to 1. [Reuse particles from a decay tree](18-filter-in-trees.html) 1. [HLT intro](18-hlt-intro.html) 1. [TisTos DIY](18-tistos-diy.html) +1. [Turbo](19-turbo.html) +1. [Turbo+PersistReco](20-persist-reco.html) ## Other Resources From c2e0f0422ff1a02cdc8ad7195aaa4aab48a32d61 Mon Sep 17 00:00:00 2001 From: Roel Aaij Date: Thu, 19 May 2016 14:26:47 +0200 Subject: [PATCH 3/4] Fix formatting for skeleton lessons. --- 19-turbo.md | 14 ++++++++------ 20-persist-reco.md | 10 +++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/19-turbo.md b/19-turbo.md index edacf4d..a08fa64 100644 --- a/19-turbo.md +++ b/19-turbo.md @@ -11,14 +11,15 @@ minutes: 30 > * Learn how to make new candidates from turbo candidate and other persisted objects > * Learn how to make an NTuple from these new candidates. -Online-offline reco the same -Online reconstructed candidates stored in raw event -Tesla pulls them out puts them back in the memory + * Online-offline reco the same + * Online reconstructed candidates stored in raw event + * Tesla pulls them out puts them back in the memory -The file used in the [lesson about the HLT ](05-hlt-intro.html) can also be -used for this lesson: `root://eoslhcb.cern.ch//eos/lhcb/user/r/raaij/Impactkit/00051318_00000509_1.turbo.mdst`. +| The file used in the [lesson about the HLT ](18-hlt-intro.html) can also be used for this lesson: +| `root://eoslhcb.cern.ch//eos/lhcb/user/r/raaij/Impactkit/00051318_00000509_1.turbo.mdst`. Python file that defines the data: + ~~~ {.python} # data.py from GaudiConf import IOHelper @@ -28,6 +29,7 @@ IOHelper('ROOT').inputFiles([prefix + fname], clear=True) ~~~ Basic script for making a turbo NTuple `turbo_intro.py` + ~~~ {.python} # DaVinci configuration from Configurables import DaVinci @@ -56,5 +58,5 @@ DaVinci().UserAlgorithms = [dtt] Then we run it! ```shell -lb-run DaVinci gaudirun.py turbo_persistreco.py data.py +lb-run DaVinci gaudirun.py turbo_intro.py data.py ``` diff --git a/20-persist-reco.md b/20-persist-reco.md index b99ba02..473f965 100644 --- a/20-persist-reco.md +++ b/20-persist-reco.md @@ -15,10 +15,11 @@ Now we want to use the PersistReco to make something more from the candidates, in this case a D* -> (D0 -> K pi) pi. Create a new script, `turbo_persistreco.py`, based on `turbo_intro.py` from the -previous lesson to contain your configuration. +[lesson about turbo ](19-turbo.html) to contain your configuration. There are some general options needed to configure DaVinci to recreate the particles created in the HLT. + ~~~ {.python} # Turbo with PersistReco from Configurables import DstConf, TurboConf @@ -31,8 +32,10 @@ them. > ## Persisted Particles {.challenge} > -> Use a GaudiPython script to find out which particles are persisted from the -> online reconstruction. +> Use a GaudiPython script inspired by +> [another lesson](http://lhcb.github.io/first-analysis-steps/05-interactive-dst.html) +> to find out which particles are persisted from the +> online reconstruction by exploring the transient event store. ~~~ {.python} # Get the D0 and the pions @@ -50,6 +53,7 @@ dst = CombineParticles( ~~~ To run our combination, we create a selection and a selection sequence. + ~~~ {.python} dst_sel = Selection( 'Sel_DstToD0pi', From a53daed2ccde4837695e77ce5ea5dc0056ed3596 Mon Sep 17 00:00:00 2001 From: Roel Aaij Date: Fri, 20 May 2016 18:10:34 +0200 Subject: [PATCH 4/4] Fix link titles. --- index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.md b/index.md index 669f03c..a2b802c 100644 --- a/index.md +++ b/index.md @@ -36,8 +36,8 @@ developed][second-ana-repo], or you can [send an email to 1. [Reuse particles from a decay tree](18-filter-in-trees.html) 1. [HLT intro](18-hlt-intro.html) 1. [TisTos DIY](18-tistos-diy.html) -1. [Turbo](19-turbo.html) -1. [Turbo+PersistReco](20-persist-reco.html) +1. [Turbo Stream](19-turbo.html) +1. [Persisted Reconstruction](20-persist-reco.html) 1. [Managing files in Ganga](01-managing-files-with-ganga.html) 1. [Using Ganga with local projects](01-ganga-with-cmake.html)