Belle II Software development
ElectronValCollectorModule.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#include <cdc/modules/CDCDedxValidationCollector/ElectronValCollectorModule.h>
10
11#include <mdst/dataobjects/EventLevelTriggerTimeInfo.h>
12#include <mdst/dataobjects/ECLCluster.h>
13#include <framework/dataobjects/EventMetaData.h>
14
15#include <TTree.h>
16#include <TH1D.h>
17#include <TH1I.h>
18#include <TMath.h>
19
20using namespace Belle2;
21//-----------------------------------------------------------------
22// Register the Module
23//-----------------------------------------------------------------
24REG_MODULE(ElectronValCollector);
25
26//-----------------------------------------------------------------
27// Implementation
28//-----------------------------------------------------------------
30{
31 // Set module properties
32 setDescription("A collector module for CDC dE/dx validation");
33
34 // Parameter definitions
35 addParam("cleanupCuts", m_cuts, "boolean to apply cleanup cuts", true);
36 addParam("maxHits", m_maxHits, "maximum number of hits per track ", int(100));
37 addParam("setEoP", m_setEoP, "Set E over p Cut values. ", double(0.25));
38}
39
40//-----------------------------------------------------------------
41// Create ROOT objects
42//-----------------------------------------------------------------
43
45{
46 m_trgResult.isOptional();
47 m_dedxTracks.isRequired();
48 m_tracks.isRequired();
49 m_trackFitResults.isRequired();
50
51 // Data object creation
52 auto means = new TH1D("means", "CDC dE/dx truncated means", 250, 0, 2.5);
53
54 auto tBhabha = new TTree("tBhabha", "Tree with dE/dx information for electrons");
55 auto tRadee = new TTree("tRadee", "Tree with dE/dx information for radiative electrons");
56
57 auto hestats = new TH1I("hestats", "Event Stats", 8, -0.5, 7.5);
58 hestats->SetFillColor(kYellow);
59 hestats->GetXaxis()->SetBinLabel(1, "all");
60 hestats->GetXaxis()->SetBinLabel(2, "notrig");
61 hestats->GetXaxis()->SetBinLabel(3, "noskim");
62 hestats->GetXaxis()->SetBinLabel(4, "bhabha");
63 hestats->GetXaxis()->SetBinLabel(5, "radee");
64 hestats->GetXaxis()->SetBinLabel(6, "wrong skim");
65 hestats->GetXaxis()->SetBinLabel(7, "unclean");
66 hestats->GetXaxis()->SetBinLabel(8, "selected");
67
68 auto htstats = new TH1I("htstats", "track Stats", 7, -0.5, 6.5);
69 htstats->SetFillColor(kYellow);
70 htstats->GetXaxis()->SetBinLabel(1, "alltrk");
71 htstats->GetXaxis()->SetBinLabel(2, "vtx");
72 htstats->GetXaxis()->SetBinLabel(3, "inCDC");
73 htstats->GetXaxis()->SetBinLabel(4, "whits");
74 htstats->GetXaxis()->SetBinLabel(5, "weop");
75 htstats->GetXaxis()->SetBinLabel(6, "radee");
76 htstats->GetXaxis()->SetBinLabel(7, "selected");
77
78 tRadee->Branch<double>("injtime", &m_injTime);
79 tRadee->Branch<double>("injring", &m_injRing);
80 tRadee->Branch<double>("costh", &m_costh);
81 tRadee->Branch<int>("charge", &m_charge);
82 tRadee->Branch<int>("run", &m_run);
83 tRadee->Branch<double>("p", &m_p);
84 tRadee->Branch<double>("pt", &m_pt);
85 tRadee->Branch<double>("dedx", &m_dedx);
86 tRadee->Branch("enta", &m_enta);
87 tRadee->Branch("entaRS", &m_entaRS);
88 tRadee->Branch("layer", &m_layer);
89 tRadee->Branch("dedxhit", &m_dedxhit);
90
91
92 tBhabha->Branch<double>("dedx", &m_dedx);
93 tBhabha->Branch<double>("costh", &m_costh);
94 tBhabha->Branch<double>("p", &m_p);
95 tBhabha->Branch<int>("charge", &m_charge);
96 tBhabha->Branch<int>("run", &m_run);
97 tBhabha->Branch("wire", &m_wire);
98 tBhabha->Branch("dedxhit", &m_dedxhit);
99
100 // Collector object registration
101 registerObject<TH1D>("means", means);
102 registerObject<TTree>("tRadee", tRadee);
103 registerObject<TTree>("tBhabha", tBhabha);
104
105 registerObject<TH1I>("hestats", hestats);
106 registerObject<TH1I>("htstats", htstats);
107}
108
109//-----------------------------------------------------------------
110// Fill ROOT objects
111//-----------------------------------------------------------------
113{
114
115 // Retrieve the histogram pointer
116 auto hestats = getObjectPtr<TH1I>("hestats");
117 if (!hestats) {
118 B2ERROR("Failed to retrieve histogram 'hestats'");
119 return;
120 }
121 hestats->Fill(0); // Fill the first bin to indicate processing has started
122
123 // Check if the trigger result is valid
124 if (!m_trgResult.isValid()) {
125 B2WARNING("SoftwareTriggerResult required to select bhabha/radee event is not found");
126 hestats->Fill(1); // Fill bin 2 to indicate missing trigger result
127 return;
128 }
129
130 // Retrieve the trigger results
131 const std::map<std::string, int>& fresults = m_trgResult->getResults();
132
133 // Check for the required trigger identifiers
134 if (fresults.find("software_trigger_cut&skim&accept_bhabha") == fresults.end() &&
135 fresults.find("software_trigger_cut&skim&accept_radee") == fresults.end()) {
136 B2WARNING("Can't find required bhabha/radee trigger identifiers");
137 hestats->Fill(2); // Fill bin 3 to indicate missing trigger identifiers
138 return;
139 }
140
141 // Defining event trigger conditions
142 const bool eBhabha = (m_trgResult->getResult("software_trigger_cut&skim&accept_bhabha") == SoftwareTriggerCutResult::c_accept);
143 const bool eRadBhabha = (m_trgResult->getResult("software_trigger_cut&skim&accept_radee") == SoftwareTriggerCutResult::c_accept);
144
145 // Handling different event types
146 if (eBhabha) {
147 B2INFO("Bhabha events");
148 hestats->Fill(3); // Bin 4 (index 3)
149 } else if (eRadBhabha) {
150 B2INFO("Radiative Bhabha events");
151 hestats->Fill(4); // Bin 5 (index 4)
152 } else {
153 B2WARNING("Requested event not found: going back");
154 hestats->Fill(5); // Bin 6 (index 5)
155 return; // Exiting the function if event is not found
156 }
157
158 // Ensure eventMetaDataPtr is valid
159 StoreObjPtr<EventMetaData> eventMetaDataPtr;
160 if (!eventMetaDataPtr) {
161 B2ERROR("Failed to retrieve event metadata");
162 return;
163 }
164
165 int run = eventMetaDataPtr->getRun();
166 m_run = run;
167
168 int nTracks = m_dedxTracks.getEntries();
169 if (nTracks >= 4) {
170 B2WARNING("too many tracks: unclean bhabha or radee event: " << nTracks);
171 hestats->Fill(6);
172 return;
173 }
174
175 hestats->Fill(7); // Fill bin 8 (index 7) to indicate a valid event
176
177 //Collector object access
178 auto tBhabha = getObjectPtr<TTree>("tBhabha");
179 auto tRadee = getObjectPtr<TTree>("tRadee");
180 auto htstats = getObjectPtr<TH1I>("htstats");
181 auto hmeans = getObjectPtr<TH1D>("means");
182
183 for (int idedx = 0; idedx < nTracks; idedx++) {
184
185 CDCDedxTrack* dedxTrack = m_dedxTracks[idedx];
186 if (!dedxTrack) {
187 B2WARNING("No dedx track: Going back: " << idedx);
188 continue;
189 }
190
191 const Track* track = dedxTrack->getRelatedFrom<Track>();
192 if (!track) {
193 B2WARNING("No track: Going back: " << idedx);
194 continue;
195 }
196
197 const TrackFitResult* fitResult = track->getTrackFitResultWithClosestMass(Const::pion);
198 if (!fitResult) {
199 B2WARNING("No related fit for this track...");
200 continue;
201 }
202
203 m_dedx = dedxTrack->getDedxNoSat();
204 m_p = dedxTrack->getMomentum();
205 m_costh = dedxTrack->getCosTheta();
206 m_charge = fitResult->getChargeSign();
207 m_pt = fitResult->getTransverseMomentum();
208 m_injTime = dedxTrack->getInjectionTime();
209 m_injRing = dedxTrack->getInjectionRing();
210 m_nhits = dedxTrack->size();
211
212 htstats->Fill(0);
213
214 if (m_cuts) {
215 // apply cleanup cuts
216 if (std::fabs(fitResult->getD0()) >= 1.0)continue;
217 if (std::fabs(fitResult->getZ0()) >= 1.0) continue;
218 htstats->Fill(1);
219
220 //if outside CDC
221 if (m_costh < TMath::Cos(150.0 * TMath::DegToRad()))continue; //-0.866
222 if (m_costh > TMath::Cos(17.0 * TMath::DegToRad())) continue; //0.95
223 htstats->Fill(2);
224
225 if (m_nhits > m_maxHits) continue;
226
227 //making some cuts based on acceptance
228 if (m_costh > -0.55 && m_costh < 0.820) {
229 if (dedxTrack->getNLayerHits() < 25)continue; //all CDC layer available here
230 } else {
232 if (dedxTrack->getNLayerHits() < 10)continue; //less layer available here
233 if (m_costh > 0 && dedxTrack->getNLayerHits() < 13)continue;
234 } else {
235 if (dedxTrack->getNLayerHits() < 18)continue;
236 }
237 }
238 htstats->Fill(3);
239
240 const ECLCluster* eclCluster = track->getRelated<ECLCluster>();
241 if (eclCluster and eclCluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
242 double TrkEoverP = (eclCluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons)) / (fitResult->getMomentum().R());
243 if (std::abs(TrkEoverP - 1.0) > m_setEoP)continue;
244 }
245 htstats->Fill(4);
246 }
247
248 //if dealing with radee here (do a safe side cleanup)
249 if (eRadBhabha) {
250 if (nTracks != 2)continue; //exactly 2 tracks
251 bool goodradee = false;
252 //checking if dedx of other track is restricted
253 //will not do too much as radee is clean enough
254 for (int jdedx = 0; jdedx < nTracks; jdedx++) {
255 CDCDedxTrack* dedxOtherTrack = m_dedxTracks[std::abs(jdedx - 1)];
256 if (!dedxOtherTrack)continue;
257 if (std::abs(dedxOtherTrack->getDedxNoSat() - 1.0) > 0.25)continue; //loose for uncalibrated
258 goodradee = true;
259 break;
260 }
261 if (!goodradee)continue;
262 htstats->Fill(5);
263 }
264
265 // Make sure to remove all the data in vectors from the previous track
266 m_wire.clear();
267 m_layer.clear();
268 m_dedxhit.clear();
269 m_enta.clear();
270 m_entaRS.clear();
271
272 for (int i = 0; i < m_nhits; ++i) {
273 m_wire.push_back(dedxTrack->getWire(i));
274 m_layer.push_back(dedxTrack->getHitLayer(i));
275 m_dedxhit.push_back(dedxTrack->getDedx(i));
276 m_enta.push_back(dedxTrack->getEnta(i));
277 m_entaRS.push_back(dedxTrack->getEntaRS(i));
278 }
279
280 // Track and/or hit information filled as per config
281 htstats->Fill(6);
282 hmeans->Fill(m_dedx);
283 if (eBhabha) tBhabha->Fill();
284 if (eRadBhabha) tRadee->Fill();
285 }
286}
double R
typedef autogenerated by FFTW
Debug output for CDCDedxPID module.
int getHitLayer(int i) const
Return the (global) layer number for a hit.
double getDedx() const
Get dE/dx truncated mean for this track.
double getEntaRS(int i) const
Return rescaled enta value for cell height=width assumption.
int getNLayerHits() const
Return the number of layer hits for this track.
double getCosTheta() const
Return cos(theta) for this track.
double getInjectionRing() const
Return cos(theta) for this track.
int getWire(int i) const
Return the sensor ID for this hit: wire number for CDC (0-14336)
double getEnta(int i) const
Return the entrance angle in the CDC cell for this hit.
double getInjectionTime() const
Return cos(theta) for this track.
double getDedxNoSat() const
Get dE/dx truncated mean without the saturation correction for this track.
int size() const
Return the number of hits for this track.
double getMomentum() const
Return the track momentum valid in the CDC.
void registerObject(std::string name, T *obj)
Register object with a name, takes ownership, do not access the pointer beyond prepare()
CalibrationCollectorModule()
Constructor. Sets the default prefix for calibration dataobjects.
T * getObjectPtr(std::string name)
Calls the CalibObjManager to get the requested stored collector data.
static const ChargedStable pion
charged pion particle
Definition Const.h:661
ECL cluster data.
Definition ECLCluster.h:27
bool hasHypothesis(EHypothesisBit bitmask) const
Return if specific hypothesis bit is set.
Definition ECLCluster.h:351
double getEnergy(EHypothesisBit hypothesis) const
Return Energy (GeV).
Definition ECLCluster.cc:23
@ c_nPhotons
CR is split into n photons (N1)
Definition ECLCluster.h:41
std::vector< int > m_wire
hit level information
std::vector< int > m_layer
continuous layer number for the hit
bool m_cuts
Electron collector variables.
StoreArray< TrackFitResult > m_trackFitResults
Required array for TrackFitResults.
StoreObjPtr< SoftwareTriggerResult > m_trgResult
required input
std::vector< double > m_dedxhit
dE/dx for the hit
int m_nhits
number of dE/dx hits on the track
virtual void collect() override
Fill ROOT objects.
StoreArray< Track > m_tracks
Required array for Tracks.
ElectronValCollectorModule()
Constructor: Sets the description, the properties and the parameters of the module.
virtual void prepare() override
Create and book ROOT objects.
std::vector< double > m_entaRS
rescaled entrance angle for the hit
std::vector< double > m_enta
entrance angle for the hit
StoreArray< CDCDedxTrack > m_dedxTracks
Required array for CDCDedxTracks.
double m_injTime
time since last injection
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
FROM * getRelatedFrom(const std::string &name="", const std::string &namedRelation="") const
Get the object from which this object has a relation.
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
Values of the result of a track fit with a given particle hypothesis.
short getChargeSign() const
Return track charge (1 or -1).
double getD0() const
Getter for d0.
double getTransverseMomentum() const
Getter for the absolute value of the transverse momentum at the perigee.
double getZ0() const
Getter for z0.
ROOT::Math::XYZVector getMomentum() const
Getter for vector of momentum at closest approach of track in r/phi projection.
Class that bundles various TrackFitResults.
Definition Track.h:25
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.