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