Belle II Software  release-05-01-25
CDCCosmicSelectorAfterFullSimModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: CDC group *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <cdc/modules/cdcCosmicSelectorAfterFullSim/CDCCosmicSelectorAfterFullSimModule.h>
12 #include <framework/logging/Logger.h>
13 #include <framework/datastore/RelationArray.h>
14 #include <framework/datastore/RelationIndex.h>
15 
16 #include <iostream>
17 
18 using namespace std;
19 using namespace Belle2;
20 
21 // register module
22 REG_MODULE(CDCCosmicSelectorAfterFullSim)
24 {
25  // Set description
26  setDescription("Modify CDCSimHits and MCParticles for cosmics so that the global time is (approximately) zero at y=0 using FullSim output (=CDCSimHits). And select cosmics passing through a user-specified region at y=0. This module works only for the event with the no. of primary charged MC particles=1. Please place this module after FullSim and before CDCDigitizer. This module is not needed for normal MC; only needed when you want to evaluate performance of T0 extraction module.");
27  setPropertyFlags(c_ParallelProcessingCertified);
28 
29  addParam("xOfRegion", m_xOfRegion, "x of center position of region at y=0 (cm)", 0.);
30  addParam("zOfRegion", m_zOfRegion, "z of center position of region at y=0 (cm)", 0.);
31  addParam("wOfRegion", m_wOfRegion, "full-width (x-direction) of region at y=0 (cm)", 10.);
32  addParam("lOfRegion", m_lOfRegion, "full-length (z-direction) of region at y=0 (cm)", 100.);
33 }
34 
35 void CDCCosmicSelectorAfterFullSimModule::initialize()
36 {
37  m_mcParticles.isRequired();
38  m_simHits.isRequired();
39 }
40 
41 
42 void CDCCosmicSelectorAfterFullSimModule::event()
43 {
44  // Get relation array
45  RelationArray mcParticlesToCDCSimHits(m_mcParticles, m_simHits);
46 
47  bool returnVal = false;
48 
49  // const double c = 29.9792458; //light speed (cm/ns)
50  // double mass = 0.1056583715;
51 
52  int nHits = m_simHits.getEntries();
53  if (nHits <= 1) {
54  B2DEBUG(250, "No .of CDCSimHits <= 1 in the current event.");
55  // B2WARNING("No .of CDCSimHits=0 in the current event= " << nHits);
56  setReturnValue(returnVal);
57  return;
58  }
59 
60  int nMCPs = m_mcParticles.getEntries();
61  if (nMCPs == 0) {
62  B2ERROR("No. of MCParticles=0 in the current event.");
63  setReturnValue(returnVal);
64  return;
65  }
66 
67  // Loop over prim. charged MC particle
68  unsigned nPrimChgds = 0;
69  for (int iMCP = 0; iMCP < nMCPs; ++iMCP) {
70  MCParticle* m_P = m_mcParticles[iMCP];
71 
72  // B2INFO("isPrimaryParticle= " << m_P->isPrimaryParticle());
73  if (!m_P->isPrimaryParticle()) continue;
74 
75  unsigned pid = abs(m_P->getPDG());
76  if (pid == 13) {
77  ++nPrimChgds;
78  } else if (pid == 11) {
79  ++nPrimChgds;
80  // mass = 0.000510998928;
81  } else if (pid == 211) {
82  ++nPrimChgds;
83  // mass = 0.13957018;
84  } else if (pid == 321) {
85  ++nPrimChgds;
86  // mass = 0.493677;
87  } else if (pid == 2212) {
88  ++nPrimChgds;
89  // mass = 0.938272046;
90  } else {
91  continue;
92  }
93 
94  // B2INFO("No .of prim. charged MC particles= " << nPrimChgds);
95  if (nPrimChgds > 1) continue;
96  /*
97  const TVector3 vertex = m_P->getProductionVertex();
98  const double vX0 = vertex.X();
99  const double vY0 = vertex.Y();
100  const double vZ0 = vertex.Z();
101  const TVector3 momentum = m_P->getMomentum();
102  const double pX0 = momentum.X();
103  const double pY0 = momentum.Y();
104  const double pZ0 = momentum.Z();
105  const double p = momentum.Mag();
106  const double beta = p / sqrt(p * p + mass * mass);
107 
108  //calculate an intersection with y=0 plane
109  double xi4cry = -999.;
110  double yi4cry = 0.;
111  double zi4cry = -999.;
112  if (pY0 != 0.) {
113  xi4cry = (0. - vY0) * (pX0 / pY0) + vX0;
114  zi4cry = (0. - vY0) * (pZ0 / pY0) + vZ0;
115  } else {
116  xi4cry = 0.;
117  zi4cry = -vX0 * (pZ0 / pX0) + vZ0;
118  }
119 
120  const double fl4cry = sqrt((xi4cry - vX0) * (xi4cry - vX0) + (yi4cry - vY0) * (yi4cry - vY0) + (zi4cry - vZ0) *
121  (zi4cry - vZ0)); // fl to y=0 plane
122  */
123 
124  //try to calculate cdc hit with tof_up and tof_dn
125  double tof_up = -9999.;
126  double tof_dn = 9999.;
127  double ihit_up = -1;
128  double ihit_dn = -1;
129  RelationIndex<MCParticle, CDCSimHit> mcp_to_hit(m_mcParticles, m_simHits);
130  if (!mcp_to_hit) B2FATAL("No MCParticle->CDCSimHit relation found!");
132  // std::cout <<" "<< std::endl;
133 
134  unsigned ntry = 0;
135  double yold = 0.;
136  double tofold = 0.;
137  unsigned iHitold = 0 ;
138  bool crossfind = false;
139 
140  for (int iHit = 0; iHit < nHits; ++iHit) {
141  if (crossfind) break;
142  for (const RelationElement& rel : mcp_to_hit.getElementsTo(m_simHits[iHit])) {
143  // std::cout <<"iHit,iMCP,rfromindex= " << iHit <<" "<< iMCP <<" "<< rel.from->getIndex()-1 << std::endl;
144  if ((rel.from->getIndex() - 1) != iMCP) continue;
145  // std::cout << "weight,pdginsimhit= " << rel.weight <<" "<< simHits[iHit]->getPDGCode() << std::endl;
146  if (rel.weight < 0.) continue; //reject 2ndary particle
147  const double y = m_simHits[iHit]->getPosTrack().Y();
148  const double tof = m_simHits[iHit]->getFlightTime();
149  // const double py = simHits[iHit]->getMomentum().Y();
150 
151  ++ntry;
152 
153  if (ntry == 1) {
154  yold = y;
155  tofold = tof;
156  iHitold = iHit;
157  } else {
158  // std::cout <<"yold,y= " << yold<<" "<< y << std::endl;
159  if (y * yold >= 0.) {
160  yold = y;
161  tofold = tof;
162  iHitold = iHit;
163  } else {
164  tof_up = tofold;
165  ihit_up = iHitold;
166  tof_dn = tof;
167  ihit_dn = iHit;
168  crossfind = true;
169  break;
170  }
171  }
172  /*
173  if (y > 0. && py < 0. && tof > tof_up) {
174  tof_up = tof;
175  ihit_up = iHit;
176  }
177  if (y < 0. && py < 0. && tof < tof_dn) {
178  tof_dn = tof;
179  ihit_dn = iHit;
180  }
181  */
182  }
183  }
184 
185  //calculate flight time from y_up to y=0 plane (linear approx.)
186  // std::cout <<"ihit_up,dn= " << ihit_up <<" "<< ihit_dn << std::endl;
187  if (ihit_up < 0 || ihit_dn < 0) continue;
188  const TVector3 pos_up = m_simHits[ihit_up]->getPosTrack();
189  const TVector3 pos_dn = m_simHits[ihit_dn]->getPosTrack();
190  const TVector3 mom_up = m_simHits[ihit_up]->getMomentum();
191  const TVector3 mom_dn = m_simHits[ihit_dn]->getMomentum();
192  if (tof_up > tof_dn) B2WARNING("tof_up > tof_dn " << tof_up << " " << tof_dn);
193  // std::cout <<"tof_up,dn= " << tof_up <<" "<< tof_dn << std::endl;
194 
195  // const TVector3 mom_mean = 0.5 * (mom_up + mom_dn);
196  const TVector3 dpos = pos_dn - pos_up;
197  double cx = dpos.X() / dpos.Mag();
198  double cy = dpos.Y() / dpos.Mag();
199  double cz = dpos.Z() / dpos.Mag();
200  double vx = pos_up.X();
201  double vy = pos_up.Y();
202  double vz = pos_up.Z();
203  if (tof_up > tof_dn) {
204  cx *= -1.;
205  cy *= -1.;
206  cz *= -1.;
207  vx = pos_dn.X();
208  vy = pos_dn.Y();
209  vz = pos_dn.Z();
210  }
211 
212  const double yi = 0.;
213  double xi = 0.;
214  double zi = 0.;
215  if (cy != 0.) {
216  xi = (yi - vy) * (cx / cy) + vx;
217  zi = (yi - vy) * (cz / cy) + vz;
218  } else {
219  zi = -vx * (cz / cx) + vz;
220  }
221 
222  bool hitRegion = (fabs(xi - m_xOfRegion) < 0.5 * m_wOfRegion && fabs(zi - m_zOfRegion) < 0.5 * m_lOfRegion) ? true : false;
223 
224  // std::cout <<"xi,zi= " << xi <<" "<< zi << std::endl;
225 
226  if (hitRegion) {
227  returnVal = true;
228  double fl = (xi - vx) * (xi - vx) + (yi - vy) * (yi - vy) + (zi - vz) * (zi - vz);
229  fl = sqrt(fl);
230  // const double beta_mean = mom_mean.Mag() / sqrt(mom_mean.Mag2() + mass * mass);
231  // const double tofToxyPlane = fl / (c * beta_mean);
232 
233  // if ((tof_up + tofToxyPlane) > tof_dn) {
234  // B2WARNING("TOF corr. stragne: " << tof_up << " " << tof_dn << " " << tofToxyPlane);
235  // continue;
236  // }
237 
238  // const double deltaT4cry = fl4cry / (c * beta);
239  // double deltaT = tof_up + deltaT4cry + tofToxyPlane;
240  // const double dT = tof_up + tofToxyPlane;
241  double dT = tof_up + (tof_dn - tof_up) * fl / dpos.Mag();
242  if (tof_up > tof_dn) dT = tof_dn + (tof_up - tof_dn) * fl / dpos.Mag();
243 
244  // const double dT = tof_up + (tof_dn - tof_up) * fl / dpos.Mag();
245  // std::cout <<"deltaT4cry,tof_up,tofToxyPlane,corrt= "<< deltaT4cry <<" "<< tof_up <<" "<< tofToxyPlane <<" "<< deltaT4cry - deltaT << std::endl;
246  const double pTime = m_P->getProductionTime();
247  m_P->setProductionTime(pTime - dT);
248 
249  for (int iHit = 0; iHit < nHits; ++iHit) {
250  // for (const RelationElement& rel : mcp_to_hit.getElementsTo(simHits[iHit])) {
251  // if ((rel.from->getIndex() - 1) != iMCP) continue;
252  const double oldgtime = m_simHits[iHit]->getGlobalTime();
253  m_simHits[iHit]->setFlightTime(oldgtime - dT);
254  m_simHits[iHit]->setGlobalTime(oldgtime - dT);
255  // }
256  }
257  } //end of hitRegion
258  } //end of mcp loop
259 
260  setReturnValue(returnVal);
261 
262 }
Belle2::RelationArray
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:72
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::RelationIndex
Provides access to fast ( O(log n) ) bi-directional lookups on a specified relation.
Definition: RelationIndex.h:84
Belle2::RelationIndex::getElementsTo
range_to getElementsTo(const TO *to) const
Return a range of all elements pointing to the given object.
Definition: RelationIndex.h:179
Belle2::MCParticle::isPrimaryParticle
bool isPrimaryParticle() const
Check if particle is a primary particle which was created by the generator (and not,...
Definition: MCParticle.h:588
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2::RelationElement
Class to store a single element of a relation.
Definition: RelationElement.h:33
Belle2::RelationIndexContainer::Element
Element type for the index.
Definition: RelationIndexContainer.h:62
Belle2::MCParticle::setProductionTime
void setProductionTime(float time)
Set production time.
Definition: MCParticle.h:392
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::MCParticle::getPDG
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:123
Belle2::CDCCosmicSelectorAfterFullSimModule
The Class for.
Definition: CDCCosmicSelectorAfterFullSimModule.h:43
Belle2::MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:43
Belle2::MCParticle::getProductionTime
float getProductionTime() const
Return production time in ns.
Definition: MCParticle.h:170