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", 6, -0.5, 5.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, "selected");
76
77 tRadee->Branch<double>("injtime", &m_injTime);
78 tRadee->Branch<double>("injring", &m_injRing);
79 tRadee->Branch<double>("costh", &m_costh);
80 tRadee->Branch<int>("charge", &m_charge);
81 tRadee->Branch<int>("run", &m_run);
82 tRadee->Branch<double>("p", &m_p);
83 tRadee->Branch<double>("pt", &m_pt);
84 tRadee->Branch<double>("dedx", &m_dedx);
85 tRadee->Branch("enta", &m_enta);
86 tRadee->Branch("entaRS", &m_entaRS);
87 tRadee->Branch("layer", &m_layer);
88 tRadee->Branch("dedxhit", &m_dedxhit);
89
90
91 tBhabha->Branch<double>("dedx", &m_dedx);
92 tBhabha->Branch<double>("costh", &m_costh);
93 tBhabha->Branch<double>("p", &m_p);
94 tBhabha->Branch<int>("charge", &m_charge);
95 tBhabha->Branch<int>("run", &m_run);
96 tBhabha->Branch("wire", &m_wire);
97 tBhabha->Branch("dedxhit", &m_dedxhit);
98
99 // Collector object registration
100 registerObject<TH1D>("means", means);
101 registerObject<TTree>("tRadee", tRadee);
102 registerObject<TTree>("tBhabha", tBhabha);
103
104 registerObject<TH1I>("hestats", hestats);
105 registerObject<TH1I>("htstats", htstats);
106}
107
108//-----------------------------------------------------------------
109// Fill ROOT objects
110//-----------------------------------------------------------------
112{
113
114 // Retrieve the histogram pointer
115 auto hestats = getObjectPtr<TH1I>("hestats");
116 if (!hestats) {
117 B2ERROR("Failed to retrieve histogram 'hestats'");
118 return;
119 }
120 hestats->Fill(0); // Fill the first bin to indicate processing has started
121
122 // Check if the trigger result is valid
123 if (!m_trgResult.isValid()) {
124 B2WARNING("SoftwareTriggerResult required to select bhabha/radee event is not found");
125 hestats->Fill(1); // Fill bin 2 to indicate missing trigger result
126 return;
127 }
128
129 // Retrieve the trigger results
130 const std::map<std::string, int>& fresults = m_trgResult->getResults();
131
132 // Check for the required trigger identifiers
133 if (fresults.find("software_trigger_cut&skim&accept_bhabha") == fresults.end() &&
134 (fresults.find("software_trigger_cut&skim&accept_radee") == fresults.end()
135 || fresults.find("software_trigger_cut&skim&accept_bhabha_cdc") == fresults.end())) {
136
137 B2WARNING("Can't find required bhabha/radee trigger identifiers");
138 hestats->Fill(2); // Fill bin 3 to indicate missing trigger identifiers
139 return;
140 }
141
142 // Defining event trigger conditions
143 const bool eBhabha = (m_trgResult->getResult("software_trigger_cut&skim&accept_bhabha") == SoftwareTriggerCutResult::c_accept);
144
145 bool eRadBhabha = false;
146
147 const std::string radee =
148 "software_trigger_cut&skim&accept_radee";
149
150 const std::string bhabhaCDC =
151 "software_trigger_cut&skim&accept_bhabha_cdc";
152
153 if (fresults.find(bhabhaCDC) != fresults.end()) {
154 // If bhabha_cdc exists, use only bhabha_cdc
155 eRadBhabha = (m_trgResult->getResult(bhabhaCDC) == SoftwareTriggerCutResult::c_accept);
156 } else if (fresults.find(radee) != fresults.end()) {
157 // Otherwise use radee
158 eRadBhabha = (m_trgResult->getResult(radee) == SoftwareTriggerCutResult::c_accept);
159 }
160
161
162 // Handling different event types
163 if (eBhabha) {
164 // B2INFO("Bhabha events");
165 hestats->Fill(3); // Bin 4 (index 3)
166 } else if (eRadBhabha) {
167 // B2INFO("Radiative Bhabha events");
168 hestats->Fill(4); // Bin 5 (index 4)
169 } else {
170 B2WARNING("Requested event not found: going back");
171 hestats->Fill(5); // Bin 6 (index 5)
172 return; // Exiting the function if event is not found
173 }
174
175 // Ensure eventMetaDataPtr is valid
176 StoreObjPtr<EventMetaData> eventMetaDataPtr;
177 if (!eventMetaDataPtr) {
178 B2ERROR("Failed to retrieve event metadata");
179 return;
180 }
181
182 int run = eventMetaDataPtr->getRun();
183 m_run = run;
184
185 int nTracks = m_dedxTracks.getEntries();
186 if (nTracks >= 4) {
187 B2WARNING("too many tracks: unclean bhabha or radee event: " << nTracks);
188 hestats->Fill(6);
189 return;
190 }
191
192 hestats->Fill(7); // Fill bin 8 (index 7) to indicate a valid event
193
194 //Collector object access
195 auto tBhabha = getObjectPtr<TTree>("tBhabha");
196 auto tRadee = getObjectPtr<TTree>("tRadee");
197 auto htstats = getObjectPtr<TH1I>("htstats");
198 auto hmeans = getObjectPtr<TH1D>("means");
199
200 for (int idedx = 0; idedx < nTracks; idedx++) {
201
202 CDCDedxTrack* dedxTrack = m_dedxTracks[idedx];
203 if (!dedxTrack) {
204 B2WARNING("No dedx track: Going back: " << idedx);
205 continue;
206 }
207
208 const Track* track = dedxTrack->getRelatedFrom<Track>();
209 if (!track) {
210 B2WARNING("No track: Going back: " << idedx);
211 continue;
212 }
213
214 const TrackFitResult* fitResult = track->getTrackFitResultWithClosestMass(Const::pion);
215 if (!fitResult) {
216 B2WARNING("No related fit for this track...");
217 continue;
218 }
219
220 m_dedx = dedxTrack->getDedxNoSat();
221 m_p = dedxTrack->getMomentum();
222 m_costh = dedxTrack->getCosTheta();
223 m_charge = fitResult->getChargeSign();
224 m_pt = fitResult->getTransverseMomentum();
225 m_injTime = dedxTrack->getInjectionTime();
226 m_injRing = dedxTrack->getInjectionRing();
227 m_nhits = dedxTrack->size();
228
229 htstats->Fill(0);
230
231 if (m_cuts) {
232 // apply cleanup cuts
233 if (std::fabs(fitResult->getD0()) >= 1.0)continue;
234 if (std::fabs(fitResult->getZ0()) >= 1.0) continue;
235 htstats->Fill(1);
236
237 //if outside CDC
238 if (m_costh < TMath::Cos(150.0 * TMath::DegToRad()))continue; //-0.866
239 if (m_costh > TMath::Cos(17.0 * TMath::DegToRad())) continue; //0.95
240 htstats->Fill(2);
241
242 if (m_nhits > m_maxHits) continue;
243
244 //making some cuts based on acceptance
245 if (m_costh > -0.55 && m_costh < 0.820) {
246 if (dedxTrack->getNLayerHits() < 25)continue; //all CDC layer available here
247 } else {
249 if (dedxTrack->getNLayerHits() < 10)continue; //less layer available here
250 if (m_costh > 0 && dedxTrack->getNLayerHits() < 13)continue;
251 } else {
252 if (dedxTrack->getNLayerHits() < 18)continue;
253 }
254 }
255 htstats->Fill(3);
256
257 const ECLCluster* eclCluster = track->getRelated<ECLCluster>();
258 if (eclCluster and eclCluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
259 double TrkEoverP = (eclCluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons)) / (fitResult->getMomentum().R());
260 if (std::abs(TrkEoverP - 1.0) > m_setEoP)continue;
261 }
262 htstats->Fill(4);
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(5);
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(const std::string &name, T *obj)
Register object with a name, takes ownership, do not access the pointer beyond prepare()
T * getObjectPtr(const std::string &name)
Calls the CalibObjManager to get the requested stored collector data.
CalibrationCollectorModule()
Constructor. Sets the default prefix for calibration dataobjects.
static const ChargedStable pion
charged pion particle
Definition Const.h:662
ECL cluster data.
Definition ECLCluster.h:27
bool hasHypothesis(EHypothesisBit bitmask) const
Return if specific hypothesis bit is set.
Definition ECLCluster.h:360
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.