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