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_bhabha_cdc") == fresults.end()) {
135 B2WARNING("Can't find required bhabha/radee trigger identifiers");
136 hestats->Fill(2); // Fill bin 3 to indicate missing trigger identifiers
137 return;
138 }
139
140 // Defining event trigger conditions
141 const bool eBhabha = (m_trgResult->getResult("software_trigger_cut&skim&accept_bhabha") == SoftwareTriggerCutResult::c_accept);
142 const bool eRadBhabha = (m_trgResult->getResult("software_trigger_cut&skim&accept_bhabha_cdc") ==
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 // Make sure to remove all the data in vectors from the previous track
249 m_wire.clear();
250 m_layer.clear();
251 m_dedxhit.clear();
252 m_enta.clear();
253 m_entaRS.clear();
254
255 for (int i = 0; i < m_nhits; ++i) {
256 m_wire.push_back(dedxTrack->getWire(i));
257 m_layer.push_back(dedxTrack->getHitLayer(i));
258 m_dedxhit.push_back(dedxTrack->getDedx(i));
259 m_enta.push_back(dedxTrack->getEnta(i));
260 m_entaRS.push_back(dedxTrack->getEntaRS(i));
261 }
262
263 // Track and/or hit information filled as per config
264 htstats->Fill(5);
265 hmeans->Fill(m_dedx);
266 if (eBhabha) tBhabha->Fill();
267 if (eRadBhabha) tRadee->Fill();
268 }
269}
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.