GEMC  2.3
Geant4 Monte-Carlo Framework
dc_hitprocess.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "dc_hitprocess.h"
3 
4 // clhep
5 #include "CLHEP/Random/RandGaussT.h"
6 #include "CLHEP/Units/PhysicalConstants.h"
7 using namespace CLHEP;
8 
9 // ccdb
10 #include <CCDB/Calibration.h>
11 #include <CCDB/Model/Assignment.h>
12 #include <CCDB/CalibrationGenerator.h>
13 using namespace ccdb;
14 
15 // geant4
16 #include "Randomize.hh"
17 
18 
19 static dcConstants initializeDCConstants(int runno)
20 {
21  // all these constants should be read from CCDB
22  dcConstants dcc;
23 
24  // do not initialize at the beginning, only after the end of the first event,
25  // with the proper run number coming from options or run table
26  if(runno == -1) return dcc;
27 
28  dcc.NWIRES = 113;
29  dcc.dcThreshold = 50; // eV
30 
31  // database
32  dcc.runNo = runno;
33  dcc.date = "2016-03-15";
34  if(getenv ("CCDB_CONNECTION") != NULL)
35  dcc.connection = (string) getenv("CCDB_CONNECTION");
36  else
37  dcc.connection = "mysql://clas12reader@clasdb.jlab.org/clas12";
38 
39  dcc.variation = "main";
40  auto_ptr<Calibration> calib(CalibrationGenerator::CreateCalibration(dcc.connection));
41 
42 
43  // reading efficiency parameters
44  string database = "/calibration/dc/signal_generation/intrinsic_inefficiency";
45  vector<vector<double> > data;
46  calib->GetCalib(data, database);
47  for(unsigned row = 0; row < data.size(); row++)
48  {
49  int sl = data[row][0] - 1;
50  dcc.P1[sl] = data[row][1];
51  dcc.P2[sl] = data[row][2];
52  dcc.P3[sl] = data[row][3];
53  dcc.P4[sl] = data[row][4];
54  dcc.iScale[sl] = data[row][5];
55  }
56 
57  // reading smearing parameters
58  database = "/calibration/dc/signal_generation/dc_resolution";
59  data.clear();
60  calib->GetCalib(data, database);
61  for(unsigned row = 0; row < data.size(); row++)
62  {
63  int sec = data[row][0] - 1;
64  int sl = data[row][1] - 1;
65  dcc.smearP1[sec][sl] = data[row][2];
66  dcc.smearP2[sec][sl] = data[row][3];
67  dcc.smearP3[sec][sl] = data[row][4];
68  dcc.smearP4[sec][sl] = data[row][5];
69  dcc.smearScale[sec][sl] = data[row][6];
70 
71  if(dcc.smearScale[sec][sl] > 1)
72  {
73  cout << " !!!! DC Warning: the smearing parameter is greater than one for sector " << sec << " sl " << sl
74  << ". That means that the DC response in GEMC will have"
75  << " worse resoultion than the data. " << endl;
76  }
77 
78  }
79 
80 
81  // reading DC core parameters
82  database = "/geometry/dc/superlayer";
83  auto_ptr<Assignment> dcCoreModel(calib->GetAssignment(database));
84  for(size_t rowI = 0; rowI < dcCoreModel->GetRowsCount(); rowI++)
85  dcc.dLayer[rowI] = dcCoreModel->GetValueDouble(rowI, 6);
86 
87  dcc.driftVelocity[0] = dcc.driftVelocity[1] = 0.053;
88  dcc.driftVelocity[2] = dcc.driftVelocity[3] = 0.026;
89  dcc.driftVelocity[4] = dcc.driftVelocity[5] = 0.036;
90 
91  for(int l=0; l<6; l++)
92  dcc.miniStagger[l] = 0;
93 
94  return dcc;
95 }
96 
97 
98 map<string, double> dc_HitProcess :: integrateDgt(MHit* aHit, int hitn)
99 {
100 
101  map<string, double> dgtz;
102  vector<identifier> identity = aHit->GetId();
103 
104  int SECI = identity[0].id - 1;
105  int SLI = identity[1].id - 1;
106  int nwire = identity[3].id;
107 
108  // nwire position information
109  double ylength = aHit->GetDetector().dimensions[3];
110  double deltay = 2.0*ylength/dcc.NWIRES;
111  double WIRE_Y = nwire*deltay + dcc.miniStagger[SLI];
112 
113  vector<int> stepTrackId = aHit->GetTIds();
114  vector<double> stepTime = aHit->GetTime();
115  vector<G4double> Edep = aHit->GetEdep();
116  vector<G4ThreeVector> pos = aHit->GetPos();
117  vector<G4ThreeVector> Lpos = aHit->GetLPos();
118 
119  unsigned nsteps = Edep.size();
120 
121  // Identifying the fastest - given by time + doca(s) / drift velocity
122  // trackId Strong and Weak in case the track does or does not deposit enough energy
123  int trackIds = -1;
124  int trackIdw = -1;
125  double minTime = 10000;
126  double signal_t = 0;
127 
128  for(unsigned int s=0; s<nsteps; s++)
129  {
130  G4ThreeVector DOCA(0, Lpos[s].y() + ylength - WIRE_Y, Lpos[s].z()); // local cylinder
131  signal_t = stepTime[s]/ns + DOCA.mag()/dcc.driftVelocity[SLI];
132 
133  // threshold hardcoded, please get from parameters
134  if(signal_t < minTime)
135  {
136  trackIdw = stepTrackId[s];
137  minTime = signal_t;
138 
139  if(Edep[s] >= dcc.dcThreshold*eV)
140  {
141  trackIds = stepTrackId[s];
142  }
143  }
144  }
145 
146  // If no step pass the threshold, getting the fastest signal of the weak tracks
147  if(trackIds == -1)
148  trackIds = trackIdw;
149 
150  // Left / Right ambiguity
151  // Finding DOCA
152  double LR = 0;
153  double doca = 10000;
154 
155  for(unsigned int s=0; s<nsteps; s++)
156  {
157  G4ThreeVector DOCA(0, Lpos[s].y() + ylength - WIRE_Y, Lpos[s].z());
158 
159  if(DOCA.mag() <= doca && stepTrackId[s] == trackIds )
160  {
161  doca = DOCA.mag();
162  if(DOCA.y() >=0 ) LR = 1;
163  else LR = -1;
164  }
165  }
166 
167  // percentage distance from the wire
168  double X = (doca/cm) / (2*dcc.dLayer[SLI]);
169 
170  // smeading doca by DOCA dependent function. This is the sigma of doca.
171  double smearF = dcc.smearP1[SECI][SLI] + dcc.smearP2[SECI][SLI]/pow(dcc.smearP3[SECI][SLI] + X, 2) + dcc.smearP4[SECI][SLI]*pow(X, 8);
172 
173  // smearing doca with a gaussian around doca and sigma defined above
174  double sdoca = fabs(CLHEP::RandGauss::shoot(doca, smearF*dcc.smearScale[SECI][SLI]));
175 
176  // distance-dependent efficiency as a function of doca
177  double ddEff = dcc.iScale[SLI]*(dcc.P1[SLI]/pow(X*X + dcc.P2[SLI], 2) + dcc.P3[SLI]/pow( (1-X) + dcc.P4[SLI], 2));
178  double random = G4UniformRand();
179 
180  int ineff = 1;
181  if(random < ddEff || X > 1) ineff = -1;
182 
183  // recording smeared and un-smeared quantities
184  dgtz["hitn"] = hitn;
185  dgtz["sector"] = identity[0].id;
186  dgtz["superlayer"] = SLI+1;
187  dgtz["layer"] = identity[2].id;
188  dgtz["wire"] = nwire;
189  dgtz["LR"] = LR;
190  dgtz["doca"] = doca;
191  dgtz["sdoca"] = sdoca;
192  dgtz["time"] = ineff *doca/dcc.driftVelocity[SLI];
193  dgtz["stime"] = ineff*sdoca/dcc.driftVelocity[SLI];
194 
195  return dgtz;
196 }
197 
198 // routine to determine the wire number based on the hit position
199 vector<identifier> dc_HitProcess :: processID(vector<identifier> id, G4Step* aStep, detector Detector)
200 {
201  vector<identifier> yid = id;
202  int SLI = yid[1].id - 1;
203 
204  G4StepPoint *prestep = aStep->GetPreStepPoint();
205  G4StepPoint *poststep = aStep->GetPostStepPoint();
206 
207  G4ThreeVector xyz = poststep->GetPosition();
208  G4ThreeVector Lxyz = prestep->GetTouchableHandle()->GetHistory()
209  ->GetTopTransform().TransformPoint(xyz);
210 
211 
212  double ylength = Detector.dimensions[3];
213  double deltay = 2.0*ylength/dcc.NWIRES;
214  double loc_y = Lxyz.y() + ylength - dcc.miniStagger[SLI];
215 
216  int nwire = (int) floor(loc_y/deltay);
217 
218  // resetting nwire for extreme cases
219  if(nwire <= 0 ) nwire = 1;
220  if(nwire == 113) nwire = 112;
221 
222  // setting wire number
223  yid[3].id = nwire;
224 
225  // checking that the next wire is not the one closer
226  if(fabs( (nwire+1)*deltay - loc_y ) < fabs( nwire*deltay - loc_y ) && nwire != 112 )
227  yid[3].id = nwire + 1;
228 
229  // all energy to this wire (no energy sharing)
230  yid[3].id_sharing = 1;
231 
232  return yid;
233 }
234 
235 void dc_HitProcess::initWithRunNumber(int runno)
236 {
237  if(dcc.runNo != runno)
238  {
239  cout << " > Initializing " << HCname << " digitization for run number " << runno << endl;
240  dcc = initializeDCConstants(runno);
241  dcc.runNo = runno;
242  }
243 }
244 
245 
246 map< string, vector <int> > dc_HitProcess :: multiDgt(MHit* aHit, int hitn)
247 {
248  map< string, vector <int> > MH;
249 
250  return MH;
251 }
252 
253 // this static function will be loaded first thing by the executable
254 dcConstants dc_HitProcess::dcc = initializeDCConstants(1);
255 
256 
257 
258 
259 
260 
261 
map< string, double > integrateDgt(MHit *, int)
string connection
Definition: dc_hitprocess.h:19
string variation
Definition: dc_hitprocess.h:17
double dcThreshold
Definition: dc_hitprocess.h:23
vector< identifier > GetId()
Definition: Hit.h:103
double smearScale[6][6]
Definition: dc_hitprocess.h:31
double driftVelocity[6]
Definition: dc_hitprocess.h:21
double dLayer[6]
Definition: dc_hitprocess.h:25
double smearP1[6][6]
Definition: dc_hitprocess.h:31
double smearP3[6][6]
Definition: dc_hitprocess.h:31
vector< G4ThreeVector > GetLPos()
Definition: Hit.h:76
double P2[6]
Definition: dc_hitprocess.h:28
vector< G4ThreeVector > GetPos()
Definition: Hit.h:72
Definition: Hit.h:22
vector< double > GetTime()
Definition: Hit.h:89
vector< int > GetTIds()
Definition: Hit.h:101
map< string, vector< int > > multiDgt(MHit *, int)
double P3[6]
Definition: dc_hitprocess.h:28
double P1[6]
Definition: dc_hitprocess.h:28
double P4[6]
Definition: dc_hitprocess.h:28
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:77
double miniStagger[6]
Definition: dc_hitprocess.h:22
double smearP4[6][6]
Definition: dc_hitprocess.h:31
vector< identifier > processID(vector< identifier >, G4Step *, detector)
vector< double > GetEdep()
Definition: Hit.h:83
double smearP2[6][6]
Definition: dc_hitprocess.h:31
detector GetDetector()
Definition: Hit.h:108
double iScale[6]
Definition: dc_hitprocess.h:28