From a925cb55b76d5b9b0d59ecbb554d311d81b325ef Mon Sep 17 00:00:00 2001 From: Leonhard Reichenbach Date: Thu, 11 Apr 2024 11:31:10 +0200 Subject: [PATCH] Modernize event display example steering (#178) --- .../k4MarlinWrapperCLIC/CEDViaWrapper.md | 85 +++------------ k4MarlinWrapper/examples/event_display.py | 101 ++++++++---------- 2 files changed, 60 insertions(+), 126 deletions(-) diff --git a/doc/starterkit/k4MarlinWrapperCLIC/CEDViaWrapper.md b/doc/starterkit/k4MarlinWrapperCLIC/CEDViaWrapper.md index 625bce7c..7640344d 100644 --- a/doc/starterkit/k4MarlinWrapperCLIC/CEDViaWrapper.md +++ b/doc/starterkit/k4MarlinWrapperCLIC/CEDViaWrapper.md @@ -16,9 +16,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> -# Running an Event Display with EDM4hep input +# Running an Event Display with EDM4hep or LCIO input -It is possible to run the [C Event Display (CED)](https://github.com/iLCSoft/CED) via a wrapped [CEDViewer](https://github.com/iLCSoft/CEDViewer) Marlin Processor. This makes it possible to run the Event Dispaly with EDM4hep input files using an on the fly conversion to LCIO for CED. This introduction shows the basic concepts and also provides a options file that should work for most use cases. This example will be using the CLIC detector but should also work for other DD4hep detector models. The example is fully self contained, if you already have everything set up you can jump directly to [running the event display](#running-the-event-display). +It is possible to run the [C Event Display (CED)](https://github.com/iLCSoft/CED) via a wrapped [CEDViewer](https://github.com/iLCSoft/CEDViewer) Marlin Processor. This makes it possible to run the Event Display with EDM4hep input files using an on the fly conversion to LCIO for CED. This introduction shows the basic concepts and also provides a options file that should work for most use cases. This example will be using the CLIC detector but should also work for other DD4hep detector models. The example is fully self contained, if you already have everything set up you can jump directly to [running the event display](#running-the-event-display). ## Setting up an environment @@ -53,87 +53,36 @@ You should now have a `gamma_10GeV_edm4hep.root` file containing 10 events. ## Running the event display -In order to run the event display via the `DDCEDViewer` we use the Marlin wrapper and attach an EDM4hep to LCIO converter to the wrapped processor. In the following we will build the complete Gaudi options file step by step. Here we simply present the most important steps, but do not go over all details of the `DDCEDViewer` configuration, for that it is probably best to directly look at the [CEDViewer repository](https://github.com/iLCSoft/CEDViewer) directly. The complete Gaudi configuration can be found in [`k4MarlinWrapper/examples/event_display.py`](https://github.com/key4hep/k4MarlinWrapper/blob/master/k4MarlinWrapper/examples/event_display.py) which is also installed at `$K4MARLINWRAPPER/examples/event_display.py` +In order to run the event display via the `DDCEDViewer` we use the Marlin wrapper. Here we simply present the most important steps, but do not go over all details of the `DDCEDViewer` configuration, for that it is probably best to directly look at the [CEDViewer repository](https://github.com/iLCSoft/CEDViewer) directly. The complete Gaudi configuration can be found in [`k4MarlinWrapper/examples/event_display.py`](https://github.com/key4hep/k4MarlinWrapper/blob/master/k4MarlinWrapper/examples/event_display.py) which is also installed at `$K4MARLINWRAPPER/examples/event_display.py` -To read EDM4hep input we use the `PodioInput` module and the `k4DataSvc` -```python -from Gaudi.Configuration import * -from Configurables import k4DataSvc, PodioInput - -algList = [] - -evtsvc = k4DataSvc('EventDataSvc') -evtsvc.input = '' - -inp = PodioInput('InputReader') -inp.collections = [ - # ... all collections that should be read ... -] +In order to run the event display we first have to start the `glced` server program to which the wrapped `CEDViewer` processor will then connect. Starting the server and running the wrapped processor can be done via +```bash +glced & -algList.append(inp) +k4run $K4MARLINWRAPPER/examples/event_display.py --inputFiles=gamma_10GeV_edm4hep.root ``` -The `DDCEDViewer` also requires setting up a DD4hep geometry, which can simply be done by wrapping the `InitializeDD4hep` Marlin Processor -```python -from Configurables import MarlinProcessorWrapper +If you want to run the event display for a different geometry you can do so with the `--compactFile` argument. However, depending on your detector model you might also need to change some of the `DDCEDViewer` parameters. The default compact file is `"CLICPerformance/Visualisation/CLIC_o3_v06_CED/CLIC_o3_v06_CED.xml"`. -MyInitializeDD4hep = MarlinProcessorWrapper("MyInitializeDD4hep") -MyInitializeDD4hep.OutputLevel = INFO -MyInitializeDD4hep.ProcessorType = "InitializeDD4hep" -MyInitializeDD4hep.Parameters = { - "DD4hepXMLFile": ["CLICPerformance/Visualisation/CLIC_o3_v06_CED/CLIC_o3_v06_CED.xml"] - } -algList.append(MyInitializeDD4hep) -``` -Note that in this case we already have passed in the geometry that we want to use for the event display. +## Details + +The main work is done by the `DDCEDViewer`, which we use via the `MarlinProcessorWrapper`. It is the following part of example `event_display.py`. -Finally, the main work is done by the `DDCEDViewer`, which we again use via the `MarlinProcessorWrapper` (omitting a lot of the detailed configuration here). In order to convert the EDM4hep inputs to LCIO we attach an `EDM4hep2LcioTool` to this algorithm ```python -from Configurables import EDM4hep2LcioTool +from Configurables import MarlinProcessorWrapper MyCEDViewer = MarlinProcessorWrapper("MyCEDViewer") -MyCEDViewer.OutputLevel = INFO MyCEDViewer.ProcessorType = "DDCEDViewer" MyCEDViewer.Parameters = { # ... lots of CEDViewer configuration ... } - -# EDM4hep to LCIO converter -edmConvTool = EDM4hep2LcioTool("EDM4hep2lcio") -edmConvTool.convertAll = True -edmConvTool.collNameMapping = {'MCParticles': 'MCParticle'} -edmConvTool.OutputLevel = DEBUG -MyCEDViewer.EDM4hep2LcioTool = edmConvTool - -algList.append(MyCEDViewer) -``` - -The only thing that is left to do now is to put everything into the `ApplicationManager` in order to run things -```python -from Configurables import ApplicationMgr -ApplicationMgr( TopAlg = algList, - EvtSel = 'NONE', - EvtMax = 10, - ExtSvc = [evtsvc], - OutputLevel=INFO - ) -``` - -With all these pieces put together (as in `examples/event_display.py`) it is now possible to run the event display. In order to run the event display we first have to start the `glced` server program to which the wrapped `CEDViewer` processor will then connect. Starting the server and running the wrapped processor can be done via -```bash -glced & - -k4run $K4MARLINWRAPPER/examples/event_display.py --EventDataSvc.input=gamma_10GeV_edm4hep.root ``` +Some of the more commonly used parameters have self explanatory names. -## Creating a Gaudi options file +## Troubleshooting / Using other detectors -The `event_display.py` options file that is used above and that is present in the examples has been produced following these steps: -- Using an `.slcio` input file and the desired geometry, run `ced2go` with the desired arguments. - - This produces a Marlin XML steering file on the fly and stores it at `/tmp/ced2go_${USER}_steering.xml` -- Using the `convertMarlinSteeringToGaudi.py` converter script convert this into a Gaudi options file -- Exchange the LCIO input reading by the podio input reading (see above) -- Attach the `EDM4hep2LcioTool` to the wrapped `CEDViewer` processor +When running this for a detector different than CLD, CLIC or ILD (or a derivative of one of them) you might not see anything in the event display. -This should allow one to arrive at a similar steering file even for slightly different configurations. One potential pitfall is the slightly different naming of the `ddsim` outputs between LCIO and EDM4hep (see [this issue](https://github.com/AIDASoft/DD4hep/issues/921)). This can be addressed by configuring the EDM4hep to LCIO converter (`edmConvTool` in the code above) to map the names accordingly. +If you are not seeing the detector make sure that it has the proper visualisation attributes, e.g. by comparing it to the compact file used above. +If you are not seeing any hits, tracks etc. from your event, make sure to add their collection names to the `DrawInLayer` list in the `DDCEDViewer` parameters. diff --git a/k4MarlinWrapper/examples/event_display.py b/k4MarlinWrapper/examples/event_display.py index 15d04136..36d0a500 100644 --- a/k4MarlinWrapper/examples/event_display.py +++ b/k4MarlinWrapper/examples/event_display.py @@ -18,58 +18,49 @@ # limitations under the License. # -from Gaudi.Configuration import * +from Gaudi.Configuration import INFO +from Configurables import MarlinProcessorWrapper, k4DataSvc, GeoSvc +from k4FWCore.parseArgs import parser +from k4MarlinWrapper.inputReader import create_reader, attach_edm4hep2lcio_conversion + + +parser.add_argument( + "--inputFiles", + action="extend", + nargs="+", + metavar=["file1", "file2"], + help="One or multiple input files", +) + +parser.add_argument( + "--compactFile", + help="Compact detector file to use", + type=str, + default="CLICPerformance/Visualisation/CLIC_o3_v06_CED/CLIC_o3_v06_CED.xml" +) + +reco_args = parser.parse_known_args()[0] -from Configurables import MarlinProcessorWrapper, k4DataSvc, PodioInput, EDM4hep2LcioTool algList = [] +svcList = [] -evtsvc = k4DataSvc('EventDataSvc') -evtsvc.input = '' +evtsvc = k4DataSvc("EventDataSvc") +svcList.append(evtsvc) -inp = PodioInput('InputReader') -inp.collections = [ - 'MCParticles', - 'VertexBarrelCollection', - 'VertexEndcapCollection', - 'InnerTrackerBarrelCollection', - 'OuterTrackerBarrelCollection', - 'InnerTrackerEndcapCollection', - 'OuterTrackerEndcapCollection', - 'ECalEndcapCollection', - 'ECalEndcapCollectionContributions', - 'ECalBarrelCollection', - 'ECalBarrelCollectionContributions', - 'ECalPlugCollection', - 'ECalPlugCollectionContributions', - 'HCalBarrelCollection', - 'HCalBarrelCollectionContributions', - 'HCalEndcapCollection', - 'HCalEndcapCollectionContributions', - 'HCalRingCollection', - 'HCalRingCollectionContributions', - 'YokeBarrelCollection', - 'YokeBarrelCollectionContributions', - 'YokeEndcapCollection', - 'YokeEndcapCollectionContributions', - 'LumiCalCollection', - 'LumiCalCollectionContributions', - 'BeamCalCollection', - 'BeamCalCollectionContributions', -] -MyInitializeDD4hep = MarlinProcessorWrapper("MyInitializeDD4hep") -MyInitializeDD4hep.OutputLevel = INFO -MyInitializeDD4hep.ProcessorType = "InitializeDD4hep" -MyInitializeDD4hep.Parameters = { - "DD4hepXMLFile": ["CLICPerformance/Visualisation/CLIC_o3_v06_CED/CLIC_o3_v06_CED.xml"] - } +geoSvc = GeoSvc("GeoSvc") +geoSvc.detectors = [reco_args.compactFile] +geoSvc.OutputLevel = INFO +geoSvc.EnableGeant4Geo = False +svcList.append(geoSvc) -MyEventSelector = MarlinProcessorWrapper("MyEventSelector") -MyEventSelector.OutputLevel = INFO -MyEventSelector.ProcessorType = "EventSelector" -MyEventSelector.Parameters = { - "EventList": ["28", "0", "33", "0", "52", "0", "63", "0", "73", "0", "78", "0"] - } + +if reco_args.inputFiles: + read = create_reader(reco_args.inputFiles, evtsvc) + read.OutputLevel = INFO + algList.append(read) +else: + read = None MyCEDViewer = MarlinProcessorWrapper("MyCEDViewer") MyCEDViewer.OutputLevel = INFO @@ -208,21 +199,15 @@ "WaitForKeyboard": ["1"] } -# EDM4hep to LCIO converter -edmConvTool = EDM4hep2LcioTool("EDM4hep2lcio") -edmConvTool.convertAll = True -edmConvTool.collNameMapping = {'MCParticles': 'MCParticle'} -edmConvTool.OutputLevel = DEBUG -MyCEDViewer.EDM4hep2LcioTool = edmConvTool - -algList.append(inp) -algList.append(MyInitializeDD4hep) algList.append(MyCEDViewer) +# We need to convert the inputs in case we have EDM4hep input +attach_edm4hep2lcio_conversion(algList, read) + from Configurables import ApplicationMgr ApplicationMgr( TopAlg = algList, EvtSel = 'NONE', - EvtMax = 10, - ExtSvc = [evtsvc], - OutputLevel=INFO + EvtMax = 10, + ExtSvc = svcList, + OutputLevel = INFO )