Belle II Software release-09-00-04
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 {
231 if (m_costh <= -0.62 || m_costh >= 0.880) {
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}
Debug output for CDCDedxPID module.
Definition: CDCDedxTrack.h:25
int getHitLayer(int i) const
Return the (global) layer number for a hit.
Definition: CDCDedxTrack.h:210
double getDedx() const
Get dE/dx truncated mean for this track.
Definition: CDCDedxTrack.h:104
double getEntaRS(int i) const
Return rescaled enta value for cell height=width assumption.
Definition: CDCDedxTrack.h:237
int getNLayerHits() const
Return the number of layer hits for this track.
Definition: CDCDedxTrack.h:175
double getCosTheta() const
Return cos(theta) for this track.
Definition: CDCDedxTrack.h:122
double getInjectionRing() const
Return cos(theta) for this track.
Definition: CDCDedxTrack.h:131
int getWire(int i) const
Return the sensor ID for this hit: wire number for CDC (0-14336)
Definition: CDCDedxTrack.h:207
double getEnta(int i) const
Return the entrance angle in the CDC cell for this hit.
Definition: CDCDedxTrack.h:231
double getInjectionTime() const
Return cos(theta) for this track.
Definition: CDCDedxTrack.h:128
double getDedxNoSat() const
Get dE/dx truncated mean without the saturation correction for this track.
Definition: CDCDedxTrack.h:107
int size() const
Return the number of hits for this track.
Definition: CDCDedxTrack.h:201
double getMomentum() const
Return the track momentum valid in the CDC.
Definition: CDCDedxTrack.h:119
Calibration collector module base class.
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)
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.
double m_injRing
event level information
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
@ c_accept
Accept this event.
Abstract base class for different kinds of events.