Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions data/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
#[[
Copyright (c) 2020-2024 Key4hep-Project.

This file is part of Key4hep.
See https://key4hep.github.io/key4hep-doc/ for further info.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
]]

# ECAL thresholds
INSTALL(FILES ECAL_Thresholds_3TeV.root ECAL_Thresholds_10TeV.root
DESTINATION ${CMAKE_INSTALL_DATADIR}/k4Reco/data)
Expand Down
51 changes: 50 additions & 1 deletion k4Reco/BIBUtils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ in the Muon Collider reconstruction. They were originally Marlin processors:
| Gaudi algorithm | Original Marlin processor | Original package |
|-------------------|---------------------------|------------------|
| `FilterConeHits` | `FilterConeHits` | [MarlinTrkProcessors](https://github.com/MuonColliderSoft/MarlinTrkProcessors) |
| `SplitCollectionByPolarAngle` | `SplitCollectionByPolarAngle` | [MarlinTrkProcessors](https://github.com/MuonColliderSoft/MarlinTrkProcessors) |
| `SplitCollectionByLayer` | `SplitCollectionByLayer` | [MarlinTrkProcessors](https://github.com/MuonColliderSoft/MarlinTrkProcessors) |
| `CaloConer` | `CaloConer` | [MyBIBUtils](https://github.com/madbaron/MyBIBUtils) |
| `CaloHitSelector` | `CaloHitSelector` | [MyBIBUtils](https://github.com/madbaron/MyBIBUtils) |

All three are functional `k4FWCore::MultiTransformer`s. Selected hits are written
All of them are functional `k4FWCore::MultiTransformer`s. Selected hits are written
to **subset** collections that reference the original hits, accompanied by a
freshly built reco-to-sim link collection. The simulated hit of a given
reconstructed hit is resolved through the input link collection rather than by
Expand Down Expand Up @@ -63,6 +65,53 @@ collection (vertex/inner/outer × barrel/endcap), as in the original steering.
| `FillHistograms` | `false` | fill diagnostic histograms |
| `TrackerOuterRadius` | `1500` | tracker barrel outer radius used to clip the helix [mm] |

## SplitCollectionByPolarAngle

Keeps the tracker hits whose polar angle `theta = acos(z/r)` lies inside the
window `[PolarAngleLowerLimit, PolarAngleUpperLimit]` (given in degrees). Unlike
`FilterConeHits` this selection is purely geometric and needs neither the MC
particles nor the detector field, so no `GeoSvc` is required.

Each instance handles a single tracker collection — configure one instance per
collection, as in the original steering.

| Property | Default | Description |
|---|---|---|
| `TrackerHitInputCollections` | `VBTrackerHits` | input reco tracker hits |
| `TrackerHitInputRelations` | `VBTrackerHitsRelations` | input reco→sim links |
| `TrackerHitOutputCollections` | `VBTrackerHitsSplit` | output reco hits (subset) |
| `TrackerSimHitOutputCollections` | `VertexBarrelCollectionSplit` | output sim hits (subset) |
| `TrackerHitOutputRelations` | `VBTrackerHitsRelationsSplit` | output reco→sim links |
| `PolarAngleLowerLimit` | `50` | lower limit on the hit polar angle [deg] |
| `PolarAngleUpperLimit` | `130` | upper limit on the hit polar angle [deg] |
| `FillHistograms` | `false` | fill diagnostic histograms |

## SplitCollectionByLayer

Splits a single tracker-hit collection into several output collections according
to the `layer` number decoded from each hit's cellID (via the `GeoSvc` and the
`GlobalTrackerReadoutID` encoding). Output collection `i` collects the hits whose
layer lies in the closed interval `[StartLayers[i], EndLayers[i]]`; a hit is
copied into every output whose interval contains its layer, so overlapping
intervals duplicate the hit, as in the original processor. The number of output
collections is arbitrary and follows the length of `OutputCollections`, which
must match `StartLayers` and `EndLayers`.

Two differences from the Marlin processor: it targets `edm4hep::TrackerHitPlane`
collections (the original dispatched on the LCIO hit type at run time), and it
always writes every configured output collection (the `KeepEmptyCollections`
switch has no equivalent in the functional data flow, where the output handles
are fixed).

| Property | Default | Description |
|---|---|---|
| `InputCollection` | `VBTrackerHits` | input reco tracker hits |
| `OutputCollections` | `[VBTrackerHitsInner, VBTrackerHitsOuter]` | output reco hits, one subset collection per entry |
| `StartLayers` | `[]` | first layer (inclusive) routed to each output collection |
| `EndLayers` | `[]` | last layer (inclusive) routed to each output collection |
| `EncodingStringParameterName` | `GlobalTrackerReadoutID` | DD4hep constant with the tracker cellID encoding |
| `GeoSvcName` | `GeoSvc` | name of the GeoSvc instance |

## CaloConer

Keeps the calorimeter hits within a fixed angular cone (`ConeWidth`, in radians)
Expand Down
74 changes: 74 additions & 0 deletions k4Reco/BIBUtils/include/SplitCollectionByLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2020-2024 Key4hep-Project.
*
* This file is part of Key4hep.
* See https://key4hep.github.io/key4hep-doc/ for further info.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
#ifndef K4RECO_SPLITCOLLECTIONBYLAYER_H
#define K4RECO_SPLITCOLLECTIONBYLAYER_H 1

#include "Gaudi/Property.h"

#include <edm4hep/TrackerHitPlaneCollection.h>

#include <k4FWCore/Transformer.h>
#include <k4Interface/IGeoSvc.h>

#include <GaudiKernel/StatusCode.h>

#include <string>
#include <vector>

/** === SplitCollectionByLayer ===
* Splits a single tracker-hit collection into several output collections
* according to the layer number decoded from each hit's cellID. Every output
* collection i collects the hits whose layer lies in the closed interval
* [StartLayers[i], EndLayers[i]]; a hit is copied into every output whose
* interval contains its layer, so overlapping intervals duplicate the hit as
* in the original processor. The outputs are subset collections referencing
* the original hits.
*
* Gaudi-native port of the Marlin SplitCollectionByLayer processor from
* MarlinTrkProcessors (MuonColliderSoft). The original processor dispatched on
* the LCIO hit type at run time; this port targets edm4hep::TrackerHitPlane
* collections, consistent with the other BIBUtils tracker algorithms. The
* number of output collections is arbitrary and follows the length of the
* OutputCollections list, which must match StartLayers and EndLayers.
*
* @author F. Gaede, DESY (original Marlin processor)
*/
struct SplitCollectionByLayer final : k4FWCore::Transformer<std::vector<edm4hep::TrackerHitPlaneCollection>(
const edm4hep::TrackerHitPlaneCollection&)> {
SplitCollectionByLayer(const std::string& name, ISvcLocator* svcLoc);

StatusCode initialize() override;

std::vector<edm4hep::TrackerHitPlaneCollection>
operator()(const edm4hep::TrackerHitPlaneCollection& trackerHits) const override;

private:
Gaudi::Property<std::vector<int>> m_startLayers{
this, "StartLayers", {}, "First layer (inclusive) routed to each output collection"};
Gaudi::Property<std::vector<int>> m_endLayers{
this, "EndLayers", {}, "Last layer (inclusive) routed to each output collection"};
Gaudi::Property<std::string> m_encodingStringVariable{
this, "EncodingStringParameterName", "GlobalTrackerReadoutID",
"The name of the DD4hep constant that contains the cellID encoding string for tracking detectors"};
Gaudi::Property<std::string> m_geoSvcName{this, "GeoSvcName", "GeoSvc", "The name of the GeoSvc instance"};

SmartIF<IGeoSvc> m_geoSvc;
};

#endif
87 changes: 87 additions & 0 deletions k4Reco/BIBUtils/include/SplitCollectionByPolarAngle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2020-2024 Key4hep-Project.
*
* This file is part of Key4hep.
* See https://key4hep.github.io/key4hep-doc/ for further info.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
#ifndef K4RECO_SPLITCOLLECTIONBYPOLARANGLE_H
#define K4RECO_SPLITCOLLECTIONBYPOLARANGLE_H 1

#include "Gaudi/Accumulators/RootHistogram.h"
#include "Gaudi/Property.h"

#include <edm4hep/SimTrackerHitCollection.h>
#include <edm4hep/TrackerHitPlaneCollection.h>
#include <edm4hep/TrackerHitSimTrackerHitLinkCollection.h>

#include <k4FWCore/Transformer.h>

#include <GaudiKernel/StatusCode.h>

#include <array>
#include <memory>
#include <string>
#include <tuple>

#include "GAUDI_VERSION.h"

#if GAUDI_MAJOR_VERSION < 39
namespace Gaudi::Accumulators {
template <unsigned int ND, atomicity Atomicity = atomicity::full, typename Arithmetic = double>
using StaticRootHistogram =
Gaudi::Accumulators::RootHistogramingCounterBase<ND, Atomicity, Arithmetic, naming::histogramString>;
}
#endif

/** === SplitCollectionByPolarAngle ===
* Selects the tracker hits whose polar angle theta = acos(z/r) lies inside the
* configurable window [PolarAngleLowerLimit, PolarAngleUpperLimit] (expressed in
* degrees), together with the corresponding simulated hits and reco-to-sim
* links. The accepted reco and sim hits are written out as subset collections
* and a freshly built link collection connects them.
*
* Gaudi-native port of the Marlin SplitCollectionByPolarAngle processor from
* MarlinTrkProcessors (MuonColliderSoft). Each instance handles a single
* tracker collection; configure one instance per collection. The simulated
* hits are taken from the input reco-to-sim links, so no separate simhit input
* collection is needed.
*
* @author M. Casarsa, INFN Trieste (original Marlin processor)
*/
struct SplitCollectionByPolarAngle final
: k4FWCore::MultiTransformer<std::tuple<edm4hep::TrackerHitPlaneCollection, edm4hep::SimTrackerHitCollection,
edm4hep::TrackerHitSimTrackerHitLinkCollection>(
const edm4hep::TrackerHitPlaneCollection&, const edm4hep::TrackerHitSimTrackerHitLinkCollection&)> {
SplitCollectionByPolarAngle(const std::string& name, ISvcLocator* svcLoc);

StatusCode initialize() override;

std::tuple<edm4hep::TrackerHitPlaneCollection, edm4hep::SimTrackerHitCollection,
edm4hep::TrackerHitSimTrackerHitLinkCollection>
operator()(const edm4hep::TrackerHitPlaneCollection& trackerHits,
const edm4hep::TrackerHitSimTrackerHitLinkCollection& trackerHitLinks) const override;

private:
Gaudi::Property<double> m_thetaMin{this, "PolarAngleLowerLimit", 50.,
"Lower limit on the hit polar angle in degrees"};
Gaudi::Property<double> m_thetaMax{this, "PolarAngleUpperLimit", 130.,
"Upper limit on the hit polar angle in degrees"};
Gaudi::Property<bool> m_fillHistos{this, "FillHistograms", false, "Flag to fill the diagnostic histograms"};

enum { hTheta = 0, hSize };
std::array<std::unique_ptr<Gaudi::Accumulators::StaticRootHistogram<1>>, hSize> m_histograms;
};

#endif
55 changes: 55 additions & 0 deletions k4Reco/BIBUtils/options/runSplitCollectionByLayer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#
# Copyright (c) 2020-2024 Key4hep-Project.
#
# This file is part of Key4hep.
# See https://key4hep.github.io/key4hep-doc/ for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
#
from Gaudi.Configuration import INFO
from k4FWCore import ApplicationMgr, IOSvc
from Configurables import EventDataSvc
from Configurables import SplitCollectionByLayer
from Configurables import GeoSvc
import os

geoservice = GeoSvc("GeoSvc")
geoservice.detectors = [
os.environ["MUONCOLLIDER_GEO"]
if "MUONCOLLIDER_GEO" in os.environ
else os.environ["K4GEO"] + "/MuColl/MuColl_v1/MuColl_v1.xml"
]
geoservice.OutputLevel = INFO
geoservice.EnableGeant4Geo = False

# The number of output collections is arbitrary and follows the length of
# OutputCollections; StartLayers and EndLayers must have the same length. Each
# output collection i collects the hits whose layer is in [StartLayers[i],
# EndLayers[i]].
splitter = SplitCollectionByLayer("VBTrackerHitsByLayer")
splitter.InputCollection = ["VBTrackerHits"]
splitter.OutputCollections = ["VBTrackerHitsInner", "VBTrackerHitsOuter"]
splitter.StartLayers = [0, 4]
splitter.EndLayers = [3, 7]

iosvc = IOSvc()
iosvc.Input = "digi_output.edm4hep.root"
iosvc.Output = "split_by_layer_output.edm4hep.root"

ApplicationMgr(
TopAlg=[splitter],
EvtSel="NONE",
EvtMax=-1,
ExtSvc=[EventDataSvc("EventDataSvc"), geoservice],
OutputLevel=INFO,
)
53 changes: 53 additions & 0 deletions k4Reco/BIBUtils/options/runSplitCollectionByPolarAngle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#
# Copyright (c) 2020-2024 Key4hep-Project.
#
# This file is part of Key4hep.
# See https://key4hep.github.io/key4hep-doc/ for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# 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.
#
from Gaudi.Configuration import INFO
from k4FWCore import ApplicationMgr, IOSvc
from Configurables import EventDataSvc
from Configurables import SplitCollectionByPolarAngle
from Configurables import RootHistSvc
from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink

# One instance per tracker collection. The simulated hits are taken from the
# input reco-to-sim relations, so only the reco hit and relation collections
# are needed as inputs.
splitter = SplitCollectionByPolarAngle("VXDBarrelSplitter")
splitter.TrackerHitInputCollections = ["VBTrackerHits"]
splitter.TrackerHitInputRelations = ["VBTrackerHitsRelations"]
splitter.TrackerHitOutputCollections = ["VBTrackerHitsSplit"]
splitter.TrackerSimHitOutputCollections = ["VertexBarrelCollectionSplit"]
splitter.TrackerHitOutputRelations = ["VBTrackerHitsRelationsSplit"]
splitter.PolarAngleLowerLimit = 50.0
splitter.PolarAngleUpperLimit = 130.0
splitter.FillHistograms = False

iosvc = IOSvc()
iosvc.Input = "digi_output.edm4hep.root"
iosvc.Output = "split_output.edm4hep.root"

hps = RootHistSvc("HistogramPersistencySvc")
root_hist_svc = RootHistoSink("RootHistoSink")
root_hist_svc.FileName = "splitcollectionbypolarangle_hist.root"

ApplicationMgr(
TopAlg=[splitter],
EvtSel="NONE",
EvtMax=-1,
ExtSvc=[EventDataSvc("EventDataSvc"), root_hist_svc],
OutputLevel=INFO,
)
Loading
Loading