Skip to content

Commit ddfa25e

Browse files
Merge pull request #376 from RobMina/codex/crv-pulse-hit-index
CRV pulse hit index to replace pulses vector
2 parents 0430796 + 65e2741 commit ddfa25e

16 files changed

Lines changed: 174 additions & 49 deletions

doc/branches.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,13 @@ Calorimeter hits store crystal position in (x,y,z) with frame origin at tracker
112112
The calorimeter MC branches provide MC-truth information at different levels of the calorimeter reconstruction hierarchy.
113113

114114
**Alignment with Reconstruction Branches:**
115-
MC information branches are aligned with their corresponding reco branches:
115+
Most calorimeter MC branches are index-aligned with their reco counterparts (same size and element index). One important exception:
116+
117+
> **Warning — `calohitsmc` is not aligned with `calohits`.** Reco hits come from `CaloHitMaker`; MC hits come from `compressRecoMCs`, which repacks `CaloHitMC` objects when copying cluster MC truth. The two branches can differ in size and order. Offline pairs reco and MC hits via `CaloHitMCTruthAssn` at reconstruction time, but that association is not kept in production art files read by EventNtuple. Each `calohitsmc` element therefore carries `caloHitIdx_` (index into `calohits`, or `-1`). RooUtil resolves MC hits through `caloHitIdx_`; do **not** assume `calohitsmc[i]` corresponds to `calohits[i]`.
118+
116119
- `caloclustersmc` ← aligned with `caloclusters` (same size & indices)
117-
- `calohitsmc` ← aligned with `calohits` (same size & indices)
118-
- `calodigismc` ← aligned with `calodigis` (same size & indices; raw digi MC truth) (also: `calorecodigis` too)
120+
- `calohitsmc`**not** index-aligned with `calohits` (see warning above); use `caloHitIdx_` to find the reco hit
121+
- `calodigismc` ← aligned with `calodigis` when both branches are filled (same size & indices; raw digi MC truth)
119122
- `calodigisim` ← unique SimParticles from raw digis
120123
- `calomcsim` ← unique SimParticles from MC clusters
121124

