Belle II Software  release-08-01-10
CDCCosmicSelectorModule.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/cdcCosmicSelector/CDCCosmicSelectorModule.h>
10 #include <framework/logging/Logger.h>
11 
12 #include <iostream>
13 
14 using namespace std;
15 using namespace Belle2;
16 
17 // register module
18 REG_MODULE(CDCCosmicSelector);
19 CDCCosmicSelectorModule::CDCCosmicSelectorModule() : Module()
20 {
21  // Set description
22  setDescription("Modify MCParticles for cosmics so that the global time is zero at y=0 assuming a cosmic trajectory is a line. And select cosmics passing through a trigger counter. This module works only for the event with the no. of primary charged MC particles=1. Please place this module after the event-generator and before FullSim.");
24 
25  addParam("xOfCounter", m_xOfCounter, "x-position of trigger counter (cm)", -0.6);
26  addParam("yOfCounter", m_yOfCounter, "y-position of trigger counter (cm)", -13.25);
27  addParam("zOfCounter", m_zOfCounter, "z-position of trigger counter (cm)", 17.3);
28  addParam("phiOfCounter", m_phiOfCounter, "phi-angle of trigger counter (deg)", 0.);
29  addParam("wOfCounter", m_wOfCounter, "full-width of trigger counter (cm)", 7.0);
30  addParam("lOfCounter", m_lOfCounter, "full-length of trigger counter (cm)", 12.5);
31  addParam("TOF", m_tof, "Tof=1(2): TOF from production point to trigger counter (IP) is subtracted", 1);
32  addParam("TOP", m_top, "TOP from hit point to pmt in trigger counter is subtracted (assuming PMT is put at -z end of counter",
33  false);
34  addParam("propSpeed", m_propSpeed, "Light prop. speed in counter (cm/ns)", 14.4);
35  addParam("cryGenerator", m_cryGenerator, "true: CRY generator; false Cosmics generator", true);
36 }
37 
39 {
41 }
42 
43 
45 {
46  bool returnVal = false;
47 
48  int nMCPs = m_mcParticles.getEntries();
49  if (nMCPs == 0) {
50  B2ERROR("No. of MCParticles=0 in the current event.");
51  setReturnValue(returnVal);
52  return;
53  }
54 
55  /*
56  const double yOfCounter = -16.25 + 3.0;
57  const double wOfCounter = 3.5;
58  const double zminOfCounter = -1.5 - 15.5;
59  const double zmaxOfCounter = -1.5 + 15.5;
60  */
61 
62  // Loop over prim. charged MC particle
63  const double c = 29.9792458; //light speed (cm/ns)
64  double mass = 0.1056583715; //muon mass (GeV)
65  unsigned nPrimChgds = 0;
66 
67  for (int iMCPs = 0; iMCPs < nMCPs; ++iMCPs) {
68  MCParticle* m_P = m_mcParticles[iMCPs];
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 ROOT::Math::XYZVector vertex = m_P->getProductionVertex();
96  const double vX0 = vertex.X();
97  const double vY0 = vertex.Y();
98  const double cosphi = cos(m_phiOfCounter * M_PI / 180.);
99  const double sinphi = sin(m_phiOfCounter * M_PI / 180.);
100  //(vx,vy) is prod. vertex in frame rotated in phi wrt lab. frame
101  const double vX = cosphi * vX0 + sinphi * vY0;
102  const double vY = -sinphi * vX0 + cosphi * vY0;
103  const double vZ = vertex.Z();
104 
105  // std::cout <<" "<< std::endl;
106  // std::cout <<"vr,vx,vy,yz= "<< sqrt(vX*vX + vY*vY) <<" "<<vX <<" "<< vY <<" "<< vZ << std::endl;
107 
108  const ROOT::Math::XYZVector momentum = m_P->getMomentum();
109  //(px,py) is momentum in frame rotated in phi wrt lab. frame
110  const double pX0 = momentum.X();
111  const double pY0 = momentum.Y();
112  const double pX = cosphi * pX0 + sinphi * pY0;
113  const double pY = -sinphi * pX0 + cosphi * pY0;
114  const double pZ = momentum.Z();
115 
116  double xi = -999.;
117  double yi = -999.;
118  double zi = -999.;
119 
120  //(x...,y...) is counter pos. in frame rotated in phi wrt lab. frame
121  const double xOfCounter = cosphi * m_xOfCounter + sinphi * m_yOfCounter;
122  const double yOfCounter = -sinphi * m_xOfCounter + cosphi * m_yOfCounter;
123 
124  if (pY != 0.) {
125  xi = (yOfCounter - vY) * (pX / pY) + vX;
126  yi = yOfCounter;
127  zi = (yOfCounter - vY) * (pZ / pY) + vZ;
128  } else {
129  //todo improve the following 3 lines and add check accept or not also in y-direction
130  xi = 0.;
131  yi = yOfCounter;
132  zi = -vX * (pZ / pX) + vZ;
133  }
134 
135  // std::cout << "xi,yi,zi= " << xi <<" "<< yi <<" "<< zi << std::endl;
136 
137  bool hitCounter = (fabs(xi - xOfCounter) < 0.5 * m_wOfCounter && fabs(zi - m_zOfCounter) < 0.5 * m_lOfCounter) ? true : false;
138 
139  //if hit, re-set the production time to zero at IP
140  if (hitCounter) {
141  // std::cout <<"checkxiyizi " << cosphi*xi-sinphi*yi<<" "<< sinphi*xi+cosphi *yi <<" "<< zi << std::endl;
142  returnVal = true;
143  const double p = sqrt(pX * pX + pY * pY + pZ * pZ);
144  const double cX = pX / p;
145  const double cY = pY / p;
146 
147  double fl = 0.;
148  if (m_tof == 1) {
149  fl = sqrt((xi - vX) * (xi - vX) + (yi - vY) * (yi - vY) + (zi - vZ) * (zi - vZ)); // fl to counter
150  // std::cout <<"fl= " << fl << std::endl;
151  } else if (m_tof == 2) {
152  fl = -(cX * vX + cY * vY) / (cX * cX + cY * cY); //fl to origin
153  } else {
154  B2FATAL("invalid tof option !");
155  }
156  // if (fl < 0.) B2FATAL("negative tof !");
157  // std::cout << "fl,flp,dif= " << fl <<" "<< flp <<" "<< fl-flp << std::endl;
158  // double dot = pX*(xi - vX) + pY*(yi - vY);
159  // if (dot < 0.) fl *= -1.;
160 
161  const double beta = p / sqrt(p * p + mass * mass);
162  double pTime = m_P->getProductionTime();
163  // const double pTimeOrg = pTime;
164 
165  if (m_cryGenerator) {
166  //calculate an intersection with y=0 plane
167  double xi4cry = -999.;
168  double yi4cry = 0.;
169  double zi4cry = -999.;
170  if (pY0 != 0.) {
171  xi4cry = (0. - vY0) * (pX0 / pY0) + vX0;
172  zi4cry = (0. - vY0) * (pZ / pY0) + vZ;
173  } else {
174  xi4cry = 0.;
175  zi4cry = -vX0 * (pZ / pX0) + vZ;
176  }
177 
178  const double fl4cry = sqrt((xi4cry - vX0) * (xi4cry - vX0) + (yi4cry - vY0) * (yi4cry - vY0) + (zi4cry - vZ) *
179  (zi4cry - vZ)); // fl to y=0 plane
180 
181  //reset production time (to the time which old CRY set) once
182  pTime += fl4cry / (c * beta);
183  }
184 
185  const double tofToCounter = fl / (c * beta);
186  const double topToPMT = m_top ? hypot(xi - xOfCounter, zi - (m_zOfCounter - 0.5 * m_lOfCounter)) / m_propSpeed : 0.;
187  /*
188  std::cout << "xi = " << xi << std::endl;
189  std::cout << "xOfCounter = " << xOfCounter << std::endl;
190  std::cout << "zi = " << zi << std::endl;
191  std::cout << "m_zOfCounter= " << m_zOfCounter << std::endl;
192  std::cout << "m_lOfCounter= " << m_lOfCounter << std::endl;
193  std::cout << "m_propSpeed = " << m_propSpeed << std::endl;
194  std::cout << "topToPMT = " << topToPMT << std::endl;
195  */
196  m_P->setProductionTime(pTime - tofToCounter - topToPMT);
197  // std::cout <<"org,mod= " << pTimeOrg << m_P->getProductionTime() << std::endl;
198  //if not hit, reverse the momentum vector so that the particle will not be simulated
199  //better to use condition in basf2...
200  } else {
201  // m_P->setMomentum(-1. * momentum);
202 
203  }
204  } // end loop over MCParticles
205  setReturnValue(returnVal);
206 }
double m_propSpeed
Light speed in counter (cm/ns)
void initialize() override
Initialize variables, print info, and start CPU clock.
double m_wOfCounter
full-width of counter (cm)
void event() override
Actual digitization of all hits in the CDC.
double m_phiOfCounter
phi-angle of counter (deg)
double m_lOfCounter
full-length of counter (cm)
bool m_cryGenerator
cry or cosmics generator
StoreArray< MCParticle > m_mcParticles
array of MCParticle
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
ROOT::Math::XYZVector getProductionVertex() const
Return production vertex position.
Definition: MCParticle.h:189
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
float getProductionTime() const
Return production time in ns.
Definition: MCParticle.h:159
ROOT::Math::XYZVector getMomentum() const
Return momentum.
Definition: MCParticle.h:198
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
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.