CRTGen_module.cc
Go to the documentation of this file.
1 /**
2  * @file CRTGen_module.cc
3  * @brief Producer generating Monte Carlo truth record in LArSoft format to simulate protodunedp CRT Trigger
4  * @author Jose Soto
5  */
6 /**
7  * @class evgen::CRTGen
8  * This module assumes muons cross uniformly both CRT pannels. One muon will be generated per event.
9  */
10 #include <string>
11 #include <fstream>
12 
16 #include "fhiclcpp/ParameterSet.h"
17 #include "cetlib_except/exception.h"
19 
20 #include "TLorentzVector.h"
21 
26 #include "CLHEP/Random/RandFlat.h"
27 #include "art_root_io/TFileDirectory.h"
28 #include "art_root_io/TFileService.h"
29 
30 #include"TH1D.h"
31 #include"TH2D.h"
32 #include"TFile.h"
33 namespace evgen {
34  class CRTGen;
35 }
36 
38 public:
39  explicit CRTGen(fhicl::ParameterSet const & p);
40 
41  void produce(art::Event & e) override;
42  void beginJob() override;
43  void beginRun(art::Run & run) override;
44 
45 private:
46  short int driftcoordinate=0;
47  std::vector<double> CRT_TOP_center_driftY={-581,305.7,135};//drift in Y geometry in cm
48  std::vector<double> CRT_BOT_center_driftY={+581,-202.7,135}; //drift in Y geometry in cm
49  double CRTHeight=8*14.0; //size in the vertical direction
50  double CRTLength=144; //size in Z - Along the scintillator bars.
51 
52  std::vector<double> CRT_TOP_center; //corrected to the actual geometry
53  std::vector<double> CRT_BOT_center; //corrected to the actual geometry
54  double CRTSizeX; //size of the CRT in x,y and z corrected to the actual geometry
55  double CRTSizeY;
56  double CRTSizeZ;
57 
58  TH2D CRTTop, CRTBot;
60 
61  int fmode;
63  std::pair<float,float> fEnergyRange;
64  std::string fInputFileNameCRT; ///< Name of text file containing events to simulate
65  std::string fInputFileNameEnergy; ///< Name of text file containing events to simulate
66 
67 
68  TH2F *fTH2CRTTop;
69  TH2F *fTH2CRTBot;
70  TH1F *fTH1Energy;
71  /* We might have some muons that are pointing out of the CRT bottom,
72  but they end up reaching CRT bottom due to the scattering, to take those into account, we include a buffer */
73  double BufferLengthOnCRTBottom; //buffer in cm to use when using a uniform distribution
74 };
75 
76 //------------------------------------------------------------------------------
78  : EDProducer{p}
79  , fmode{p.get<int>("Mode",0)} // 0 for uniform distribution on CRT geoometry, 1 to get the distribution from TH2D
80  , fEnergyDistributionMode{p.get<int>("EnergyDistribution",0)} // 0 for uniform distribution on CRT geoometry, 1 to get the distribution from TH2D
81  , fEnergyRange{p.get<std::pair<float,float>>("EnergyRange",std::make_pair(2,3))}
82  , fInputFileNameCRT{p.get<std::string>("InputFileNameCRT","CRT_RawInputs.root")}
83  , fInputFileNameEnergy{p.get<std::string>("InputFileNameEnergy","MuonEnergy.root")}
84  , BufferLengthOnCRTBottom{p.get<float>("BufferLengthOnCRTBottom",30.0)}
85 {
86  produces< std::vector<simb::MCTruth> >();
87  produces< sumdata::RunData, art::InRun >();
88 }
89 
90 //------------------------------------------------------------------------------
92 {
93  if( fmode==0 )
94  {
95  std::cout<<" fmode=0 - Sending muons uniformly distributed on the CRT panels." << std::endl;
96  }else if (fmode==1)
97  {
98  std::cout<<" fmode=1 - Sending muons following the distribution contained on file: " << fInputFileNameCRT << std::endl;}
99  else{ throw cet::exception("CRTGen") << "unknown fmode value " << fmode << " \n"; }
100 
101  if( fEnergyDistributionMode==0 )
102  {
103  std::cout<<" fEnergyDistributionMode=0 - Muons will follow a uniform distribution between the values: " << fEnergyRange.first<< " " << fEnergyRange.second << std::endl;
104  }else if (fEnergyDistributionMode==1)
105  {
106  std::cout<<" fEnergyDistributionMode=1 - Sending muons following the distribution contained on file: " << fInputFileNameEnergy << std::endl;}
107  else{ throw cet::exception("CRTGen") << "unknown fEnergyDistributionMode value " << fEnergyDistributionMode << " \n"; }
108 
109 
110  if(fmode==1)
111  {
112  TFile *fInputFileCRT = new TFile(fInputFileNameCRT.c_str(),"READ");
113  // check that the file is a good one
114  if( !fInputFileCRT->IsOpen() )
115  throw cet::exception("CRTGen") << "input text file "
117  << " cannot be read.\n";
118 
119  TH2D *h =(TH2D*)fInputFileCRT->Get("CRTTop");
120  if (!h) throw cet::exception("CRTGen") << "TH2D named CRTTop not found in "
122  << ".\n";
123  CRTTop = *h;
124  h =(TH2D*)fInputFileCRT->Get("CRTBot");
125  if (!h) throw cet::exception("CRTGen") << "TH2D named CRTBot not found in "
127  << ".\n";
128  CRTBot = *h;
129  fInputFileCRT->Close();
130 
131  }
132 
134  {
135  TFile *fInputFileEnergy = new TFile(fInputFileNameEnergy.c_str(),"READ");
136  // check that the file is a good one
137  if( !fInputFileEnergy->IsOpen() )
138  throw cet::exception("CRTGen") << "input root file "
140  << " cannot be read.\n";
141 
142  TH1D *h =(TH1D*)fInputFileEnergy->Get("EnergyDistribution");
143  if (!h) throw cet::exception("CRTGen") << "TH1D named EnergyDistribution not found in "
145  << ".\n";
147  fInputFileEnergy->Close();
148  }
149 
151 
152  fTH2CRTTop = tfs->make<TH2F>("CRTTop","Start position at CRT Top",10,0,0,10,0,0);
153  fTH2CRTBot = tfs->make<TH2F>("CRTBot","Expected end track position at CRT Bot",10,0,0,10,0,0);
154  fTH1Energy = tfs->make<TH1F>("TH1Energy","Muon energy GeV",100,0,0);
155 
156 }
157 
158 //------------------------------------------------------------------------------
160 {
162  run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
163  driftcoordinate = (geo->TPC(0)).DetectDriftDirection();
164 
165  if( driftcoordinate==1 || driftcoordinate==2 )
166  {
167  std::cout<<" drift coordinate: "<<driftcoordinate<<std::endl;
168  }else{ throw cet::exception("CRTGen") << "unknown drift coordinate " << driftcoordinate << " \n"; }
169 
170 
171  /* +1: positive x
172  +2: positive y
173  +3: positive z
174  -1: negative x
175  -2: negative y
176  -3: negative z
177  0: other (or algorithm failed)
178  */
179 
180 
181  // We fix the CRT coordinates assuming drift in Y geometry
182  CRT_TOP_center=CRT_TOP_center_driftY; //{-581,305.7,135};//drift in Y geometry in cm
183  CRT_BOT_center=CRT_BOT_center_driftY;//{+581,-202.7,135}; //drift in Y geometry in cm
185  CRTSizeX=0.0;
186  CRTSizeZ=CRTLength; //size in Z for drift in Y and X
187 
188  //We correct for the drift in X geometry
189  if(driftcoordinate==1) // Y->X, X->-Y
190  {
191  // CRT_TOP_center {305.7,581,135};//drift in X geometry in cm
192  // CRT_BOT_center {-202.7,-581,135};//drift in X geometry in cm
193 
199  CRTSizeY=0;
201  }
202 
203  }
204 
205 //------------------------------------------------------------------------------
207 {
208 
209  std::unique_ptr< std::vector<simb::MCTruth> > truthcol(new std::vector<simb::MCTruth>);
210  simb::MCTruth truth;
211 
212  // declare the variables for reading in the event record
213  int pdg = 13;
214  double energy;
215 
216  if(fEnergyDistributionMode==1) energy = EnergyDistribution.GetRandom();
217  else energy = CLHEP::RandFlat::shoot(fEnergyRange.first,fEnergyRange.second); //uniform distribution among values set in the range
218 
219  double mass = 0.1056583745;//muon mass in GeV
220  double xPosition, yPosition, zPosition, xPositionEnd, yPositionEnd, zPositionEnd;
221  if(fmode==1)
222  {
223  if(driftcoordinate==1)
224  { //drift in X
225  CRTTop.GetRandom2(zPosition,xPosition);
226  CRTBot.GetRandom2(zPositionEnd,xPositionEnd);
227  yPosition = CRT_TOP_center[1];
228  yPositionEnd = CRT_BOT_center[1];
229 
230  fTH2CRTTop->Fill(zPosition,xPosition);
231  fTH2CRTBot->Fill(zPositionEnd,xPositionEnd);
232  }
233  if(driftcoordinate==2)
234  { //drift in Y
235  CRTTop.GetRandom2(zPosition,yPosition);
236  CRTBot.GetRandom2(zPositionEnd,yPositionEnd);
237  xPosition = CRT_TOP_center[0];
238  xPositionEnd = CRT_BOT_center[0];
239  fTH2CRTTop->Fill(zPosition,yPosition);
240  fTH2CRTBot->Fill(zPositionEnd,yPositionEnd);
241 
242  }
243  }
244  else
245  {
246  xPosition = CLHEP::RandFlat::shoot(CRT_TOP_center[0]-0.5*CRTSizeX,CRT_TOP_center[0]+0.5*CRTSizeX);
247  yPosition = CLHEP::RandFlat::shoot(CRT_TOP_center[1]-0.5*CRTSizeY,CRT_TOP_center[1]+0.5*CRTSizeY);
248  zPosition = CLHEP::RandFlat::shoot(CRT_TOP_center[2]-0.5*CRTSizeZ,CRT_TOP_center[2]+0.5*CRTSizeZ);
249 
250  if(driftcoordinate==1)
251  { //drift in X
252  xPositionEnd = CLHEP::RandFlat::shoot(CRT_BOT_center[0]-0.5*CRTSizeX-BufferLengthOnCRTBottom,CRT_BOT_center[0]+0.5*CRTSizeX+BufferLengthOnCRTBottom);
253  yPositionEnd = CLHEP::RandFlat::shoot(CRT_BOT_center[1]-0.5*CRTSizeY,CRT_BOT_center[1]+0.5*CRTSizeY);
254  zPositionEnd = CLHEP::RandFlat::shoot(CRT_BOT_center[2]-0.5*CRTSizeZ-BufferLengthOnCRTBottom,CRT_BOT_center[2]+0.5*CRTSizeZ+BufferLengthOnCRTBottom);
255  }
256  if(driftcoordinate==2)
257  { //drift in Y
258  xPositionEnd = CLHEP::RandFlat::shoot(CRT_BOT_center[0]-0.5*CRTSizeX,CRT_BOT_center[0]+0.5*CRTSizeX);
259  yPositionEnd = CLHEP::RandFlat::shoot(CRT_BOT_center[1]-0.5*CRTSizeY-BufferLengthOnCRTBottom,CRT_BOT_center[1]+0.5*CRTSizeY+BufferLengthOnCRTBottom);
260  zPositionEnd = CLHEP::RandFlat::shoot(CRT_BOT_center[2]-0.5*CRTSizeZ-BufferLengthOnCRTBottom,CRT_BOT_center[2]+0.5*CRTSizeZ+BufferLengthOnCRTBottom);
261  }
262  }
263 
264  if(driftcoordinate==1)
265  { //drift in X
266  fTH2CRTTop->Fill(zPosition,xPosition);
267  fTH2CRTBot->Fill(zPositionEnd,xPositionEnd);
268  }
269  if(driftcoordinate==2)
270  { //drift in Y
271  fTH2CRTTop->Fill(zPosition,yPosition);
272  fTH2CRTBot->Fill(zPositionEnd,yPositionEnd);
273  }
274 
275  double time = 0.;
276  double totmom = sqrt(pow(energy,2)-pow(mass,2));
277 
278  double dx=xPositionEnd-xPosition;
279  double dy=yPositionEnd-yPosition;
280  double dz=zPositionEnd-zPosition;
281  double norm=sqrt(pow(dx,2)+pow(dy,2)+pow(dz,2));
282  dx/=norm;
283  dy/=norm;
284  dz/=norm;
285 
286  double xMomentum = dx*totmom;
287  double yMomentum = dy*totmom;
288  double zMomentum = dz*totmom;
289  mf::LogPrint("CRTGen") << "Shooting muon on " << xPosition << " " << yPosition << " " << zPosition << "to "<< xPositionEnd << " " << yPositionEnd << " " << zPositionEnd <<" With momentum: " << xMomentum << " " << yMomentum << " " << zMomentum << " E=" << energy << " m=" << mass;
290 
291  TLorentzVector pos(xPosition, yPosition, zPosition, time);
292  TLorentzVector mom(xMomentum, yMomentum, zMomentum, energy);
293 
294  fTH1Energy->Fill(energy);
295 
296  simb::MCParticle part(-1, pdg, "primary");
297  part.AddTrajectoryPoint(pos, mom);
298 
299  truth.Add(part);
300 
301  truthcol->push_back(truth);
302 
303  e.put(std::move(truthcol));
304 }
305 
void beginRun(art::Run &run) override
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
Definition: MCParticle.h:257
std::pair< float, float > fEnergyRange
std::string string
Definition: nybbler.cc:12
void produce(art::Event &e) override
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
constexpr T pow(T x)
Definition: pow.h:72
TH1D EnergyDistribution
CRTGen(fhicl::ParameterSet const &p)
Particle class.
art framework interface to geometry description
Definition: Run.h:17
std::string fInputFileNameEnergy
Name of text file containing events to simulate.
std::vector< double > CRT_TOP_center
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
short int driftcoordinate
def move(depos, offset)
Definition: depos.py:107
int fEnergyDistributionMode
std::string fInputFileNameCRT
Name of text file containing events to simulate.
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
std::vector< double > CRT_BOT_center_driftY
auto norm(Vector const &v)
Return norm of the specified vector.
double BufferLengthOnCRTBottom
void Add(simb::MCParticle const &part)
Definition: MCTruth.h:80
std::vector< double > CRT_TOP_center_driftY
void beginJob() override
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
Event generator information.
Definition: MCTruth.h:32
LArSoft geometry interface.
Definition: ChannelGeo.h:16
Event Generation using GENIE, cosmics or single particles.
std::vector< double > CRT_BOT_center
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
MaybeLogger_< ELseverityLevel::ELsev_warning, true > LogPrint
QTextStream & endl(QTextStream &s)