Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tutorials to use IOSvc and functional algorithms #21

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions gaudi_alg_higgs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ intermediate collection with the muons.

First, we will need a key4hep setup, typically obtained by sourcing scripts from
cvmfs, see the instructions
[here](https://key4hep.github.io/key4hep-doc/setup-and-getting-started/README.html).
[here](https://key4hep.github.io/key4hep-doc/getting_started/setup.html).
After sourcing, check that the environment variable `KEY4HEP_STACK` is set to
make sure the stack has been loaded correctly:

Expand Down Expand Up @@ -87,8 +87,8 @@ instructions for what algorithms we want to run, what parameters we want to pass
them and other configuration like logging.

There are several options that can be changed in the steering file that may be important:
- The name of the input file is passed to the `PodioInput` plugin
- The name of the output file is passed to the `PodioOutput` plugin
- The name of the input file is passed to the `IOSvc` service
- The name of the output file is passed to the `IOSvc` service
- The number of events to process is passed to the `ApplicationMgr`. Choose `-1`
not to limit it (all the events in the input file will be processed) or any
other number to put a limit (sometimes useful for testing or debugging)
Expand Down
1 change: 0 additions & 1 deletion gaudi_alg_higgs/setup/higgs_recoil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ set(sources components/HiggsRecoil.cpp
gaudi_add_module(tutorial
SOURCES ${sources}
LINK Gaudi::GaudiKernel
Gaudi::GaudiAlgLib
k4FWCore::k4FWCore
EDM4HEP::edm4hep
EDM4HEP::utils
Expand Down
29 changes: 19 additions & 10 deletions gaudi_alg_higgs/setup/higgs_recoil/components/HiggsRecoil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,39 @@
*/

#include "Gaudi/Property.h"
#include "GaudiAlg/Transformer.h"
#include "Gaudi/Accumulators/Histogram.h"
#include "Gaudi/Histograming/Sink/Utils.h"

#include "edm4hep/ReconstructedParticleCollection.h"
#include "edm4hep/utils/kinematics.h"

// Define BaseClass_t
#include "k4FWCore/BaseClass.h"
#include "k4FWCore/Transformer.h"

#include "TH1D.h"

#include <string>

// histogram compatibility when older version of Gaudi is used
#include "GAUDI_VERSION.h"
#if GAUDI_MAJOR_VERSION < 39
namespace Gaudi::Accumulators {
template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double>
using StaticHistogram =
Gaudi::Accumulators::HistogramingCounterBase<ND, Atomicity, Arithmetic, naming::histogramString,
HistogramingAccumulator>;
}
#endif

struct HiggsRecoil final
: Gaudi::Functional::MultiTransformer<std::tuple<edm4hep::ReconstructedParticleCollection,
: k4FWCore::MultiTransformer<std::tuple<edm4hep::ReconstructedParticleCollection,
edm4hep::ReconstructedParticleCollection>
(const edm4hep::ReconstructedParticleCollection&), BaseClass_t> {
(const edm4hep::ReconstructedParticleCollection&)> {
HiggsRecoil(const std::string& name, ISvcLocator* svcLoc)
: MultiTransformer(
name, svcLoc,
{KeyValue("InputMuons", "Muons")},
{KeyValue("HiggsCollection", "Higgs"),
KeyValue("ZCollection", "Z")}) {
{KeyValues("InputMuons", {"Muons"})},
{KeyValues("HiggsCollection", {"Higgs"}),
KeyValues("ZCollection", {"Z"})}) {
}

std::tuple<edm4hep::ReconstructedParticleCollection,
Expand Down Expand Up @@ -85,8 +94,8 @@ struct HiggsRecoil final
// Thread-safe custom histograms from Gaudi
// 1 is the dimension of the histogram
// Here "Higgs mass" is the title of the histogram, then we pass the bins and the axis labels
mutable Gaudi::Accumulators::Histogram<1> higgsHist{this, "", "Higgs mass", {100, 0., 250., "m_{H} [GeV];Entries"}};
mutable Gaudi::Accumulators::Histogram<1> zHist{this, "", "Z mass", {100, 0., 250., "m_{Z} [GeV];Entries"}};
mutable Gaudi::Accumulators::StaticHistogram<1> higgsHist{this, "", "Higgs mass", {100, 0., 250., "m_{H} [GeV];Entries"}};
mutable Gaudi::Accumulators::StaticHistogram<1> zHist{this, "", "Z mass", {100, 0., 250., "m_{Z} [GeV];Entries"}};

/* We are going to leave thread-safe histogramming commented out since
the version of Gaudi installed in the stack is not recent enough. Once a
Expand Down
10 changes: 4 additions & 6 deletions gaudi_alg_higgs/setup/higgs_recoil/components/MuonFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,21 @@
*/

#include "Gaudi/Property.h"
#include "GaudiAlg/Transformer.h"

#include "edm4hep/ReconstructedParticleCollection.h"
#include "edm4hep/utils/kinematics.h"

// Define BaseClass_t
#include "k4FWCore/BaseClass.h"
#include "k4FWCore/Transformer.h"

#include <string>

struct MuonFilter final
: Gaudi::Functional::Transformer<edm4hep::ReconstructedParticleCollection(const edm4hep::ReconstructedParticleCollection&), BaseClass_t> {
: public k4FWCore::Transformer<edm4hep::ReconstructedParticleCollection(const edm4hep::ReconstructedParticleCollection&)> {
MuonFilter(const std::string& name, ISvcLocator* svcLoc)
: Transformer(
name, svcLoc,
{KeyValue("InputPFOs", "PandoraPFOs")},
{KeyValue("OutputMuons", "Muons")}) {
{KeyValues("InputPFOs", {"PandoraPFOs"})},
{KeyValues("OutputMuons", {"Muons"})}) {
}

edm4hep::ReconstructedParticleCollection operator()(const edm4hep::ReconstructedParticleCollection& recoColl) const override {
Expand Down
33 changes: 14 additions & 19 deletions gaudi_alg_higgs/setup/higgs_recoil/options/runHiggsRecoil.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,43 @@

from Gaudi.Configuration import INFO
from Configurables import HiggsRecoil, MuonFilter
from Configurables import ApplicationMgr
from Configurables import k4DataSvc
from Configurables import PodioOutput
from Configurables import PodioInput
from k4FWCore import ApplicationMgr, IOSvc

data_svc = k4DataSvc("EventDataSvc")
data_svc.input = "/home/juanmi/Downloads/ZH_40_events_ILD_DST_merged.edm4hep.root"
io_svc = IOSvc()
io_svc.Input = "rv02-02.sv02-02.mILD_l5_o1_v02.E250-SetA.I402004.Pe2e2h.eR.pL.n000.d_dstm_15090_0.edm4hep.root"

inp = PodioInput()
inp.collections = [
io_svc.CollectionNames = [
"PandoraPFOs",
]

out = PodioOutput("out")
out.outputCommands = [
io_svc.outputCommands = [
"drop *",
"keep Muons",
"keep PandoraPFOs",
"keep Z",
"keep Higgs",
]
out.filename = "higgs_recoil_out.root"
io_svc.Output = "higgs_recoil_out.root"

# The collections that we don't drop will be present in the output file
# out.outputCommands = ["drop Collection1"]
# io_svc.outputCommands = ["drop Collection1"]

# If we don't specify the values for the name parameters
# they will take the default value defined in the C++ code
muon = MuonFilter("MuonFilter",
InputPFOs="PandoraPFOs",
OutputMuons="Muons",
InputPFOs=["PandoraPFOs"],
OutputMuons=["Muons"],
MinPt=10.0)

recoil = HiggsRecoil("HiggsRecoil",
InputMuons="Muons",
HiggsCollection="Higgs",
ZCollection="Z",
InputMuons=["Muons"],
HiggsCollection=["Higgs"],
ZCollection=["Z"],
)

ApplicationMgr(TopAlg=[inp, muon, recoil, out],
ApplicationMgr(TopAlg=[muon, recoil],
EvtSel="NONE",
EvtMax=-1,
ExtSvc=[data_svc],
ExtSvc=[],
OutputLevel=INFO,
)
37 changes: 14 additions & 23 deletions gaudi_ild_reco/.solution/MarlinStdReco.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import os
from Gaudi.Configuration import *

from Configurables import (
PodioInput,
PodioOutput,
k4DataSvc,
MarlinProcessorWrapper,
EDM4hep2LcioTool,
Lcio2EDM4hepTool,
)
from k4MarlinWrapper.parseConstants import *

from k4FWCore import IOSvc

algList = []
evtsvc = k4DataSvc("EventDataSvc")


CONSTANTS = {
Expand Down Expand Up @@ -134,9 +131,9 @@

parseConstants(CONSTANTS)

read = PodioInput()
read.OutputLevel = INFO
read.collections = [
io_svc = IOSvc()
io_svc.OutputLevel = INFO
io_svc.CollectionNames = [
"BeamCalCollection",
"BeamCalCollectionContributions",
"ECalBarrelScHitsEven",
Expand Down Expand Up @@ -187,8 +184,13 @@
"YokeEndcapsCollection",
"YokeEndcapsCollectionContributions",
]

algList.append(read)
io_svc.Output = "zh_mumu_reco.edm4hep.root"
io_svc.outputCommands = [
"drop *",
"keep MCParticlesSkimmed",
"keep PandoraPFOs",
"keep RecoMCTruthLink",
]

edm4hep2LcioConv = EDM4hep2LcioTool()
edm4hep2LcioConv.collNameMapping = {"MCParticles": "MCParticle"}
Expand Down Expand Up @@ -1783,16 +1785,6 @@
lcio2edm4hepConv.collNameMapping = {"MCParticle": "MCParticles"}
MyPfoAnalysis.Lcio2EDM4hepTool = lcio2edm4hepConv

edm4hepOutput = PodioOutput()
edm4hepOutput.OutputLevel = DEBUG
edm4hepOutput.filename = "zh_mumu_reco.edm4hep.root"
edm4hepOutput.outputCommands = [
"drop *",
"keep MCParticlesSkimmed",
"keep PandoraPFOs",
"keep RecoMCTruthLink",
]


algList.append(MyAIDAProcessor)
algList.append(InitDD4hep)
Expand Down Expand Up @@ -1863,10 +1855,9 @@
algList.append(MyLCIOOutputProcessor)
algList.append(DSTOutput)
algList.append(MyPfoAnalysis)
algList.append(edm4hepOutput)

from Configurables import ApplicationMgr
from k4FWCore import ApplicationMgr

ApplicationMgr(
TopAlg=algList, EvtSel="NONE", EvtMax=10, ExtSvc=[evtsvc], OutputLevel=INFO
TopAlg=algList, EvtSel="NONE", EvtMax=10, ExtSvc=[], OutputLevel=INFO
)
69 changes: 32 additions & 37 deletions gaudi_ild_reco/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,16 +228,9 @@ resp. The corresponding filename constants values in `CONSTANTS`.
### Adapting the options file for EDM4hep

It is necessary to adapt the Gaudi options file a bit further:
- Replace the `LcioEvent` algorithm with the `PodioInput` algorithm
- Make sure to replace the `Files` option with the `collections` option and to
populate this option with the list of collections you want to read (see
below)
- Replace the `EventDataSvc` with the `k4DataSvc` (remember to instantiate it
with `"EventDataSvc"` as name)
- Add a `PodioOutput` algorithm to write EDM4hep output (don't forget to add it
to the `algList` at the very end)
- (For the sake of this exercise) configure this to only write the
`MCParticlesSkimmed`, `PandoraPFOs` and the `RecoMCTruthLink` collections
- Remove the `LcioEvent` algorithm and create the `IOSvc` service
- Populate the `CollectionNames` property of `IOSvc` with the list of collections you want to read (see below).
- Use `Output` property of `IOSvc` to specify to which file write the EDM4hep output. (For the sake of this exercise) configure the `outputCommands` property to only write the `MCParticlesSkimmed`, `PandoraPFOs` and the `RecoMCTruthLink` collections.
- Attach the necessary in-memory on-the-fly converters between EDM4hep and LCIO
(and vice versa)
- For the conversion of the EDM4hep inputs to LCIO instantiate a
Expand All @@ -247,33 +240,42 @@ It is necessary to adapt the Gaudi options file a bit further:
`Lcio2EDM4hepTool` and attach it to the last wrapped processor that is run
before the `PodioOutput` algorithm that you just added (`MyPfoAnalysis`).
Also see below.
- Near the end of the file replace the `from Configurables import ApplicationMgr` with `from k4FWCore import ApplicationMgr`.

**For all of these steps make sure that you `import` all the necessary tools and
algorithms from `Configurables`!**
algorithms from `Configurables`! Both `IOSvc` and `ApplicationMgr` services should be imported from `k4FWCore`.**

The top of your file should now look something like this

```python
from Configurables import (
PodioInput, PodioOutput, k4DataSvc, MarlinProcessorWrapper,
MarlinProcessorWrapper,
EDM4hep2LcioTool, Lcio2EDM4hepTool
)
from k4MarlinWrapper.parseConstants import *
from k4FWCore import IOSvc

algList = []
evtsvc = k4DataSvc("EventDataSvc")

io_svc = IOSvc()
io_svc.OutputLevel = INFO
io_svc.CollectionNames = [
# ... list of collection names
]

io_svc.Output = "zh_mumu_reco.edm4hep.root"
io_svc.outputCommands = [
"drop *",
"keep MCParticlesSkimmed",
"keep PandoraPFOs",
"keep RecoMCTruthLink",
]
```

while the configuration for the input reader and the `EDM4hep2LcioTool` should
while the configuration for the `EDM4hep2LcioTool` should
look like this

```python
read = PodioInput()
read.OutputLevel = INFO
read.collections = [
# ... list of collection names
]
algList.append(read)

edm4hep2LcioConv = EDM4hep2LcioTool()
edm4hep2LcioConv.collNameMapping = {
"MCParticles": "MCParticle"
Expand All @@ -290,7 +292,7 @@ The list of collections that is populated by standard configuration of ILD for
simulation looks like this. You can simply copy this into the options file

```python
read.collections = [
io_svc.CollectionNames = [
"BeamCalCollection",
"BeamCalCollectionContributions",
"ECalBarrelScHitsEven",
Expand Down Expand Up @@ -345,8 +347,7 @@ read.collections = [

:::

Finally, the `PodioOutput` algorithm and the `Lcio2EDM4hepTool` can be
configuration should look something like this
Finally, the `Lcio2EDM4hepTool` configuration and `ApplicationMgr` should look something like this

```python
# ... MyPfoAnalysis configuration unchanged
Expand All @@ -357,19 +358,13 @@ lcio2edm4hepConv.collNameMapping = {
}
MyPfoAnalysis.Lcio2EDM4hepTool = lcio2edm4hepConv

edm4hepOutput = PodioOutput()
edm4hepOutput.filename = "zh_mumu_reco.edm4hep.root"
edm4hepOutput.outputCommands = [
"drop *",
"keep MCParticlesSkimmed",
"keep PandoraPFOs",
"keep RecoMCTruthLink",
]
# algList unchanged

# ... the complete algList
algList.append(edm4hepOutput)
from k4FWCore import ApplicationMgr

# ... ApplicationMgr config
ApplicationMgr(
TopAlg=algList, EvtSel="NONE", EvtMax=10, ExtSvc=[], OutputLevel=INFO
)
```

### Running the reconstruction with `k4run`
Expand All @@ -378,7 +373,7 @@ After all these adaptions it is now possible to run the full reconstruction
chain on the previously simulated input with `k4run`

```bash
k4run MarlinStdReco.py --num-events=3 --EventDataSvc.input=zh_mumu_SIM.edm4hep.root
k4run MarlinStdReco.py --num-events=3 --IOSvc.Input=zh_mumu_SIM.edm4hep.root
```

Here we are again using the command line to specify the input file, we could
Expand All @@ -388,6 +383,6 @@ for [this issue](https://github.com/key4hep/k4MarlinWrapper/issues/94).

You should now have a `zh_mumu_reco.edm4hep.root` file that contains the
complete events in all their glory. For a more practical output you can tweak
the `edm4hepOutput.outputCommands` option in order to keep only "interesting"
the `io_svc.outputCommands` option in order to keep only "interesting"
collections. Also note that the REC and DST LCIO output files are still
produced. Can you reproduce these data tiers for EDM4hep?