@@ -124,7 +127,7 @@ Each MC element contains `simParticleIds` to index into the corresponding `*mcsi
124127
| branch | structure | explanation | key fields | leaf information |
125128
|--------|-----------|-------------|-----------|------------------|
126129
| caloclustersmc | Vector branch | MC-truth information for calorimeter clusters (aligned with caloclusters)| `nsim` (# of sim particles), `etot` (total true energy), `tavg` (avg time), `eprimary` (primary particle energy), `tprimary` (primary time), `simParticleIds`, `simRels` (MCRelationship), `hits_`, `prel` (primary to event primary relationship) | [see CaloClusterInfoMC.hh](../inc/CaloClusterInfoMC.hh)
127-
| calohitsmc | Vector branch | MC-truth information for calorimeter hits (aligned with calohits)| `nsim`, `eDep`, `eDepG4`, `eprimary`, `tprimary`, `eDeps`, `tDeps`, `momentumIns`, `simParticleIds`, `simRels`, `caloClusterIdx_`, etc. | [see CaloHitInfoMC.hh](../inc/CaloHitInfoMC.hh)
130+
| calohitsmc | Vector branch | MC-truth for calorimeter hits (**not** index-aligned with `calohits`; use `caloHitIdx_`)| `nsim`, `eDep`, `eDepG4`, `eprimary`, `tprimary`, `eDeps`, `tDeps`, `momentumIns`, `simParticleIds`, `simRels`, `clusterIdx_`, `caloHitIdx_`, etc. | [see CaloHitInfoMC.hh](../inc/CaloHitInfoMC.hh)
128131
| calodigismc | Vector branch | MC-truth information for raw calorimeter digis (aligned with calodigis)| `nsim`, `eDep`, `eDepG4`, `eprimary`, `tprimary`, `eDeps`, `tDeps`, `momentumIns`, `simParticleIds`, `simRels`, `caloHitIdx_`, `crystalID_`, `diskID_`, `energyCorr_`, `timeCorr_`, `posX_`, `posY_` | [see CaloDigiMCInfo.hh](../inc/CaloDigiMCInfo.hh)
129132
| calodigisim | Vector branch | unique SimParticles in all raw digis (genealogy information)| SimParticle genealogy info | [see SimInfo.hh](../inc/SimInfo.hh)
130133
| calomcsim | Vector branch | unique SimParticles in all MC clusters (genealogy information)| SimParticle genealogy info | [see SimInfo.hh](../inc/SimInfo.hh)
@@ -140,6 +143,8 @@ The branch is empty if there are no CRV hit during the event.
140143
| crvcoincs | Vector branch | information about a cluster of CRV coincidence triplets| [see CrvHitInfoReco.hh](../inc/CrvHitInfoReco.hh)
141144
| crvcoincsmc | Vector branch | information about the MC track which most likely caused the CRV coincidence triplets| [see CrvHitInfoMC.hh](../inc/CrvHitInfoMC.hh)
142145
| crvcoincsmcplane | Vector branch | information about the point where the MC trajectory crosses the xz plane of CRV-T| [see CrvPlaneInfoMC.hh](../inc/CrvPlaneInfoMC.hh)
146+
| crvpulses | Vector branch | information about CRV reco pulses, including ROC/FEB/FEB channel IDs. `crvHitIndex` gives the index in `crvcoincs`, or -1 if the pulse was not clustered into a CRV hit| [see CrvPulseInfoReco.hh](../inc/CrvPulseInfoReco.hh)
147+
| crvpulsesmc | Vector branch | MC-truth information corresponding entry-by-entry to `crvpulses`| [see CrvHitInfoMC.hh](../inc/CrvHitInfoMC.hh)
143148
## Trigger Branches
144149

145150
Trigger branches store trigger decision information for each event and track hypothesis. Each trigger branch corresponds to a different trigger path or decision criterion.

fcl/prolog.fcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ EventNtupleMaker : {
361361
recoPulsesTag : "SelectReco"
362362
stepsTag : "compressRecoMCs"
363363
fillPulses : false
364+
keepUnclusteredPulses : false
364365
fillDigis : false
365366
digisTag : "SelectReco"
366367
planeY : @local::crvPlaneY.CRV_T

inc/CaloHitInfoMC.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ namespace mu2e
2222
std::vector<int> simParticleIds; // list of simparticle ids
2323
std::vector<MCRelationship> simRels; // relationship to the particle that deposited the most energy in the calo Hit
2424
int clusterIdx_; // Cluster index
25+
int caloHitIdx_; // index into calohits branch, -1 if unset; calohitsmc is NOT index-aligned with calohits
2526

26-
CaloHitInfoMC() : crystalID_(0), nsim(0), eDep(0.0), eDepG4(0.0), eprimary(0.0), tprimary(0.0), clusterIdx_(-1){}
27+
CaloHitInfoMC() : crystalID_(0), nsim(0), eDep(0.0), eDepG4(0.0), eprimary(0.0), tprimary(0.0), clusterIdx_(-1), caloHitIdx_(-1){}
2728

2829
void reset() { *this = CaloHitInfoMC(); }
2930

inc/CrvHitInfoReco.hh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
// CrvHitInfoReco: information about a cluster of CRV coincidence triplets
55

6-
#include "EventNtuple/inc/CrvPulseInfoReco.hh"
76
#include "EventNtuple/inc/RootVectors.hh"
87
#include "Offline/DataProducts/inc/CRVId.hh"
98
namespace CLHEP {class Hep3Vector; }
@@ -30,10 +29,9 @@ namespace mu2e
3029
int nHits = -1; //number of coincidence hits in this cluster
3130
int nLayers = -1; //number of coincidence layers in this cluster
3231
float angle = -999; //coincidence direction
33-
std::vector<CrvPulseInfoReco> crvPulses;
3432

3533
CrvHitInfoReco(){}
36-
CrvHitInfoReco(int sectorType, bool hitPosAndTimeCalculated, CLHEP::Hep3Vector hpos, float timeWindowStart, float timeWindowEnd, float timeAvg, float PEs, std::array<float, CRVId::nLayers> PEsPerLayer, std::array<float, CRVId::nLayers * CRVId::nSidesPerBar> sidePEsPerLayer, std::array<size_t, CRVId::nSidesPerBar> sidePulses, std::array<float, CRVId::nSidesPerBar> sidePEs, std::array<float, CRVId::nSidesPerBar> sideTimes, int nCoincidenceHits, int nCoincidenceLayers, float coincidenceAngle, std::vector<CrvPulseInfoReco> crvPulses);
34+
CrvHitInfoReco(int sectorType, bool hitPosAndTimeCalculated, CLHEP::Hep3Vector hpos, float timeWindowStart, float timeWindowEnd, float timeAvg, float PEs, std::array<float, CRVId::nLayers> PEsPerLayer, std::array<float, CRVId::nLayers * CRVId::nSidesPerBar> sidePEsPerLayer, std::array<size_t, CRVId::nSidesPerBar> sidePulses, std::array<float, CRVId::nSidesPerBar> sidePEs, std::array<float, CRVId::nSidesPerBar> sideTimes, int nCoincidenceHits, int nCoincidenceLayers, float coincidenceAngle);
3735
};
3836
typedef std::vector<CrvHitInfoReco> CrvHitInfoRecoCollection; //this is the reco vector which will be stored in the main TTree
3937
}

inc/CrvInfoHelper.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,17 @@ namespace mu2e
4242
CrvPlaneInfoMCCollection &MCInfoPlane, double crvPlaneY,
4343
art::Handle<PrimaryParticle> const& primary);
4444

45+
void FillCrvPulseHitIndices(
46+
art::Handle<CrvCoincidenceClusterCollection> const& crvCoincidences,
47+
art::Handle<CrvRecoPulseCollection> const& crvRecoPulses,
48+
std::vector<int> &pulseHitIndices);
49+
4550
void FillCrvPulseInfoCollections(
4651
art::Handle<CrvRecoPulseCollection> const& crvRecoPulses,
4752
art::Handle<CrvDigiMCCollection> const& crvDigiMCs,
4853
art::Handle<EventWindowMarker> const& ewmh,
54+
const std::vector<int> &pulseHitIndices,
55+
bool keepUnclusteredPulses,
4956
CrvPulseInfoRecoCollection &recoInfo, CrvHitInfoMCCollection &MCInfo);
5057

5158
void FillCrvDigiInfoCollections(

inc/CrvPulseInfoReco.hh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,19 @@ namespace mu2e
1515
int barId = -1; //CRV counter ID
1616
int sectorId = -1; //CRV sector ID
1717
int SiPMId = -1; //SiPMId number
18+
int ROC = -1; //ROC number
19+
int FEB = -1; //FEB number
20+
int FEBchannel = -1; //FEB channel number
1821
int PEs = -1; //PEs using pulse integral
1922
int PEsPulseHeight = -1; //PEs using pulse height
2023
float pulseHeight = -1; //Pulse height
2124
float pulseBeta = -1; //Pulse beta
2225
float pulseFitChi2 = -1; //Pulse Fit chi2
2326
float time = -1; //Time
27+
int crvHitIndex = -1; //index of the CRV hit containing this pulse, or -1 if unclustered
2428

2529
CrvPulseInfoReco(){}
26-
CrvPulseInfoReco(CLHEP::Hep3Vector ppos, int barId, int sectorId, int SiPMId, int PEs, int PEsPulseHeight, float pulseHeight, float pulseBeta, float pulseFitChi2, float time);
30+
CrvPulseInfoReco(CLHEP::Hep3Vector ppos, int barId, int sectorId, int SiPMId, int ROC, int FEB, int FEBchannel, int PEs, int PEsPulseHeight, float pulseHeight, float pulseBeta, float pulseFitChi2, float time, int crvHitIndex);
2731
};
2832

2933
typedef std::vector<CrvPulseInfoReco> CrvPulseInfoRecoCollection; //this is the reco vector which will be stored in the main TTree

rooutil/examples/PrintEvents.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ void PrintEvents(std::string filename) {
212212
// crvpulses branch
213213
if (event.crvpulses != nullptr) {
214214
for (const auto& crvpulse : *(event.crvpulses)) {
215-
std::cout << "crvpulse: " << crvpulse.pos.x() << "," << crvpulse.barId << "," << crvpulse.time << std::endl;
215+
std::cout << "crvpulse: " << crvpulse.pos.x() << "," << crvpulse.barId << "," << crvpulse.ROC << "," << crvpulse.FEB << "," << crvpulse.FEBchannel << "," << crvpulse.time << "," << crvpulse.crvHitIndex << std::endl;
216216
}
217217
}
218218

rooutil/inc/Event.hh

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "EventNtuple/inc/TrkStrawHitCalibInfo.hh"
3737

3838
#include "EventNtuple/inc/MVAResultInfo.hh"
39+
#include <stdexcept>
3940

4041
#include "EventNtuple/inc/TrigInfo.hh"
4142
#include "EventNtuple/inc/MCStepInfo.hh"
@@ -155,6 +156,8 @@ namespace rooutil {
155156
for (int i_crv_coinc = 0; i_crv_coinc < nCrvCoincs(); ++i_crv_coinc) {
156157
CrvCoinc crv_coinc(&(crvcoincs->at(i_crv_coinc)));
157158
if (crvcoincsmc != nullptr) {
159+
if (i_crv_coinc >= static_cast<int>(crvcoincsmc->size()))
160+
throw std::runtime_error("CRV coincidence cluster count mismatch between reco and MC collections");
158161
crv_coinc.mc = &(crvcoincsmc->at(i_crv_coinc));
159162
}
160163
crv_coincs.emplace_back(crv_coinc);
@@ -185,8 +188,15 @@ namespace rooutil {
185188
CaloHit calohit;
186189
calohit.reco = &(calohits->at(calohit_Idx)); // passing the addresses of the underlying structs
187190

188-
if (calohitsmc != nullptr) { // 1-to-1 matching of calohits and calohitsmc
189-
calohit.mc = &(calohitsmc->at(calohit_Idx));
191+
// WARNING: calohitsmc is NOT index-aligned with calohits (different art products).
192+
// Do not use calohitsmc->at(calohit_Idx); look up via caloHitIdx_ instead.
193+
if (calohitsmc != nullptr) {
194+
for (int i_mc = 0; i_mc < static_cast<int>(calohitsmc->size()); ++i_mc) {
195+
if (calohitsmc->at(i_mc).caloHitIdx_ == static_cast<int>(calohit_Idx)) {
196+
calohit.mc = &(calohitsmc->at(i_mc));
197+
break;
198+
}
199+
}
190200
}
191201

192202
calo_cluster.hits.emplace_back(calohit);

src/CrvHitInfoReco.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "EventNtuple/inc/CrvHitInfoReco.hh"
22
#include "CLHEP/Vector/ThreeVector.h"
33
namespace mu2e {
4-
CrvHitInfoReco::CrvHitInfoReco(int sectorType, bool hitPosAndTimeCalculated, CLHEP::Hep3Vector hpos, float timeWindowStart, float timeWindowEnd, float timeAvg, float PEs, std::array<float, CRVId::nLayers> PEsPerLayer, std::array<float, CRVId::nLayers * CRVId::nSidesPerBar> sidePEsPerLayer, std::array<size_t, CRVId::nSidesPerBar> sidePulses, std::array<float, CRVId::nSidesPerBar> sidePEs, std::array<float, CRVId::nSidesPerBar> sideTimes, int nCoincidenceHits, int nCoincidenceLayers, float coincidenceAngle, CrvPulseInfoRecoCollection crvPulses) :
4+
CrvHitInfoReco::CrvHitInfoReco(int sectorType, bool hitPosAndTimeCalculated, CLHEP::Hep3Vector hpos, float timeWindowStart, float timeWindowEnd, float timeAvg, float PEs, std::array<float, CRVId::nLayers> PEsPerLayer, std::array<float, CRVId::nLayers * CRVId::nSidesPerBar> sidePEsPerLayer, std::array<size_t, CRVId::nSidesPerBar> sidePulses, std::array<float, CRVId::nSidesPerBar> sidePEs, std::array<float, CRVId::nSidesPerBar> sideTimes, int nCoincidenceHits, int nCoincidenceLayers, float coincidenceAngle) :
55
sectorType(sectorType),
66
hitPosAndTimeCalculated(hitPosAndTimeCalculated),
77
pos(hpos),
@@ -16,7 +16,6 @@ namespace mu2e {
1616
sideTimes(sideTimes),
1717
nHits(nCoincidenceHits),
1818
nLayers(nCoincidenceLayers),
19-
angle(coincidenceAngle),
20-
crvPulses(crvPulses)
19+
angle(coincidenceAngle)
2120
{}
2221
}

0 commit comments

Comments
 (0)