Belle II Software development
ECLTRGInformationModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9/* Own header. */
10#include <ecl/modules/eclTRGInformation/ECLTRGInformationModule.h>
11
12/* ECL headers. */
13#include <ecl/dataobjects/ECLCalDigit.h>
14#include <ecl/dataobjects/ECLElementNumbers.h>
15
16/* Basf2 headers. */
17#include <analysis/dataobjects/ECLTRGInformation.h>
18#include <analysis/dataobjects/ECLTriggerCell.h>
19#include <framework/logging/Logger.h>
20#include <framework/gearbox/Unit.h>
21#include <mdst/dataobjects/ECLCluster.h>
22#include <trg/ecl/dataobjects/TRGECLUnpackerEvtStore.h>
23#include <trg/ecl/dataobjects/TRGECLUnpackerStore.h>
24#include <trg/ecl/TrgEclMapping.h>
25
26using namespace Belle2;
27using namespace std;
28
29//-----------------------------------------------------------------
30// Register the Module
31//-----------------------------------------------------------------
33
34//-----------------------------------------------------------------
35// Implementation
36//-----------------------------------------------------------------
37
39{
40 // Set module properties
41 setDescription("Get ECL TRG energy information");
42 addParam("clusterEnergyThreshold", m_clusterEnergyThreshold, "Include ECLClusters above this energy in the energy sum.",
43 100.0 * Belle2::Unit::MeV);
44
46}
47
49{
51 m_eclCalDigits.isRequired();
52 m_eclClusters.isRequired();
53 m_trgUnpackerStore.isRequired();
54 m_trgUnpackerEvtStore.isRequired();
55
57 m_eclTRGInformation.registerInDataStore();
58 m_eclTCs.registerInDataStore();
59
61 m_eclClusters.registerRelationTo(m_eclTCs);
62 m_eclTCs.registerRelationTo(m_eclCalDigits);
63
67
69 m_trgmap = new TrgEclMapping();
70}
71
73{
74 // Fill a vector that can be used to map cellid -> store array position. Dont resize!
76 for (int i = 0; i < m_eclCalDigits.getEntries(); i++) {
77 m_calDigitStoreArrPosition[m_eclCalDigits[i]->getCellId()] = i;
78 }
79
80 int EventTiming = 0;
81 int RevoGDL = 0; // L1 Revo clk (Same value in an event)
82 int RevoFAM = 0; // FAM Revo clk (Same value in an event)
83 for (const auto& trgEvt : m_trgUnpackerEvtStore) {
84 EventTiming = trgEvt.getEvtTime();
85 RevoGDL = trgEvt.getL1Revo();
86 RevoFAM = trgEvt.getEvtRevo();
87 }
88
89 // Store each TC and set relations to ECLClusters
90 for (const auto& trg : m_trgUnpackerStore) {
91
92 if (trg.getTCId()<1 or trg.getTCId()>ECLTRGInformation::c_nTCs) continue;
93
94 const auto aTC = m_eclTCs.appendNew();
95
96 const unsigned idx = trg.getTCId();
97
98 aTC->setTCId(idx);
99 aTC->setFADC(trg.getTCEnergy());
100 aTC->setTiming(trg.getTCTime());
101 aTC->setEvtTiming(EventTiming);
102 aTC->setRevoGDL(RevoGDL);
103 aTC->setRevoFAM(RevoFAM);
104 aTC->setThetaId(m_trgmap->getTCThetaIdFromTCId(idx));
105 aTC->setPhiId(m_trgmap->getTCPhiIdFromTCId(idx));
106 aTC->setHitWin(trg.getHitWin());
107
108 // Fill ECLCalDigit energy sum
109 float energySum = 0.;
110 for (const auto& id : m_trgmap->getXtalIdFromTCId(idx)) {
111 // m_trgmap returns fixed size vectors with '0' to indicate empty positions -> 1-based
112 if (id > 0) {
113 const int pos = m_calDigitStoreArrPosition[id]; // id is 1-based, m_calDigitStoreArrPosition is 1-based
114 if (pos >= 0) { //not existing digits would return -1
115 energySum += m_eclCalDigits[pos]->getEnergy();
116
117 aTC->addRelationTo(m_eclCalDigits[pos]);
118 }
119 }
120 }
121
122 aTC->setECLCalDigitEnergy(energySum);
123 }
124
125 // Fill a vector that can be used to map tcid -> store array position. Dont resize!
126 memset(&m_TCStoreArrPosition[0], -1, m_TCStoreArrPosition.size() * sizeof m_TCStoreArrPosition[0]);
127 for (int i = 0; i < m_eclTCs.getEntries(); i++) {
128 m_TCStoreArrPosition[m_eclTCs[i]->getTCId()] = i;
129 if (m_eclTCs[i]->getTCId() == 0) {
130 B2ERROR(m_eclTCs[i]->getTCId() << " not possible");
131 }
132 }
133
134 // need relation for ECLClusters
135 for (const auto& cluster : m_eclClusters) {
136
137 // only photon clusters
138 if (!cluster.hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) continue;
139
140 // map TCId, energy
141 tcmap TCMap;
142
143 // loop over all digits of this cluster
144 auto relationsCalDigits = cluster.getRelationsTo<ECLCalDigit>();
145 for (unsigned int idx = 0; idx < relationsCalDigits.size(); ++idx) {
146 const auto cal = relationsCalDigits.object(idx);
147 const auto weight = relationsCalDigits.weight(idx);
148
149 auto relationsTCs = cal->getRelationsWith<ECLTriggerCell>();
150 for (unsigned int idxTC = 0; idxTC < relationsTCs.size(); ++idxTC) {
151 const auto tc = relationsTCs.object(idxTC);
152
153 const unsigned tcid = tc->getTCId();
154 TCMap[tcid] += weight * cal->getEnergy();
155 }
156 }
157
158 // set weighted relations between cluster and TC, where the weight is the energy of ECLCalDigits that belong to this shower in this TC
159 for (const auto& mapentry : TCMap) {
160 const int pos = m_TCStoreArrPosition[mapentry.first];
161 cluster.addRelationTo(m_eclTCs[pos], mapentry.second);
162 }
163 }
164
165 //energy sum
166 float sumEnergyTCECLCalDigitInECLCluster = 0.0;
167 float sumEnergyECLCalDigitInECLCluster = 0.0;
168
169 // create the dataobject
170 if (!m_eclTRGInformation) {
171 m_eclTRGInformation.create();
172 }
173
174 // get the actual TC information (energy, timing, ...)
175 float eventtiming = std::numeric_limits<float>::quiet_NaN();
176 int maxtcid = -1;
177 float maxtc = -1;
178
179 for (const auto& trg : m_trgUnpackerStore) {
180 const int tcid = trg.getTCId();
181 if (tcid<1 or tcid>ECLTRGInformation::c_nTCs) continue;
182
183 if (trg.getTCEnergy() > maxtc) {
184 maxtc = trg.getTCEnergy();
185 maxtcid = tcid;
186 }
187
188 m_eclTRGInformation->setEnergyTC(tcid, trg.getTCEnergy());
189 m_eclTRGInformation->setTimingTC(tcid, trg.getTCTime());
190 m_eclTRGInformation->setRevoGDLTC(tcid, RevoGDL);
191 m_eclTRGInformation->setRevoFAMTC(tcid, RevoFAM);
192 m_eclTRGInformation->setHitWinTC(tcid, trg.getHitWin());
193
194 if (trg.getTCEnergy() > 0 and std::isnan(eventtiming)) {
195 eventtiming = EventTiming;
196 }
197
198 B2DEBUG(29, "TC Id: (1.." << ECLTRGInformation::c_nTCs << ") " << trg.getTCId() << " FADC=" << trg.getTCEnergy() << ", t=" <<
199 trg.getTCTime() << ", tevent=" << eventtiming);
200 }
201
202 // loop over all possible TCs and fill the 'offline' ECLCalDigit information
203 for (unsigned idx = 1; idx <= ECLTRGInformation::c_nTCs; idx++) {
204 float energyInTC = 0.;
205 float energyInTCInECLCluster = 0.;
206 float highestEnergy = -1.;
207 float time = std::numeric_limits<float>::quiet_NaN();
208
209 for (const auto& id : m_trgmap->getXtalIdFromTCId(idx)) {
210 // the mapping returns fixed size vectors with '0' to indicate empty positions
211 if (id > 0) {
212 const int pos = m_calDigitStoreArrPosition[id];
213
214 if (pos >= 0) {
215 energyInTC += m_eclCalDigits[pos]->getEnergy();
216
217 // check if that eclcaldigit is part of an ECLCluster above threshold
218 auto rel = m_eclCalDigits[pos]->getRelationsFrom<ECLCluster>();
219 for (unsigned int irel = 0; irel < rel.size(); ++irel) {
220
221 const auto cluster = rel.object(irel);
222
223 if (!cluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) continue;
224
225 const auto weight = rel.weight(irel);
226 float clusterenergy = cluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons);
227
228 B2DEBUG(28, irel << " " << clusterenergy << " " << m_clusterEnergyThreshold);
229
230 if (clusterenergy >= m_clusterEnergyThreshold) {
231 energyInTCInECLCluster += weight * m_eclCalDigits[pos]->getEnergy();
232 }
233 }
234
235 // get the highest energy caldigit for the approximate timing
236 if (m_eclCalDigits[pos]->getEnergy() > highestEnergy) {
237 highestEnergy = m_eclCalDigits[pos]->getEnergy();
238 time = m_eclCalDigits[pos]->getTime();
239 }
240 }
241 }
242 }
243
244 // only add this to the total sum if the TC is read out and within trigger acceptance
245 if (m_eclTRGInformation->getEnergyTC(idx)) {
246 B2DEBUG(28, energyInTCInECLCluster << " " << m_trgmap->getTCThetaIdFromTCId(idx));
247 }
248
249 if (m_trgmap->getTCThetaIdFromTCId(idx) >= 2 and
250 m_trgmap->getTCThetaIdFromTCId(idx) <= 15) {
251 if (m_eclTRGInformation->getEnergyTC(idx)) sumEnergyTCECLCalDigitInECLCluster += energyInTCInECLCluster;
252 sumEnergyECLCalDigitInECLCluster += energyInTCInECLCluster;
253 }
254
255 m_eclTRGInformation->setEnergyTCECLCalDigit(idx, energyInTC);
256 m_eclTRGInformation->setTimingTCECLCalDigit(idx, time);
257
258 m_eclTRGInformation->setThetaIdTC(idx, m_trgmap->getTCThetaIdFromTCId(idx));
259 m_eclTRGInformation->setPhiIdTC(idx, m_trgmap->getTCPhiIdFromTCId(idx));
260
261 if (energyInTC > 0) B2DEBUG(29, "ECLCalDigits TC Id: (1.." << ECLTRGInformation::c_nTCs << ") " << idx << " E=" << energyInTC <<
262 ", t=" << time);
263
264 }
265
266 m_eclTRGInformation->setClusterEnergyThreshold(m_clusterEnergyThreshold);
267 m_eclTRGInformation->setSumEnergyTCECLCalDigitInECLCluster(sumEnergyTCECLCalDigitInECLCluster);
268 m_eclTRGInformation->setSumEnergyECLCalDigitInECLCluster(sumEnergyECLCalDigitInECLCluster);
269 m_eclTRGInformation->setEvtTiming(eventtiming);
270 m_eclTRGInformation->setMaximumTCId(maxtcid);
271
272 //flag highest energy TC
273 if (maxtcid >= 0) {
274 int pos = m_TCStoreArrPosition[maxtcid];
275 m_eclTCs[pos]->setIsHighestFADC(true);
276 }
277
278}
279
281{
282 if (m_trgmap) delete m_trgmap;
283}
Class to store calibrated ECLDigits: ECLCalDigits.
Definition: ECLCalDigit.h:23
ECL cluster data.
Definition: ECLCluster.h:27
@ c_nPhotons
CR is split into n photons (N1)
StoreObjPtr< ECLTRGInformation > m_eclTRGInformation
Analysis level information per event holding TRG information.
virtual void initialize() override
initialize
ECLTRGInformationModule()
Constructor: Sets the description, the properties and the parameters of the module.
virtual void event() override
event
std::vector< int > m_TCStoreArrPosition
vector (576+1 entries) with TC id to store array positions
virtual void terminate() override
terminate
std::vector< int > m_calDigitStoreArrPosition
vector (ECLElementNumbers::c_NCrystals + 1 entries) with cell id to store array positions
std::map< unsigned, float > tcmap
map TCId, energy
StoreArray< TRGECLUnpackerStore > m_trgUnpackerStore
Required input array of TRGECLUnpackerStore
StoreArray< ECLCluster > m_eclClusters
Required input array of ECLClusters
TrgEclMapping * m_trgmap
TC mapping class.
StoreArray< ECLCalDigit > m_eclCalDigits
Required input array of ECLCalDigits
double m_clusterEnergyThreshold
threshold for eclcluster energy sum
StoreArray< ECLTriggerCell > m_eclTCs
Output array of ECLTCs
StoreArray< TRGECLUnpackerEvtStore > m_trgUnpackerEvtStore
Required input array of TRGECLUnpackerEvtStore
Class to store information about ECL trigger cells (TCs)
static constexpr int c_nTCs
Number of TCs.
ECL Trigger cells.
unsigned int getTCId() const
Get m_TCId.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
A class of TC Mapping.
Definition: TrgEclMapping.h:26
int getTCThetaIdFromTCId(int)
get [TC Theta ID] from [TC ID]
std::vector< int > getXtalIdFromTCId(int)
get [Xtal ID] from [TC ID] (Output as a vector)
int getTCPhiIdFromTCId(int)
get [TC Phi ID] from [TC ID]
static const double MeV
[megaelectronvolt]
Definition: Unit.h:114
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.
STL namespace.