10#include <ecl/modules/eclee5x5Collector/eclee5x5CollectorModule.h>
13#include <ecl/dataobjects/ECLCalDigit.h>
14#include <ecl/dataobjects/ECLDigit.h>
15#include <ecl/dataobjects/ECLElementNumbers.h>
16#include <ecl/dbobjects/ECLCrystalCalib.h>
19#include <analysis/ClusterUtility/ClusterUtils.h>
20#include <framework/dataobjects/EventMetaData.h>
21#include <framework/datastore/RelationVector.h>
22#include <framework/geometry/VectorUtil.h>
23#include <mdst/dataobjects/ECLCluster.h>
24#include <mdst/dataobjects/TRGSummary.h>
27#include <Math/Vector3D.h>
28#include <Math/Vector4D.h>
47 m_ECLExpee5x5E(
"ECLExpee5x5E"), m_ElectronicsCalib(
"ECLCrystalElectronics"), m_ee5x5Calib(
"ECLCrystalEnergyee5x5"),
48 m_selectdPhiData(
"ECLeedPhiData"), m_selectdPhiMC(
"ECLeedPhiMC")
51 setDescription(
"Calibration Collector Module for ECL single crystal energy calibration using Bhabha events");
55 addParam(
"minE0",
m_minE0,
"minimum energy of cluster 0: E*0/sqrts", 0.45);
56 addParam(
"minE1",
m_minE1,
"minimum energy of cluster 1: E*1/sqrts", 0.40);
57 addParam(
"maxdThetaSum",
m_maxdThetaSum,
"maximum diff between 180 deg and sum of cluster theta* (deg)", 2.);
74 B2INFO(
"eclee5x5Collector: Experiment = " <<
m_evtMetaData->getExperiment() <<
" run = " <<
m_evtMetaData->getRun() <<
" sqrts = "
80 auto EnVsCrysID =
new TH2F(
"EnVsCrysID",
"Normalized 5x5 energy for each crystal;crystal ID;E25/Expected",
83 registerObject<TH2F>(
"EnVsCrysID", EnVsCrysID);
85 auto RvsCrysID =
new TH1F(
"RvsCrysID",
"E_exp x E_crysID / sigma^2;crysID;sum of E_exp x E_crysID/sigma^2",
89 auto NRvsCrysID =
new TH1F(
"NRvsCrysID",
"Entries in RvsCrysID vs crysID;crysID;Entries in RvsCrysID",
98 auto ElecCalibvsCrys =
new TH1F(
"ElecCalibvsCrys",
"Sum electronics calib const vs crystal ID;crystal ID;calibration constant",
100 registerObject<TH1F>(
"ElecCalibvsCrys", ElecCalibvsCrys);
101 auto ExpEvsCrys =
new TH1F(
"ExpEvsCrys",
"Sum expected energy calib const vs crystalID;crystal ID;calibration constant",
104 registerObject<TH1F>(
"ExpEvsCrys", ExpEvsCrys);
105 auto InitialCalibvsCrys =
new TH1F(
"InitialCalibvsCrys",
"Sum initial calib const vs crystal ID;crystal ID;calibration constant",
107 registerObject<TH1F>(
"InitialCalibvsCrys", InitialCalibvsCrys);
109 auto CalibEntriesvsCrys =
new TH1F(
"CalibEntriesvsCrys",
"Entries in calib vs crys histograms;crystal ID;Entries per crystal",
112 registerObject<TH1F>(
"CalibEntriesvsCrys", CalibEntriesvsCrys);
114 auto EntriesvsCrys =
new TH1F(
"EntriesvsCrys",
"Selected Bhabha clusters vs crystal ID;crystal ID;Entries",
116 registerObject<TH1F>(
"EntriesvsCrys", EntriesvsCrys);
118 auto dPhivsThetaID =
new TH2F(
"dPhivsThetaID",
119 "Phi* vs thetaID forward, pass thetaSum,E0,E1;thetaID of forward cluster;dPhi COM (deg)", 69, 0, 69, 150, 165, 180);
120 registerObject<TH2F>(
"dPhivsThetaID", dPhivsThetaID);
124 B2INFO(
"Input parameters to eclee5x5Collector:");
162 for (
int ic = 1; ic < 9000; ic += 1000) {
163 B2INFO(
"DB constants for cellID=" << ic <<
": ee5x5Calib = " <<
ee5x5Calib[ic - 1] <<
" Expee5x5E = " <<
Expee5x5E[ic - 1] <<
164 " ElectronicsCalib = " <<
171 if (
Expee5x5E[crysID] == 0) {B2FATAL(
"eclee5x5Collector: Expee5x5E = 0 for crysID = " << crysID);}
172 if (
ee5x5Calib[crysID] == 0) {B2FATAL(
"eclee5x5Collector: ee5x5Calib = 0 for crysID = " << crysID);}
185 for (
int it = 0; it < 69; it++) {
207 getObjectPtr<TH1F>(
"ExpEvsCrys")->Fill(crysID + 0.001,
Expee5x5E[crysID]);
208 getObjectPtr<TH1F>(
"ElecCalibvsCrys")->Fill(crysID + 0.001,
ElectronicsCalib[crysID]);
209 getObjectPtr<TH1F>(
"InitialCalibvsCrys")->Fill(crysID + 0.001,
ee5x5Calib[crysID]);
210 getObjectPtr<TH1F>(
"CalibEntriesvsCrys")->Fill(crysID + 0.001);
217 bool newConst =
false;
226 B2INFO(
"ECLCrystalElectronics has changed, exp = " <<
m_evtMetaData->getExperiment() <<
" run = " <<
m_evtMetaData->getRun());
231 B2INFO(
"ECLCrystalEnergyee5x5 has changed, exp = " <<
m_evtMetaData->getExperiment() <<
" run = " <<
m_evtMetaData->getRun());
236 for (
int ic = 1; ic < 9000; ic += 1000) {
237 B2INFO(
"DB constants for cellID=" << ic <<
": ee5x5Calib = " <<
ee5x5Calib[ic - 1] <<
" Expee5x5E = " <<
Expee5x5E[ic - 1] <<
238 " ElectronicsCalib = " <<
245 if (
Expee5x5E[crysID] == 0) {B2FATAL(
"eclee5x5Collector: Expee5x5E = 0 for crysID = " << crysID);}
246 if (
ee5x5Calib[crysID] == 0) {B2FATAL(
"eclee5x5Collector: ee5x5Calib = 0 for crysID = " << crysID);}
253 unsigned int L1TriggerResults =
m_TRGResults->getTRGSummary(0);
254 if (L1TriggerResults == 0) {
return;}
259 int icMax[2] = { -1, -1};
260 double maxClustE[2] = { -1., -1.};
262 for (
int ic = 0; ic < nclust; ic++) {
265 if (eClust > maxClustE[0]) {
266 maxClustE[1] = maxClustE[0];
268 maxClustE[0] = eClust;
270 }
else if (eClust > maxClustE[1]) {
271 maxClustE[1] = eClust;
280 if (icMax[1] == -1) {
return;}
290 double dt99min = dt990;
291 if (dt991 < dt990) {dt99min = dt991;}
292 if (dt99min <= 0) {dt99min = 0.0001;}
293 if (abs(t1 - t0) > dt99min *
m_maxTime) {
return;}
298 const ROOT::Math::XYZVector clustervertex = cUtil.
GetIPPosition();
301 ROOT::Math::XYZVector p30;
302 VectorUtil::setMagThetaPhi(p30, maxClustE[0], theta0, phi0);
307 ROOT::Math::XYZVector p31;
308 VectorUtil::setMagThetaPhi(p31, maxClustE[1], theta1, phi1);
315 double theta01COM = (p41COM.Theta() + p40COM.Theta()) * TMath::RadToDeg();
325 int crysIDMax[2] = { -1, -1};
326 double crysEMax[2] = { -1., -1.};
327 for (
int imax = 0; imax < 2; imax++) {
329 for (
unsigned int ir = 0; ir < eclClusterRelations.size(); ir++) {
330 const auto calDigit = eclClusterRelations.object(ir);
331 int tempCrysID = calDigit->
getCellId() - 1;
332 float tempE = calDigit->getEnergy();
333 if (tempE > crysEMax[imax]) {
334 crysEMax[imax] = tempE;
335 crysIDMax[imax] = tempCrysID;
341 double dphiCOM = abs(p41COM.Phi() - p40COM.Phi()) * TMath::RadToDeg();
342 if (dphiCOM > 180.) {dphiCOM = 360. - dphiCOM;}
344 int thetaIDmin =
m_thetaID[crysIDMax[0]];
346 getObjectPtr<TH2F>(
"dPhivsThetaID")->Fill(thetaIDmin + 0.001, dphiCOM);
356 int tempCrysID = eclCalDigit.getCellId() - 1;
357 EperCrys[tempCrysID] = eclCalDigit.getEnergy();
361 int tempCrysID = eclDigit.getCellId() - 1;
369 for (
int ic = 0; ic < 2; ic++) {
370 int crysMax = crysIDMax[ic];
376 double reducedExpE = expE;
378 for (
auto& cellID : neighbours) {
381 reducedExpE -=
EperCrys[cellID - 1];
386 double rexpE = reducedExpE / sigmaExp;
387 for (
auto& celli : neighbours) {
389 float rEi =
EperCrys[celli - 1] / sigmaExp;
390 getObjectPtr<TH1F>(
"RvsCrysID")->Fill(celli - 0.999, rexpE * rEi);
391 getObjectPtr<TH1F>(
"NRvsCrysID")->Fill(celli - 0.999);
392 for (
auto& cellj : neighbours) {
394 float rEj =
EperCrys[cellj - 1] / sigmaExp;
395 getObjectPtr<TH2F>(
"Qmatrix")->Fill(celli - 0.999, cellj - 0.999, rEi * rEj);
402 getObjectPtr<TH2F>(
"EnVsCrysID")->Fill(crysMax + 0.001, E25 / expE);
403 getObjectPtr<TH1F>(
"EntriesvsCrys")->Fill(crysMax + 0.001);
404 getObjectPtr<TH1F>(
"ExpEvsCrys")->Fill(crysMax + 0.001,
Expee5x5E[crysMax]);
405 getObjectPtr<TH1F>(
"ElecCalibvsCrys")->Fill(crysMax + 0.001,
ElectronicsCalib[crysMax]);
406 getObjectPtr<TH1F>(
"InitialCalibvsCrys")->Fill(crysMax + 0.001,
ee5x5Calib[crysMax]);
407 getObjectPtr<TH1F>(
"CalibEntriesvsCrys")->Fill(crysMax + 0.001);
Calibration collector module base class.
void registerObject(std::string name, T *obj)
Register object with a name, takes ownership, do not access the pointer beyond prepare()
Class to provide momentum-related information from ECLClusters.
const ROOT::Math::PxPyPzEVector Get4MomentumFromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns four momentum vector.
const ROOT::Math::XYZVector GetIPPosition()
Returns default IP position from beam parameters.
Class to store calibrated ECLDigits: ECLCalDigits.
int getCellId() const
Get Cell ID.
@ c_nPhotons
CR is split into n photons (N1)
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.
short int getCrystalsPerRing(const short int thetaid) const
return number of crystals in a given theta ring
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...
DBObjPtr< ECLCrystalCalib > m_selectdPhiData
dPhi cut
StoreArray< ECLDigit > m_eclDigitArray
Required input array of ECLDigits.
std::vector< float > widthdPhi
width of requirement on dPhi from DB object
std::vector< float > Expee5x5E
vector of energies obtained from DB object
bool m_requireL1
require events to satisfy a level 1 trigger (false)
DBObjPtr< ECLCrystalCalib > m_ECLExpee5x5E
Expected energies from database.
double m_maxTime
maximum cluster time diff abs(t1-t0)/dt99 (10)
eclee5x5CollectorModule()
Constructor: Sets the description, the properties and the parameters of the module.
double m_maxdThetaSum
abs(theta0* + theta1* - 180 deg) must be less than less (2 deg)
StoreArray< ECLCluster > m_eclClusterArray
Required arrays.
StoreObjPtr< TRGSummary > m_TRGResults
dataStore TRGSummary
bool storeCalib
force the input calibration constants to be saved first event
double m_minE0
minimum energy of cluster 0: E*0/sqrts (0.45)
std::vector< float > EperCrys
Energy for each crystal from ECLDigit or ECLCalDigit (GeV)
std::vector< int > m_thetaID
thetaID of each crystal
ECL::ECLNeighbours * m_eclNeighbours5x5
Neighbour map of 25 crystals.
bool m_useCalDigits
use eclCalDigit to determine MC deposited energy (false)
std::vector< float > Expee5x5Sigma
vector of sigmaE obtained from DB object
std::vector< float > m_dPhiMin
minimum dPhi* as a function of thetaID
std::vector< float > m_dPhiMax
maximum dPhi* as a function of thetaID
void collect() override
Select events and crystals and accumulate histograms.
StoreObjPtr< EventMetaData > m_evtMetaData
dataStore EventMetaData
std::vector< float > ElectronicsCalib
vector obtained from DB object
StoreArray< ECLCalDigit > m_eclCalDigitArray
Required input array of ECLCalDigits.
double m_thetaLabMax
m_thetaLabMaxDeg converted to radians
std::vector< float > meandPhi
mean requirement on dPhi from DB object
double m_sqrts
sqrt s from m_boostrotate
void prepare() override
Define histograms and read payloads from DB.
std::vector< float > ee5x5Calib
vector obtained from DB object
double m_thetaLabMin
Some other useful quantities.
DBObjPtr< ECLCrystalCalib > m_selectdPhiMC
DB object for MC.
double m_thetaLabMaxDeg
maximum ecl cluster theta in lab (150 degrees)
DBObjPtr< ECLCrystalCalib > m_ee5x5Calib
Existing single crystal calibration from DB; will be updated by CAF.
double m_thetaLabMinDeg
Parameters to control the job.
PCmsLabTransform m_boostrotate
boost from COM to lab and visa versa
double m_dPhiScale
scale dPhi* cut by this factor (1)
double m_minE1
minimum energy of cluster 1: E*1/sqrts (0.40)
DBObjPtr< ECLCrystalCalib > m_ElectronicsCalib
Electronics calibration from database.
double m_expectedEnergyScale
scale expected energies for non-4S calibration (1.)
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.