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 || fresults.find("software_trigger_cut&skim&accept_bhabha_cdc") == fresults.end())) {
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 const bool eRadBhabha = (m_trgResult->getResult("software_trigger_cut&skim&accept_bhabha_cdc") ==
146
147 // Handling different event types
148 if (eBhabha) {
149 B2INFO("Bhabha events");
150 hestats->Fill(3); // Bin 4 (index 3)
151 } else if (eRadBhabha) {
152 B2INFO("Radiative Bhabha events");
153 hestats->Fill(4); // Bin 5 (index 4)
154 } else {
155 B2WARNING("Requested event not found: going back");
156 hestats->Fill(5); // Bin 6 (index 5)
157 return; // Exiting the function if event is not found
158 }
159
160 // Ensure eventMetaDataPtr is valid
161 StoreObjPtr<EventMetaData> eventMetaDataPtr;
162 if (!eventMetaDataPtr) {
163 B2ERROR("Failed to retrieve event metadata");
164 return;
165 }
166
167 int run = eventMetaDataPtr->getRun();
168 m_run = run;
169
170 int nTracks = m_dedxTracks.getEntries();
171 if (nTracks >= 4) {
172 B2WARNING("too many tracks: unclean bhabha or radee event: " << nTracks);
173 hestats->Fill(6);
174 return;
175 }
176
177 hestats->Fill(7); // Fill bin 8 (index 7) to indicate a valid event
178
179 //Collector object access
180 auto tBhabha = getObjectPtr<TTree>("tBhabha");
181 auto tRadee = getObjectPtr<TTree>("tRadee");
182 auto htstats = getObjectPtr<TH1I>("htstats");
183 auto hmeans = getObjectPtr<TH1D>("means");
184
185 for (int idedx = 0; idedx < nTracks; idedx++) {
186
187 CDCDedxTrack* dedxTrack = m_dedxTracks[idedx];
188 if (!dedxTrack) {
189 B2WARNING("No dedx track: Going back: " << idedx);
190 continue;
191 }
192
193 const Track* track = dedxTrack->getRelatedFrom<Track>();
194 if (!track) {
195 B2WARNING("No track: Going back: " << idedx);
196 continue;
197 }
198
199 const TrackFitResult* fitResult = track->getTrackFitResultWithClosestMass(Const::pion);
200 if (!fitResult) {
201 B2WARNING("No related fit for this track...");
202 continue;
203 }
204
205 m_dedx = dedxTrack->getDedxNoSat();
206 m_p = dedxTrack->getMomentum();
207 m_costh = dedxTrack->getCosTheta();
208 m_charge = fitResult->getChargeSign();
209 m_pt = fitResult->getTransverseMomentum();
210 m_injTime = dedxTrack->getInjectionTime();
211 m_injRing = dedxTrack->getInjectionRing();
212 m_nhits = dedxTrack->size();
213
214 htstats->Fill(0);
215
216 if (m_cuts) {
217 // apply cleanup cuts
218 if (std::fabs(fitResult->getD0()) >= 1.0)continue;
219 if (std::fabs(fitResult->getZ0()) >= 1.0) continue;
220 htstats->Fill(1);
221
222 //if outside CDC
223 if (m_costh < TMath::Cos(150.0 * TMath::DegToRad()))continue; //-0.866
224 if (m_costh > TMath::Cos(17.0 * TMath::DegToRad())) continue; //0.95
225 htstats->Fill(2);
226
227 if (m_nhits > m_maxHits) continue;
228
229 //making some cuts based on acceptance
230 if (m_costh > -0.55 && m_costh < 0.820) {
231 if (dedxTrack->getNLayerHits() < 25)continue; //all CDC layer available here
232 } else {
234 if (dedxTrack->getNLayerHits() < 10)continue; //less layer available here
235 if (m_costh > 0 && dedxTrack->getNLayerHits() < 13)continue;
236 } else {
237 if (dedxTrack->getNLayerHits() < 18)continue;
238 }
239 }
240 htstats->Fill(3);
241
242 const ECLCluster* eclCluster = track->getRelated<ECLCluster>();
243 if (eclCluster and eclCluster->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
244 double TrkEoverP = (eclCluster->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons)) / (fitResult->getMomentum().R());
245 if (std::abs(TrkEoverP - 1.0) > m_setEoP)continue;
246 }
247 htstats->Fill(4);
248 }
249
250 //if dealing with radee here (do a safe side cleanup)
251 if (eRadBhabha) {
252 if (nTracks != 2)continue; //exactly 2 tracks
253 bool goodradee = false;
254 //checking if dedx of other track is restricted
255 //will not do too much as radee is clean enough
256 for (int jdedx = 0; jdedx < nTracks; jdedx++) {
257 CDCDedxTrack* dedxOtherTrack = m_dedxTracks[std::abs(jdedx - 1)];
258 if (!dedxOtherTrack)continue;
259 if (std::abs(dedxOtherTrack->getDedxNoSat() - 1.0) > 0.25)continue; //loose for uncalibrated
260 goodradee = true;
261 break;
262 }
263 if (!goodradee)continue;
264 htstats->Fill(5);
265 }
266
267 // Make sure to remove all the data in vectors from the previous track
268 m_wire.clear();
269 m_layer.clear();
270 m_dedxhit.clear();
271 m_enta.clear();
272 m_entaRS.clear();
273
274 for (int i = 0; i < m_nhits; ++i) {
275 m_wire.push_back(dedxTrack->getWire(i));
276 m_layer.push_back(dedxTrack->getHitLayer(i));
277 m_dedxhit.push_back(dedxTrack->getDedx(i));
278 m_enta.push_back(dedxTrack->getEnta(i));
279 m_entaRS.push_back(dedxTrack->getEntaRS(i));
280 }
281
282 // Track and/or hit information filled as per config
283 htstats->Fill(6);
284 hmeans->Fill(m_dedx);
285 if (eBhabha) tBhabha->Fill();
286 if (eRadBhabha) tRadee->Fill();
287 }
288}
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:661
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.