Belle II Software  release-08-02-06
CDCFudgeFactorCalibrationCollector.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/cdcCalibrationCollector/CDCFudgeFactorCalibrationCollector.h"
10 #include "analysis/utility/PCmsLabTransform.h"
11 #include <framework/dataobjects/Helix.h>
12 #include <mdst/dataobjects/HitPatternVXD.h>
13 #include <mdst/dataobjects/ECLCluster.h>
14 #include <mdst/dataobjects/EventLevelTrackingInfo.h>
15 #include <analysis/dataobjects/Particle.h>
16 #include <analysis/dataobjects/ParticleList.h>
17 #include <analysis/variables/PIDVariables.h>
18 #include <Math/ProbFuncMathCore.h>
19 
20 #include <TH1F.h>
21 #include <TH2F.h>
22 #include <TMath.h>
23 
24 using namespace std;
25 using namespace Belle2;
26 using namespace CDC;
27 
28 REG_MODULE(CDCFudgeFactorCalibrationCollector);
29 
30 CDCFudgeFactorCalibrationCollectorModule::CDCFudgeFactorCalibrationCollectorModule() : CalibrationCollectorModule()
31 {
32  setDescription("Collector module for cdc fudege calibration");
33  setPropertyFlags(c_ParallelProcessingCertified); // specify this flag if you need parallel processing
34  addParam("StoreNtuple", m_StoreNtuple, "Store ntuple other studies", true);
35  addParam("MinColinearityTheta", m_minCollinearityTheta, "cut on colinear of the two track by theta", 10.);
36  addParam("MinColinearityPhi0", m_minCollinearityPhi0, "cut on colinear of the two track by phi0", 10.);
37  addParam("DiMuonListName", m_DiMuonListName, "name of the di-muon list", std::string("vpho:mumu"));
38  addParam("GammaListName", m_GammaListName, "name of the gamma list", std::string("gamma:HLT"));
39 
40 }
41 
43 {
44 }
45 
47 {
48  m_Tracks.isRequired(m_trackArrayName);
50  m_DiMuonList.isRequired(m_DiMuonListName);
51 
52  if (m_StoreNtuple) {
53  auto m_tree = new TTree(m_treeName.c_str(), "tree for cdc calibration");
54  m_tree->Branch<Int_t>("exp_run", &expRun);
55  m_tree->Branch<Float_t>("pt_pos", &ptPos);
56  m_tree->Branch<Float_t>("pt_neg", &ptNeg);
57  m_tree->Branch<Float_t>("pz_pos", &pzPos);
58  m_tree->Branch<Float_t>("pz_neg", &pzNeg);
59 
60  m_tree->Branch<Float_t>("pt_pos_cm", &ptPosCm);
61  m_tree->Branch<Float_t>("pt_neg_cm", &ptNegCm);
62  m_tree->Branch<Float_t>("pz_pos_cm", &pzPosCm);
63  m_tree->Branch<Float_t>("pz_neg_cm", &pzNegCm);
64 
65  m_tree->Branch<Float_t>("theta_pos_cm", &thetaPosCm);
66  m_tree->Branch<Float_t>("theta_neg_cm", &thetaNegCm);
67 
68  m_tree->Branch<Float_t>("phi0_pos_cm", &phi0PosCm);
69  m_tree->Branch<Float_t>("theta_neg_cm", &phi0NegCm);
70 
71  m_tree->Branch<Float_t>("Pval_pos", &pvalPos);
72  m_tree->Branch<Float_t>("Pval_neg", &pvalNeg);
73 
74  m_tree->Branch<Float_t>("ndf_pos", &ndfPos);
75  m_tree->Branch<Float_t>("ndf_neg", &ndfNeg);
76 
77  m_tree->Branch<Float_t>("ncdc_pos", &ncdcPos);
78  m_tree->Branch<Float_t>("ncdc_neg", &ncdcNeg);
79  m_tree->Branch<Float_t>("npxd_pos", &npxdPos);
80  m_tree->Branch<Float_t>("npxd_neg", &npxdNeg);
81  m_tree->Branch<Float_t>("nsvd_pos", &nsvdPos);
82  m_tree->Branch<Float_t>("nsvd_neg", &nsvdNeg);
83 
84  m_tree->Branch<Float_t>("nextra_cdchit", &nExtraCDCHits);
85  m_tree->Branch<Float_t>("ecl_track", &eclTrack);
86  m_tree->Branch<Float_t>("ecl_neutral", &eclNeutral);
87 
88  m_tree->Branch<Float_t>("d0_pos", &d0Pos);
89  m_tree->Branch<Float_t>("d0_neg", &d0Neg);
90  m_tree->Branch<Float_t>("z0_pos", &z0Pos);
91  m_tree->Branch<Float_t>("z0_neg", &z0Neg);
92  m_tree->Branch<Float_t>("d0ip_pos", &d0ipPos);
93  m_tree->Branch<Float_t>("d0ip_neg", &d0ipNeg);
94  m_tree->Branch<Float_t>("z0ip_pos", &z0ipPos);
95  m_tree->Branch<Float_t>("z0ip_neg", &z0ipNeg);
96  m_tree->Branch<Float_t>("muid_pos", &muidPos);
97  m_tree->Branch<Float_t>("muid_neg", &muidNeg);
98  m_tree->Branch<Float_t>("eid_pos", &eidPos);
99  m_tree->Branch<Float_t>("eid_neg", &eidNeg);
100 
101  registerObject<TTree>(m_treeName.c_str(), m_tree);
102  }
103  auto m_hEventT0 = new TH1F("hEventT0", "Event T0", 200, -100, 100);
104  auto m_hExtraCDCHit = new TH1F("hExtraCDCHit", "Extra cdc hits", 500, 0, 5000);
105  auto m_hNDF_pos = new TH1F("hNDF_pos", "NDF of positive track;NDF;Tracks", 71, -1, 70);
106  auto m_hNDF_neg = new TH1F("hNDF_neg", "NDF of negative track;NDF;Tracks", 71, -1, 70);
107  auto m_hPval_pos = new TH1F("hPval_pos", "p-values of pos tracks;pVal;Tracks", 1000, 0, 1);
108  auto m_hPval_neg = new TH1F("hPval_neg", "p-values of neg tra cks;pVal;Tracks", 1000, 0, 1);
109  auto m_hnCDC_pos = new TH1F("hnCDC_pos", "nCDC hit of positive track ; nCDC ; Tracks", 71, -1, 70);
110  auto m_hnCDC_neg = new TH1F("hnCDC_neg", "nCDC hit of negative track ; nCDC ; Tracks", 71, -1, 70);
111 
112  auto m_hdPt = new TH1F("hdPt", "#DeltaP_{t} ; #DeltaP_{t} ; Events ", 200, -0.5, 0.5);
113  auto m_hdD0 = new TH1F("hdD0", "#DeltaD_{0} ; #DeltaD_{0} ; Events ", 200, -0.1, 0.1);
114  auto m_hdZ0 = new TH1F("hdZ0", "#DeltaZ_{0} ; #DeltaD_{0} ; Events ", 200, -1.5, 1.5);
115 
116  auto m_hdPt_cm = new TH1F("hdPt_cm", "#DeltaP_{t} in c.m frame ; #DeltaP_{t} (c.m) ; Events ", 200, -0.5, 0.5);
117  auto m_hdPtPt_cm = new TH2F("hdPtPt_cm", "#DeltaP_{t}:P_{t} in c.m frame ;P_{t} GeV/c ; #DeltaP_{t} (c.m) ", 50, 2., 7., 200, -0.5,
118  0.5);
119 
120  auto m_hdPhi0_cm = new TH1F("hdPhi0_cm", "#DeltaPhi_{0} in c.m frame ; #Delta#Phi_{0} in c.m ; Events ", 200, -0.7, 0.7);
121  auto m_hdTheta_cm = new TH1F("hdTheta_cm", "#Delta#theta in c.m frame ; #Delta#theta in c.m ; Events ", 200, -3.0, 3.0);
122 
123  registerObject<TH1F>("hEventT0", m_hEventT0);
124  registerObject<TH1F>("hExtraCDCHit", m_hExtraCDCHit);
125  registerObject<TH1F>("hNDF_pos", m_hNDF_pos);
126  registerObject<TH1F>("hNDF_neg", m_hNDF_neg);
127  registerObject<TH1F>("hnCDC_pos", m_hnCDC_pos);
128  registerObject<TH1F>("hnCDC_neg", m_hnCDC_neg);
129 
130  registerObject<TH1F>("hPval_pos", m_hPval_pos);
131  registerObject<TH1F>("hPval_neg", m_hPval_neg);
132 
133 
134  registerObject<TH1F>("hdPt", m_hdPt);
135  registerObject<TH1F>("hdD0", m_hdD0);
136  registerObject<TH1F>("hdZ0", m_hdZ0);
137 
138  registerObject<TH1F>("hdPt_cm", m_hdPt_cm);
139  registerObject<TH2F>("hdPtPt_cm", m_hdPtPt_cm);
140  registerObject<TH1F>("hdPhi0_cm", m_hdPhi0_cm);
141  registerObject<TH1F>("hdTheta_cm", m_hdTheta_cm);
142 }
143 
145 {
146  int nCandidates = m_DiMuonList->getListSize();
147  B2DEBUG(29, "Number of muon canndiate:" << nCandidates);
148  if (nCandidates < 1) return;
149 
150  // event with is fail to extract t0 will be exclude from analysis
151  if (m_eventTimeStoreObject.isValid() && m_eventTimeStoreObject->hasEventT0()) {
152  getObjectPtr<TH1F>("hEventT0")->Fill(m_eventTimeStoreObject->getEventT0());
153  } else {
154  return;
155  }
156  //store run/exp info
157  StoreObjPtr<EventMetaData> m_EventMetaData;
158  int run = m_EventMetaData->getRun();
159  int exp = m_EventMetaData->getExperiment();
160  expRun = exp * 1000000 + run;
161 
162  /************************************/
165  int nG = gamma_list->getListSize();
166  B2DEBUG(29, "Number of gamma: " << nG);
167  for (int i = 0; i < nG; ++i) {
168  Particle* gamma = gamma_list->getParticle(i);
169  eclNeutral += gamma->getEnergy();
170  }
171  B2DEBUG(29, "Sum of neutral ECL " << eclNeutral);
172  /************************************/
174  //now start to collect dimuon parameters
175  double thetaPos(0), thetaNeg(0);
176  int charge_sum = 0;
177 
178  for (int i = 0; i < nCandidates; ++i) {
179  Particle* part = m_DiMuonList->getParticle(i);
180  //vertex from vertex fit
181  ROOT::Math::XYZVector v0Vertex = part->getVertex();
182 
183  //loop over its daugter
184  for (int j = 0; j < 2; ++j) {
185  //we have two daugters.
186  const Particle* d0 = part->getDaughter(j);
187  short chg = d0->getCharge();
188 
189  const Belle2::TrackFitResult* fitresult = d0->getTrackFitResult();
190  if (!fitresult) {
191  B2WARNING("No track fit result found.");
192  break;
193  }
194  //get Cluter Energy
195  eclTrack += d0->getECLClusterEnergy();
196  double muid = Variable::muonID(d0);
197  double eid = Variable::muonID(d0);
198 
199  if (chg > 0) {
200  ndfPos = fitresult->getNDF();
201  pvalPos = fitresult->getPValue();
202  ptPos = fitresult->getTransverseMomentum();
203  pzPos = fitresult->getMomentum().Z();
204  d0Pos = fitresult->getD0();
205  z0Pos = fitresult->getZ0();
206  thetaPos = fitresult->getMomentum().Theta() * 180 / M_PI;
207  ncdcPos = fitresult->getHitPatternCDC().getNHits();
208  nsvdPos = fitresult->getHitPatternVXD().getNSVDHits();
209  npxdPos = fitresult->getHitPatternVXD().getNPXDHits();
210  ROOT::Math::PxPyPzEVector P4_pos = T.rotateLabToCms() * fitresult->get4Momentum();
211  ptPosCm = P4_pos.Pt();
212  thetaPosCm = P4_pos.Theta() * 180 / M_PI;
213  phi0PosCm = P4_pos.Phi() * 180 / M_PI;
214  UncertainHelix helix_pos = fitresult->getUncertainHelix();
215  helix_pos.passiveMoveBy(v0Vertex);
216  d0ipPos = helix_pos.getD0();
217  z0ipPos = helix_pos.getZ0();
218  muidPos = muid; eidPos = eid;
219  } else if (chg < 0) {
220  ndfNeg = fitresult->getNDF();
221  pvalNeg = fitresult->getPValue();
222  ptNeg = fitresult->getTransverseMomentum();
223  pzNeg = fitresult->getMomentum().Z();
224  d0Neg = fitresult->getD0();
225  z0Neg = fitresult->getZ0();
226  thetaNeg = fitresult->getMomentum().Theta() * 180 / M_PI;
227  ncdcNeg = fitresult->getHitPatternCDC().getNHits();
228  nsvdNeg = fitresult->getHitPatternVXD().getNSVDHits();
229  npxdNeg = fitresult->getHitPatternVXD().getNPXDHits();
230 
231  ROOT::Math::PxPyPzEVector P4_neg = T.rotateLabToCms() * fitresult->get4Momentum();
232  ptNegCm = P4_neg.Pt();
233  thetaNegCm = P4_neg.Theta() * 180 / M_PI;
234  phi0NegCm = P4_neg.Phi() * 180 / M_PI;
235  UncertainHelix helix_neg = fitresult->getUncertainHelix();
236  helix_neg.passiveMoveBy(v0Vertex);
237  d0ipNeg = helix_neg.getD0();
238  z0ipNeg = helix_neg.getZ0();
239  muidNeg = muid;
240  eidNeg = eid;
241  } else {
242  continue;
243  }
244  //count #good charged track and sum of charged
245  charge_sum += chg;
246  }
247  //save extra cdc hit for background monitoring
249  if (!elti) nExtraCDCHits = -1;
250  else nExtraCDCHits = elti->getNCDCHitsNotAssigned();
251  getObjectPtr<TH1F>("hExtraCDCHit")->Fill(nExtraCDCHits);
252  // cut good charged track
253  if (charge_sum != 0) {continue;}
254  //cut according to the Line400 in the plotMumu_4ff.C
255  if (ptPos < 2.5 || ptNeg < 2.5
256  || thetaPos < 45 || thetaPos > 125
257  || thetaNeg < 45 || thetaNeg > 125) {return;}
258 
259  // cut on Energy deposite in ECL
260  // Keep the same as in the dimuon study script,
261  // Although it is not neccessary to keep this as cut on Etot is enough
262  double eclTot = eclNeutral + eclTrack;
263  if (eclTot > 2 || eclTrack > 2) return;
264 
265  // B2INFO("Total Eecl_track = "<< Eecl_trk);
266  double dPt = (ptPos - ptNeg) / sqrt(2);
267  double dD0 = (d0Pos + d0Neg) / sqrt(2);
268  double dZ0 = (z0Pos - z0Neg) / sqrt(2);
269  double Pt_cm = (ptPosCm + ptNegCm) / 2;
270  double dPt_cm = (ptPosCm - ptNegCm) / sqrt(2);
271  double dPhi0_cm = (180 - fabs(phi0PosCm - phi0NegCm)) / sqrt(2);
272  double dTheta_cm = (180 - fabs(thetaPosCm + thetaNegCm)) / sqrt(2);
273 
274  //require back to back
275  if (fabs(dPhi0_cm) > m_minCollinearityPhi0 || fabs(dTheta_cm) > m_minCollinearityTheta) return;
276 
277  getObjectPtr<TH1F>("hPval_pos")->Fill(pvalPos);
278  getObjectPtr<TH1F>("hPval_neg")->Fill(pvalNeg);
279  getObjectPtr<TH1F>("hNDF_pos")->Fill(ndfPos);
280  getObjectPtr<TH1F>("hNDF_neg")->Fill(ndfNeg);
281  getObjectPtr<TH1F>("hnCDC_pos")->Fill(ncdcPos);
282  getObjectPtr<TH1F>("hnCDC_neg")->Fill(ncdcNeg);
283 
284  getObjectPtr<TH1F>("hdPt")->Fill(dPt);
285  getObjectPtr<TH1F>("hdD0")->Fill(dD0);
286  getObjectPtr<TH1F>("hdZ0")->Fill(dZ0);
287 
288  getObjectPtr<TH1F>("hdPt_cm")->Fill(dPt_cm);
289  getObjectPtr<TH2F>("hdPtPt_cm")->Fill(Pt_cm, dPt_cm);
290  getObjectPtr<TH1F>("hdPhi0_cm")->Fill(dPhi0_cm);
291  getObjectPtr<TH1F>("hdTheta_cm")->Fill(dTheta_cm);
292 
293  if (m_StoreNtuple) {
294  getObjectPtr<TTree>(m_treeName.c_str())->Fill();
295  }
296  }
297 }
298 
300 {
301 }
Double_t m_minCollinearityTheta
Minimum requirement for accolinear theta in c.m frame.
Double_t m_minCollinearityPhi0
Minimum requirement for accolinear phi0 in c.m frame.
Float_t pzPos
Longitudinal momentum of the positive track
Int_t expRun
Exp and run numbers, encoded by exp*10^6+run.
StoreArray< TrackFitResult > m_TrackFitResults
Track fit results.
Float_t nExtraCDCHits
Number of CDC hits not assigned to any tracks.
Float_t ptNeg
Transeverse momentum of the negative track
Float_t thetaNegCm
theta of the negative track in c.m frame.
std::string m_DiMuonListName
List name for the reconstruted dimuon.
void collect() override
Event action, collect information for calibration.
Float_t ptPos
Transeverse momentum of the positive track
bool m_StoreNtuple
Option to store ntuple, =true: tree with these variables will be stored.
StoreObjPtr< ParticleList > m_DiMuonList
List of the reconstructed dimion.
Float_t thetaPosCm
theta of the positive track in c.m frame.
Float_t pzPosCm
Longitudinal momentum of the positive track in c.m frame.
std::string m_trackFitResultArrayName
Belle2::TrackFitResult StoreArray name.
Float_t ptPosCm
Transeverse momentum of the positive track in c.m frame.
Float_t ptNegCm
Transeverse momentum of the negative track in c.m frame.
Float_t pzNegCm
Longitudinal momentum of the negative track in c.m frame.
std::string m_GammaListName
List name for the reconstruted dimuon.
Float_t pzNeg
Longitudinal momentum of the negative track
Calibration collector module base class.
unsigned short getNHits() const
Get the total Number of CDC hits in the fit.
unsigned short getNPXDHits() const
Get total number of hits in the PXD.
unsigned short getNSVDHits() const
Get total number of hits in the SVD.
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Class to hold Lorentz transformations from/to CMS and boost vector.
const ROOT::Math::LorentzRotation rotateLabToCms() const
Returns Lorentz transformation from Lab to CMS.
Class to store reconstructed particles.
Definition: Particle.h:75
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.
float getNDF() const
Getter for number of degrees of freedom of the track fit.
double getPValue() const
Getter for Chi2 Probability of the track fit.
ROOT::Math::PxPyPzEVector get4Momentum() const
Getter for the 4Momentum at the closest approach of the track in the r/phi projection.
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.
HitPatternCDC getHitPatternCDC() const
Getter for the hit pattern in the CDC;.
UncertainHelix getUncertainHelix() const
Conversion to framework Uncertain Helix (i.e., with covariance).
HitPatternVXD getHitPatternVXD() const
Getter for the hit pattern in the VXD;.
This class represents an ideal helix in perigee parameterization including the covariance matrix of t...
double passiveMoveBy(const ROOT::Math::XYZVector &by)
Moves origin of the coordinate system (passive transformation) by the given vector.
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
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.