10#include <ecl/modules/eclCosmicECollector/eclCosmicECollectorModule.h>
13#include <ecl/dataobjects/ECLDigit.h>
14#include <ecl/dataobjects/ECLElementNumbers.h>
15#include <ecl/dbobjects/ECLCrystalCalib.h>
16#include <ecl/geometry/ECLGeometryPar.h>
17#include <ecl/geometry/ECLNeighbours.h>
20#include <framework/dataobjects/EventMetaData.h>
21#include <trg/ecl/TrgEclMapping.h>
43 m_ECLExpCosmicEDifferent(
"ECLExpCosmicEDifferent"), m_ElectronicsCalib(
"ECLCrystalElectronics"),
44 m_CosmicECalib(
"ECLCrystalEnergyCosmic")
47 setDescription(
"Calibration Collector Module for ECL single crystal energy calibration using cosmic rays");
49 addParam(
"minCrysE",
m_minCrysE,
"Minimum energy in GeV for a crystal to be considered hit", 0.010);
50 addParam(
"mockupL1",
m_mockupL1,
"Calculate energy per trigger cell in lieu of trigger simulation",
false);
51 addParam(
"trigThreshold",
m_trigThreshold,
"Minimum energy in GeV per trigger cell to mock up L1 trigger", 0.1);
66 auto EnvsCrysSameRing =
new TH2F(
"EnvsCrysSameRing",
"Normalized energy vs crystal ID, same theta ring;crystal ID;E/Expected",
69 registerObject<TH2F>(
"EnvsCrysSameRing", EnvsCrysSameRing);
71 auto EnvsCrysDifferentRing =
new TH2F(
"EnvsCrysDifferentRing",
74 registerObject<TH2F>(
"EnvsCrysDifferentRing", EnvsCrysDifferentRing);
76 auto ExpEvsCrysSameRing =
new TH1F(
"ExpEvsCrysSameRing",
79 registerObject<TH1F>(
"ExpEvsCrysSameRing", ExpEvsCrysSameRing);
81 auto ExpEvsCrysDifferentRing =
new TH1F(
"ExpEvsCrysDifferentRing",
84 registerObject<TH1F>(
"ExpEvsCrysDifferentRing", ExpEvsCrysDifferentRing);
86 auto ElecCalibvsCrysSameRing =
new TH1F(
"ElecCalibvsCrysSameRing",
89 registerObject<TH1F>(
"ElecCalibvsCrysSameRing", ElecCalibvsCrysSameRing);
91 auto ElecCalibvsCrysDifferentRing =
new TH1F(
"ElecCalibvsCrysDifferentRing",
94 registerObject<TH1F>(
"ElecCalibvsCrysDifferentRing", ElecCalibvsCrysDifferentRing);
96 auto InitialCalibvsCrysSameRing =
new TH1F(
"InitialCalibvsCrysSameRing",
99 registerObject<TH1F>(
"InitialCalibvsCrysSameRing", InitialCalibvsCrysSameRing);
101 auto InitialCalibvsCrysDifferentRing =
new TH1F(
"InitialCalibvsCrysDifferentRing",
104 registerObject<TH1F>(
"InitialCalibvsCrysDifferentRing", InitialCalibvsCrysDifferentRing);
106 auto CalibEntriesvsCrysSameRing =
new TH1F(
"CalibEntriesvsCrysSameRing",
109 registerObject<TH1F>(
"CalibEntriesvsCrysSameRing", CalibEntriesvsCrysSameRing);
111 auto CalibEntriesvsCrysDifferentRing =
new TH1F(
"CalibEntriesvsCrysDifferentRing",
114 registerObject<TH1F>(
"CalibEntriesvsCrysDifferentRing", CalibEntriesvsCrysDifferentRing);
116 auto RawDigitAmpvsCrys =
new TH2F(
"RawDigitAmpvsCrys",
"Digit Amplitude vs crystal ID;crystal ID;Amplitude",
119 registerObject<TH2F>(
"RawDigitAmpvsCrys", RawDigitAmpvsCrys);
123 B2INFO(
"Input parameters to eclCosmicECollector:");
143 for (
int ic = 1; ic < 9000; ic += 1000) {
144 B2INFO(
"DB constants for cellID=" << ic <<
": ExpCosmicESame = " <<
ExpCosmicESame[ic - 1] <<
" ExpCosmicEDifferent = " <<
151 if (
ExpCosmicESame[ic] == 0) {B2FATAL(
"eclCosmicECollector: ExpCosmicESame = 0 for crysID = " << ic);}
152 if (
ExpCosmicEDifferent[ic] == 0) {B2FATAL(
"eclCosmicECollector: ExpCosmicEDifferent = 0 for crysID = " << ic);}
153 if (
CosmicECalib[ic] == 0) {B2FATAL(
"eclCosmicECollector: CosmicECalib = 0 for crysID = " << ic);}
160 const short m_crystalsPerRing[69] = {
161 48, 48, 64, 64, 64, 96, 96, 96, 96, 96, 96, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 96, 96, 96, 96, 96, 64, 64, 64
165 short firstCrystal[69] = {};
166 for (
int it = 1; it < 69; it++) {firstCrystal[it] = firstCrystal[it - 1] + m_crystalsPerRing[it - 1];}
172 for (
int it = 0; it < 69; it++) {
173 for (
int ic = 0; ic < m_crystalsPerRing[it]; ic++) {
174 ThetaIDCrys.at(cID) = it;
175 PhiIDCrys.at(cID) = ic;
193 double n2Overn0 = (double)m_crystalsPerRing[ThetaID + 2] / (
double)m_crystalsPerRing[ThetaID];
194 for (
int phiID = 0; phiID < m_crystalsPerRing[ThetaID]; phiID++) {
195 int crysID = firstCrystal[ThetaID] + phiID;
198 int phiIDA = phiID + 1;
199 if (phiIDA == m_crystalsPerRing[ThetaID]) {phiIDA = 0;}
200 int phiIDB = phiID - 1;
201 if (phiIDB == -1) {phiIDB = m_crystalsPerRing[ThetaID] - 1;}
204 NeighbourA.push_back(firstCrystal[ThetaID] + phiIDA);
205 NeighbourB.push_back(firstCrystal[ThetaID] + phiIDB);
208 double dphiB = n2Overn0 * phiID + 0.0001;
211 NeighbourA.push_back(firstCrystal[ThetaID + 1] + phiID);
212 NeighbourB.push_back(firstCrystal[ThetaID + 2] + phiIDB);
216 NeighbourA.push_back(firstCrystal[ThetaID + 1] + phiID);
217 NeighbourB.push_back(firstCrystal[ThetaID + 2] + phiIDB);
226 for (
int crysID = firstCrystal[1]; crysID < firstCrystal[68]; crysID++) {
227 std::vector<short int> neighbours = myNeighbours4->
getNeighbours(crysID + 1);
232 std::vector<short int> nextThetaNeighbours;
233 std::vector<short int> previousThetaNeighbours;
234 for (
auto& ID1 : neighbours) {
236 if (temp0 != crysID && ThetaIDCrys[temp0] == ThetaIDCrys[crysID] && nA == -1) {
238 }
else if (temp0 != crysID && ThetaIDCrys[temp0] == ThetaIDCrys[crysID] && nA != -1) {
243 if (ThetaIDCrys[temp0] == ThetaIDCrys[crysID] + 1) {nextThetaNeighbours.push_back(temp0);}
244 if (ThetaIDCrys[temp0] == ThetaIDCrys[crysID] - 1) {previousThetaNeighbours.push_back(temp0);}
248 if (nA >= 0 && nB >= 0) {
254 B2FATAL(
"No neighbour pair with the same thetaID for crysID = " << crysID);
258 for (
auto& IDn : nextThetaNeighbours) {
259 for (
auto& IDp : previousThetaNeighbours) {
271 for (
int phiID = 0; phiID < m_crystalsPerRing[ThetaID]; phiID++) {
272 int crysID = firstCrystal[ThetaID] + phiID;
275 int phiIDA = phiID + 1;
276 if (phiIDA == m_crystalsPerRing[ThetaID]) {phiIDA = 0;}
277 int phiIDB = phiID - 1;
278 if (phiIDB == -1) {phiIDB = m_crystalsPerRing[ThetaID] - 1;}
281 NeighbourA.push_back(firstCrystal[ThetaID] + phiIDA);
282 NeighbourB.push_back(firstCrystal[ThetaID] + phiIDB);
286 NeighbourA.push_back(firstCrystal[ThetaID - 1] + phiID);
287 NeighbourB.push_back(firstCrystal[ThetaID - 2] + phiID);
304 getObjectPtr<TH1F>(
"ExpEvsCrysSameRing")->Fill(crysID + 0.001,
ExpCosmicESame[crysID]);
305 getObjectPtr<TH1F>(
"ElecCalibvsCrysSameRing")->Fill(crysID + 0.001,
ElectronicsCalib[crysID]);
306 getObjectPtr<TH1F>(
"InitialCalibvsCrysSameRing")->Fill(crysID + 0.001,
CosmicECalib[crysID]);
307 getObjectPtr<TH1F>(
"CalibEntriesvsCrysSameRing")->Fill(crysID + 0.001);
309 getObjectPtr<TH1F>(
"ExpEvsCrysDifferentRing")->Fill(crysID + 0.001,
ExpCosmicEDifferent[crysID]);
310 getObjectPtr<TH1F>(
"ElecCalibvsCrysDifferentRing")->Fill(crysID + 0.001,
ElectronicsCalib[crysID]);
311 getObjectPtr<TH1F>(
"InitialCalibvsCrysDifferentRing")->Fill(crysID + 0.001,
CosmicECalib[crysID]);
312 getObjectPtr<TH1F>(
"CalibEntriesvsCrysDifferentRing")->Fill(crysID + 0.001);
319 if (
iEvent % 10000 == 0) {B2INFO(
"eclCosmicECollector: iEvent = " <<
iEvent);}
322 if (
m_ECLExpCosmicESame.hasChanged()) {B2FATAL(
"eclCosmicECollector: ECLExpCosmicESame has changed");}
324 if (
m_ElectronicsCalib.hasChanged()) {B2FATAL(
"eclCosmicECollector: ElectronicsCalib has changed");}
326 B2DEBUG(9,
"eclCosmicECollector: new values for ECLCosmicECalib");
337 int crysID = eclDigit.getCellId() - 1;
342 getObjectPtr<TH2F>(
"RawDigitAmpvsCrys")->Fill(crysID + 0.001, eclDigit.getAmp());
350 for (
int tc = 0; tc < 576; tc++) {
354 if (!ECLtrigger) {
return;}
365 getObjectPtr<TH2F>(
"EnvsCrysSameRing")->Fill(crysID + 0.001,
EperCrys[crysID] / abs(
ExpCosmicESame[crysID]));
366 getObjectPtr<TH1F>(
"ExpEvsCrysSameRing")->Fill(crysID + 0.001,
ExpCosmicESame[crysID]);
367 getObjectPtr<TH1F>(
"ElecCalibvsCrysSameRing")->Fill(crysID + 0.001,
ElectronicsCalib[crysID]);
368 getObjectPtr<TH1F>(
"InitialCalibvsCrysSameRing")->Fill(crysID + 0.001,
CosmicECalib[crysID]);
369 getObjectPtr<TH1F>(
"CalibEntriesvsCrysSameRing")->Fill(crysID + 0.001);
372 getObjectPtr<TH1F>(
"ExpEvsCrysDifferentRing")->Fill(crysID + 0.001,
ExpCosmicEDifferent[crysID]);
373 getObjectPtr<TH1F>(
"ElecCalibvsCrysDifferentRing")->Fill(crysID + 0.001,
ElectronicsCalib[crysID]);
374 getObjectPtr<TH1F>(
"InitialCalibvsCrysDifferentRing")->Fill(crysID + 0.001,
CosmicECalib[crysID]);
375 getObjectPtr<TH1F>(
"CalibEntriesvsCrysDifferentRing")->Fill(crysID + 0.001);
Calibration collector module base class.
Class to get the neighbours for a given cell id.
const std::vector< short int > & getNeighbours(short int cid) const
Return the neighbours for a given cell ID.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
int getTCIdFromXtalId(int)
get [TC ID] from [Xtal ID]
DBObjPtr< ECLCrystalCalib > m_ECLExpCosmicEDifferent
Expected energies from database; neighbours in different ThetaID rings.
DBObjPtr< ECLCrystalCalib > m_CosmicECalib
Existing single crystal calibration from DB; will be updated by CAF.
eclCosmicECollectorModule()
Constructor.
std::vector< float > CosmicECalib
vector obtained from DB object
std::vector< int > FirstSet
First set of 3 crystals for each crystalID.
StoreArray< ECLDigit > m_eclDigitArray
Required input array of eclDigits.
std::vector< float > EnergyPerTC
Energy (GeV) per trigger cell.
std::vector< float > EperCrys
Energy related.
void collect() override
collect.
StoreObjPtr< EventMetaData > m_evtMetaData
Store array: EventMetaData.
std::vector< float > ElectronicsCalib
vector obtained from DB object
bool m_mockupL1
Calculate energy per trigger cell in lieu of trigger simulation (false)
std::vector< float > ExpCosmicEDifferent
vector obtained from DB object
void prepare() override
prepare.
std::vector< bool > HitCrys
true if energy>m_minCrysE
DBObjPtr< ECLCrystalCalib > m_ECLExpCosmicESame
Expected energies from database; neighbours in the same ThetaID ring.
std::vector< short int > NeighbourA
if this crystal is > threshold
DBObjPtr< ECLCrystalCalib > m_ElectronicsCalib
Electronics calibration from database.
std::vector< short int > NeighbourB
and this crystal is > threshold
std::vector< float > ExpCosmicESame
vector obtained from DB object
double m_trigThreshold
Minimum energy in trigger cell, if required (0.1 GeV)
double m_minCrysE
Parameters to control the job.
std::vector< short int > TCperCrys
Trigger.
std::vector< short int > CenterCrys
Sets of three crystals that define a useful cosmic.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.