Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4TpcCentralMembrane.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4TpcCentralMembrane.cc
2 
3 #include <phparameter/PHParameterInterface.h> // for PHParameterInterface
4 
5 #include <g4main/PHG4Hit.h>
7 #include <g4main/PHG4HitDefs.h> // for get_volume_id
8 #include <g4main/PHG4Hitv1.h>
9 
11 #include <fun4all/SubsysReco.h> // for SubsysReco
12 
13 #include <phool/getClass.h>
14 #include <phool/phool.h> // for PHWHERE
15 
16 #include <TVector3.h>
17 #include <TString.h>
18 
19 #include <iostream> // for operator<<, endl, basi...
20 
21 class PHCompositeNode;
22 
23 namespace
24 {
25  // unique detector id for all direct lasers
26  static const int detId = PHG4HitDefs::get_volume_id("PHG4TpcCentralMembrane");
27 
28  template<class T> inline constexpr T square( const T& x ) { return x*x; }
29 
30  template<class T> inline T get_r( const T& x, const T& y ) { return std::sqrt( square(x) + square(y) ); }
31 
32 } // namespace
33 
34 //_____________________________________________________________
35 // all distances in mm, all angles in rad
36 // class that generates stripes and dummy hit coordinates
37 // stripes have width of one mm, length of one pad width, and are centered in middle of sector gaps
39  : SubsysReco(name)
40  , PHParameterInterface(name)
41 {
43 
44  // set to 1.0 mm for all else
45  for (int j = 0; j < nRadii; j++)
46  {
47  for (int i = 0; i < nStripes_R1; i++)
48  {
49  str_width_R1_e[i][j] = 1.0 * mm;
50  str_width_R1[i][j] = 1.0 * mm;
51  }
52  for (int i = 0; i < nStripes_R2; i++)
53  {
54  str_width_R2[i][j] = 1.0 * mm;
55  }
56  for (int i = 0; i < nStripes_R3; i++)
57  {
58  str_width_R3[i][j] = 1.0 * mm;
59  }
60  }
61 
66 }
67 
68 //______________________________________________________
70 {
71  for (auto&& hit : PHG4Hits)
72  {
73  delete hit;
74  }
75 }
76 
77 //_____________________________________________________________
79 {
80  // setup parameters
82  electrons_per_stripe = get_int_param("electrons_per_stripe");
83  electrons_per_gev = get_double_param("electrons_per_gev");
84 
85  std::cout << "PHG4TpcCentralMembrane::InitRun - electrons_per_stripe: " << electrons_per_stripe << std::endl;
86  std::cout << "PHG4TpcCentralMembrane::InitRun - electrons_per_gev " << electrons_per_gev << std::endl;
87 
88  // reset g4hits
89  for (auto&& hit : PHG4Hits)
90  {
91  delete hit;
92  }
93 
94  PHG4Hits.clear();
95 
96  /*
97  * utility function to
98  * - duplicate generated G4Hit to cover both sides of the central membrane
99  * - adjust hit time and z,
100  * - insert in container
101  */
102  auto adjust_hits = [&](PHG4Hit* source) {
103  // adjust time to account for central membrane delay
104  source->set_t(0, m_centralMembraneDelay);
105  source->set_t(1, m_centralMembraneDelay);
106 
107  // assign to positive side
108  source->set_z(0, 1.);
109  source->set_z(1, 1.);
110  PHG4Hits.push_back(source);
111 
112  // clone
113  // assign to negative side and insert in list
114  auto copy = new PHG4Hitv1(source);
115  copy->set_z(0, -1.);
116  copy->set_z(1, -1.);
117  PHG4Hits.push_back(copy);
118  };
119 
120  // loop over petalID
121  for (int i = 0; i < 18; i++)
122  {
123  // loop over radiusID
124  for (int j = 0; j < 8; j++)
125  {
126  // loop over stripeID
127  for (int k = 0; k < nGoodStripes_R1_e[j]; k++)
128  {
129  adjust_hits(GetPHG4HitFromStripe(i, 0, j, k, electrons_per_stripe));
130  }
131 
132  // loop over stripeID
133  for (int k = 0; k < nGoodStripes_R1[j]; k++)
134  {
135  adjust_hits(GetPHG4HitFromStripe(i, 1, j, k, electrons_per_stripe));
136  }
137 
138  // loop over stripeID
139  for (int k = 0; k < nGoodStripes_R2[j]; k++)
140  {
141  adjust_hits(GetPHG4HitFromStripe(i, 2, j, k, electrons_per_stripe));
142  }
143 
144  // loop over stripeID
145  for (int k = 0; k < nGoodStripes_R3[j]; k++)
146  {
147  adjust_hits(GetPHG4HitFromStripe(i, 3, j, k, electrons_per_stripe));
148  }
149  }
150  }
151 
152  m_eventNum = 0;
153 
155 }
156 
157 //_____________________________________________________________
159 {
160 
161  if(m_eventNum % m_eventModulo != 0)
162  {
163  if(Verbosity()) std::cout << "Event " << m_eventNum << " will not generate CM hits" << std::endl;
164  m_eventNum++;
166  }
167 
168  // load g4hit container
169  auto g4hitcontainer = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
170  if (!g4hitcontainer)
171  {
172  std::cout << PHWHERE << "Could not locate g4 hit node " << hitnodename << std::endl;
174  }
175 
176  // copy all hits from G4hits vector into container
177  for (const auto& hit : PHG4Hits)
178  {
179  auto copy = new PHG4Hitv1(hit);
180  g4hitcontainer->AddHit(detId, copy);
181  }
182 
183  m_eventNum++;
184 
186 }
187 
188 //_____________________________________________________________
190 {
191  // same gas parameters as in PHG4TpcElectronDrift::SetDefaultParameters
192 
193  // Data on gasses @20 C and 760 Torr from the following source:
194  // http://www.slac.stanford.edu/pubs/icfa/summer98/paper3/paper3.pdf
195  // diffusion and drift velocity for 400kV for NeCF4 50/50 from calculations:
196  // http://skipper.physics.sunysb.edu/~prakhar/tpc/HTML_Gases/split.html
197  static constexpr double Ne_dEdx = 1.56; // keV/cm
198  static constexpr double CF4_dEdx = 7.00; // keV/cm
199  static constexpr double Ne_NTotal = 43; // Number/cm
200  static constexpr double CF4_NTotal = 100; // Number/cm
201  static constexpr double Tpc_NTot = 0.5 * Ne_NTotal + 0.5 * CF4_NTotal;
202  static constexpr double Tpc_dEdx = 0.5 * Ne_dEdx + 0.5 * CF4_dEdx;
203  static constexpr double Tpc_ElectronsPerKeV = Tpc_NTot / Tpc_dEdx;
204 
205  // number of electrons per deposited GeV in TPC gas
206  set_default_double_param("electrons_per_gev", Tpc_ElectronsPerKeV * 1000000.);
207 
209  set_default_int_param("electrons_per_stripe", 100);
210 }
211 
212 //_____________________________________________________________
214  int nStripes, int nPads,
215  const std::array<double, nRadii>& R,
216  std::array<double, nRadii>& spacing,
217  double x1a[][nRadii], double y1a[][nRadii],
218  double x1b[][nRadii], double y1b[][nRadii],
219  double x2a[][nRadii], double y2a[][nRadii],
220  double x2b[][nRadii], double y2b[][nRadii],
221  double x3a[][nRadii], double y3a[][nRadii],
222  double x3b[][nRadii], double y3b[][nRadii],
223  double padfrac,
224  double str_width[][nRadii],
225  const std::array<double, nRadii>& widthmod,
226  std::array<int, nRadii>& nGoodStripes,
227  const std::array<int, nRadii>& keepUntil,
228  std::array<int, nRadii>& nStripesIn,
229  std::array<int, nRadii>& nStripesBefore)
230 {
231  const double phi_module = M_PI / 6.0; // angle span of a module
232  const int pr_mult = 3; // multiples of intrinsic resolution of pads
233  const int dw_mult = 8; // multiples of diffusion width
234  const double diffwidth = 0.6 * mm; // diffusion width
235  const double adjust = 0.015; //arbitrary angle to center the pattern in a petal
236 
237  double theta = 0.0;
238  //center coords
239  double cx[nStripes][nRadii];
240  double cy[nStripes][nRadii];
241  //corner coords
242  /* double tempX1a[nStripes][nRadii], tempY1a[nStripes][nRadii];
243  double tempX1b[nStripes][nRadii], tempY1b[nStripes][nRadii];
244  double tempX2a[nStripes][nRadii], tempY2a[nStripes][nRadii];
245  double tempX2b[nStripes][nRadii], tempY2b[nStripes][nRadii];
246  double rotatedX1a[nStripes][nRadii], rotatedY1a[nStripes][nRadii];
247  double rotatedX1b[nStripes][nRadii], rotatedY1b[nStripes][nRadii];
248  double rotatedX2a[nStripes][nRadii], rotatedY2a[nStripes][nRadii];
249  double rotatedX2b[nStripes][nRadii], rotatedY2b[nStripes][nRadii]; */
250 
251  //calculate spacing first:
252  for (int i = 0; i < nRadii; i++)
253  {
254  spacing[i] = 2.0 * ((dw_mult * diffwidth / R[i]) + (pr_mult * phi_module / nPads));
255  }
256 
257  //vertex calculation
258  for (int j = 0; j < nRadii; j++)
259  {
260  int i_out = 0;
261  for (int i = keepThisAndAfter[j]; i < keepUntil[j]; i++)
262  {
263  if (j % 2 == 0)
264  {
265  theta = i * spacing[j] + (spacing[j] / 2) - adjust;
266  cx[i_out][j] = R[j] * cos(theta);
267  cy[i_out][j] = R[j] * sin(theta);
268  }
269  else
270  {
271  theta = (i + 1) * spacing[j] - adjust;
272  cx[i_out][j] = R[j] * cos(theta);
273  cy[i_out][j] = R[j] * sin(theta);
274  }
275 
276  TVector3 corner[4];
277  corner[0].SetXYZ(-padfrac + arc_r, -(widthmod[j] * str_width[i][j]) / 2, 0); //"1a" = length of the pad, but not including the arc piece
278  corner[1].SetXYZ(padfrac - arc_r, -(widthmod[j] * str_width[i][j]) / 2, 0); //"1b" = length of the pad, but not including the arc piece
279  corner[2].SetXYZ(-padfrac + arc_r, (widthmod[j] * str_width[i][j]) / 2, 0); //"2a" = length of the pad, but not including the arc piece
280  corner[3].SetXYZ(padfrac - arc_r, (widthmod[j] * str_width[i][j]) / 2, 0); //"2b" = length of the pad, but not including the arc piece
281 
282  TVector3 rotatedcorner[4];
283  for (int n = 0; n < 4; n++)
284  {
285  rotatedcorner[n] = corner[n];
286  rotatedcorner[n].RotateZ(theta);
287  }
288 
289  x1a[i_out][j] = rotatedcorner[0].X() + cx[i_out][j];
290  x1b[i_out][j] = rotatedcorner[1].X() + cx[i_out][j];
291  x2a[i_out][j] = rotatedcorner[2].X() + cx[i_out][j];
292  x2b[i_out][j] = rotatedcorner[3].X() + cx[i_out][j];
293 
294  y1a[i_out][j] = rotatedcorner[0].Y() + cy[i_out][j];
295  y1b[i_out][j] = rotatedcorner[1].Y() + cy[i_out][j];
296  y2a[i_out][j] = rotatedcorner[2].Y() + cy[i_out][j];
297  y2b[i_out][j] = rotatedcorner[3].Y() + cy[i_out][j];
298 
299  /* x1a[i_out][j] = cx[i_out][j] - padfrac + arc_r;
300  y1a[i_out][j] = cy[i_out][j] - str_width/2;
301  x1b[i_out][j] = cx[i_out][j] + padfrac - arc_r;
302  y1b[i_out][j] = cy[i_out][j] - str_width/2;
303  x2a[i_out][j] = cx[i_out][j] - padfrac + arc_r;
304  y2a[i_out][j] = cy[i_out][j] + str_width/2;
305  x2b[i_out][j] = cx[i_out][j] + padfrac - arc_r;
306  y2b[i_out][j] = cy[i_out][j] + str_width/2;
307 
308  tempX1a[i_out][j] = x1a[i_out][j] - cx[i_out][j];
309  tempY1a[i_out][j] = y1a[i_out][j] - cy[i_out][j];
310  tempX1b[i_out][j] = x1b[i_out][j] - cx[i_out][j];
311  tempY1b[i_out][j] = y1b[i_out][j] - cy[i_out][j];
312  tempX2a[i_out][j] = x2a[i_out][j] - cx[i_out][j];
313  tempY2a[i_out][j] = y2a[i_out][j] - cy[i_out][j];
314  tempX2b[i_out][j] = x2b[i_out][j] - cx[i_out][j];
315  tempY2b[i_out][j] = y2b[i_out][j] - cy[i_out][j];
316 
317  rotatedX1a[i_out][j] = tempX1a[i_out][j]*cos(theta) - tempY1a[i_out][j]*sin(theta);
318  rotatedY1a[i_out][j] = tempX1a[i_out][j]*sin(theta) + tempY1a[i_out][j]*cos(theta);
319  rotatedX1b[i_out][j] = tempX1b[i_out][j]*cos(theta) - tempY1b[i_out][j]*sin(theta);
320  rotatedY1b[i_out][j] = tempX1b[i_out][j]*sin(theta) + tempY1b[i_out][j]*cos(theta);
321  rotatedX2a[i_out][j] = tempX2a[i_out][j]*cos(theta) - tempY2a[i_out][j]*sin(theta);
322  rotatedY2a[i_out][j] = tempX2a[i_out][j]*sin(theta) + tempY2a[i_out][j]*cos(theta);
323  rotatedX2b[i_out][j] = tempX2b[i_out][j]*cos(theta) - tempY2b[i_out][j]*sin(theta);
324  rotatedY2b[i_out][j] = tempX2b[i_out][j]*sin(theta) + tempY2b[i_out][j]*cos(theta);*/
325 
326  /* x1a[i_out][j] = rotatedX1a[i_out][j] + cx[i_out][j];
327  y1a[i_out][j] = rotatedY1a[i_out][j] + cy[i_out][j];
328  x1b[i_out][j] = rotatedX1b[i_out][j] + cx[i_out][j];
329  y1b[i_out][j] = rotatedY1b[i_out][j] + cy[i_out][j];
330  x2a[i_out][j] = rotatedX2a[i_out][j] + cx[i_out][j];
331  y2a[i_out][j] = rotatedY2a[i_out][j] + cy[i_out][j];
332  x2b[i_out][j] = rotatedX2b[i_out][j] + cx[i_out][j];
333  y2b[i_out][j] = rotatedY2b[i_out][j] + cy[i_out][j]; */
334 
335  x3a[i_out][j] = (x1a[i_out][j] + x2a[i_out][j]) / 2.0;
336  y3a[i_out][j] = (y1a[i_out][j] + y2a[i_out][j]) / 2.0;
337  x3b[i_out][j] = (x1b[i_out][j] + x2b[i_out][j]) / 2.0;
338  y3b[i_out][j] = (y1b[i_out][j] + y2b[i_out][j]) / 2.0;
339 
340  i_out++;
341 
342  nStripesBefore_R1_e[0] = 0;
343 
344  nStripesIn[j] = keepUntil[j] - keepThisAndAfter[j];
345  if (j == 0)
346  {
347  nStripesBefore[j] = 0;
348  }
349  else
350  {
351  nStripesBefore[j] = nStripesIn[j - 1] + nStripesBefore[j - 1];
352  }
353  nStripesBefore_R1_e[0] = 0;
354  }
355  nGoodStripes[j] = i_out;
356  }
357 }
358 
360  const double x1a[][nRadii], const double x1b[][nRadii],
361  const double x2a[][nRadii], const double x2b[][nRadii],
362  const double y1a[][nRadii], const double y1b[][nRadii],
363  const double y2a[][nRadii], const double y2b[][nRadii],
364  const double x3a[][nRadii], const double y3a[][nRadii],
365  const double x3b[][nRadii], const double y3b[][nRadii],
366  double x, double y, const std::array<int, nRadii>& nGoodStripes) const
367 {
368  int c = 0;
369 
370  for (int j = 0; j < nRadii; j++)
371  {
372  for (int i = 0; i < nGoodStripes[j]; i++)
373  {
374  if (((y1a[i][j] > y) != (y2a[i][j] > y) && (x < (x2a[i][j] - x1a[i][j]) * (y - y1a[i][j]) / (y2a[i][j] - y1a[i][j]) + x1a[i][j])))
375  c = !c;
376  if (((y1b[i][j] > y) != (y1a[i][j] > y) && (x < (x1a[i][j] - x1b[i][j]) * (y - y1b[i][j]) / (y1a[i][j] - y1b[i][j]) + x1b[i][j])))
377  c = !c;
378  if (((y2b[i][j] > y) != (y1b[i][j] > y) && (x < (x1b[i][j] - x2b[i][j]) * (y - y2b[i][j]) / (y1b[i][j] - y2b[i][j]) + x2b[i][j])))
379  c = !c;
380  if (((y2a[i][j] > y) != (y2b[i][j] > y) && (x < (x2b[i][j] - x2a[i][j]) * (y - y2a[i][j]) / (y2b[i][j] - y2a[i][j]) + x2a[i][j])))
381  c = !c;
382 
383  //check inside arcs
384  if (c == 0)
385  {
386  if (((x - x3a[i][j]) * (x - x3a[i][j]) + (y - y3a[i][j]) * (y - y3a[i][j])) <= arc_r * arc_r)
387  {
388  c = !c;
389  }
390  else if (((x - x3b[i][j]) * (x - x3b[i][j]) + (y - y3b[i][j]) * (y - y3b[i][j])) <= arc_r * arc_r)
391  {
392  c = !c;
393  }
394  }
395  }
396  }
397  return c;
398 }
399 
400 int PHG4TpcCentralMembrane::getSearchResult(double xcheck, double ycheck) const
401 {
402  const double phi_petal = M_PI / 9.0; // angle span of one petal
403  const double end_R1_e = 312.0 * mm; // arbitrary radius between R1_e and R1
404  const double end_R1 = 408.0 * mm; // arbitrary radius between R1 and R2
405  const double end_R2 = 580.0 * mm; // arbitrary radius between R2 and R3
406 
407  double r, phi, phimod, xmod, ymod;
408 
409  r = sqrt(xcheck * xcheck + ycheck * ycheck);
410  phi = atan(ycheck / xcheck);
411  if ((xcheck < 0.0) && (ycheck > 0.0))
412  {
413  phi = phi + M_PI;
414  }
415  else if ((xcheck > 0.0) && (ycheck < 0.0))
416  {
417  phi = phi + 2.0 * M_PI;
418  }
419 
420  phimod = fmod(phi, phi_petal);
421  xmod = r * cos(phimod);
422  ymod = r * sin(phimod);
423 
424  int result = 0;
425 
426  if (r <= end_R1_e)
427  {
429  }
430  else if ((r > end_R1_e) && (r <= end_R1))
431  {
433  }
434  else if ((r > end_R1) && (r <= end_R2))
435  {
437  }
438  else if ((r > end_R2) && (r <= end_CM))
439  {
441  }
442 
443  return result;
444 }
445 
446 PHG4Hit* PHG4TpcCentralMembrane::GetPHG4HitFromStripe(int petalID, int moduleID, int radiusID, int stripeID, int nElectrons) const
447 { //this function generates a PHG4 hit using coordinates from a stripe
448  const double phi_petal = M_PI / 9.0; // angle span of one petal
449  PHG4Hit* hit;
450  TVector3 dummyPos0, dummyPos1;
451 
452  //could put in some sanity checks here but probably not necessary since this is only really used within the class
453  //petalID ranges 0-17, module ID 0-3, stripeID varies - nGoodStripes for each module
454  //radiusID ranges 0-7
455 
456  //from phg4tpcsteppingaction.cc
457  hit = new PHG4Hitv1();
458  hit->set_layer(-1); // dummy number
459  //here we set the entrance values in cm
460  if (moduleID == 0)
461  {
462  hit->set_x(0, x3a_R1_e[stripeID][radiusID] / cm);
463  hit->set_y(0, y3a_R1_e[stripeID][radiusID] / cm);
464  }
465  else if (moduleID == 1)
466  {
467  hit->set_x(0, x3a_R1[stripeID][radiusID] / cm);
468  hit->set_y(0, y3a_R1[stripeID][radiusID] / cm);
469  }
470  else if (moduleID == 2)
471  {
472  hit->set_x(0, x3a_R2[stripeID][radiusID] / cm);
473  hit->set_y(0, y3a_R2[stripeID][radiusID] / cm);
474  }
475  else if (moduleID == 3)
476  {
477  hit->set_x(0, x3a_R3[stripeID][radiusID] / cm);
478  hit->set_y(0, y3a_R3[stripeID][radiusID] / cm);
479  }
480  hit->set_z(0, 0.0 / cm);
481 
482  // check if you need to rotate coords to another petal
483  if (petalID > 0)
484  {
485  dummyPos0.SetXYZ(hit->get_x(0), hit->get_y(0), hit->get_z(0));
486  dummyPos0.RotateZ(petalID * phi_petal);
487  hit->set_x(0, dummyPos0.X());
488  hit->set_y(0, dummyPos0.Y());
489  }
490 
491  // TODO: use actual stripe direction for the momentum
492  hit->set_px(1, 500.0);
493  hit->set_py(1, 500.0);
494  hit->set_pz(1, 500.0);
495 
496  // time in ns
497  hit->set_t(0, 0);
498 
499  //set and save the track ID
500  hit->set_trkid(-1); // dummy number
501 
502  // here we just update the exit values, it will be overwritten
503  // for every step until we leave the volume or the particle
504  // ceases to exist
505  if (moduleID == 0)
506  {
507  hit->set_x(1, x3b_R1_e[stripeID][radiusID] / cm);
508  hit->set_y(1, y3b_R1_e[stripeID][radiusID] / cm);
509  }
510  else if (moduleID == 1)
511  {
512  hit->set_x(1, x3b_R1[stripeID][radiusID] / cm);
513  hit->set_y(1, y3b_R1[stripeID][radiusID] / cm);
514  }
515  else if (moduleID == 2)
516  {
517  hit->set_x(1, x3b_R2[stripeID][radiusID] / cm);
518  hit->set_y(1, y3b_R2[stripeID][radiusID] / cm);
519  }
520  else if (moduleID == 3)
521  {
522  hit->set_x(1, x3b_R3[stripeID][radiusID] / cm);
523  hit->set_y(1, y3b_R3[stripeID][radiusID] / cm);
524  }
525  hit->set_z(1, 0.0 / cm);
526 
527  // check if you need to rotate coords to another petal
528  if (petalID > 0)
529  {
530  dummyPos1.SetXYZ(hit->get_x(1), hit->get_y(1), hit->get_z(1));
531  dummyPos1.RotateZ(petalID * phi_petal);
532  hit->set_x(1, dummyPos1.X());
533  hit->set_y(1, dummyPos1.Y());
534  }
535 
536  // TODO: use actual stripe direction for the momentum
537  hit->set_px(1, 500.0);
538  hit->set_py(1, 500.0);
539  hit->set_pz(1, 500.0);
540 
541  hit->set_t(1, 0); // dummy number, nanosecond
542 
543  // calculate deposited energy corresponding to number of electrons per stripe
544  const double edep = nElectrons / electrons_per_gev;
545  hit->set_edep(edep);
546  hit->set_eion(edep);
547 
548  /*
549  if (hit->get_edep()){ //print out hits
550  double rin = sqrt(hit->get_x(0) * hit->get_x(0) + hit->get_y(0) * hit->get_y(0));
551  double rout = sqrt(hit->get_x(1) * hit->get_x(1) + hit->get_y(1) * hit->get_y(1));
552  std::cout << "Added Tpc g4hit with rin, rout = " << rin << " " << rout
553  << " g4hitid " << hit->get_hit_id() << std::endl;
554  std::cout << " xin " << hit->get_x(0)
555  << " yin " << hit->get_y(0)
556  << " zin " << hit->get_z(0)
557  << " rin " << rin
558  << std::endl;
559  std::cout << " xout " << hit->get_x(1)
560  << " yout " << hit->get_y(1)
561  << " zout " << hit->get_z(1)
562  << " rout " << rout
563  << std::endl;
564  std::cout << " xav " << (hit->get_x(1) + hit->get_x(0)) / 2.0
565  << " yav " << (hit->get_y(1) + hit->get_y(0)) / 2.0
566  << " zav " << (hit->get_z(1) + hit->get_z(0)) / 2.0
567  << " rav " << (rout + rin) / 2.0
568  << std::endl;
569  }
570  */
571 
572  return hit;
573 }
574 
575 int PHG4TpcCentralMembrane::getStripeID(double xcheck, double ycheck) const
576 {
577  //check if point came from stripe then see which stripe it is
578  //213 stripes in a petal, 18 petals, ntotstripes = 3834
579  int result;
580  int fullID = -1;
581  //const double adjust = 0.015; //arbitrary angle to center the pattern in a petal
582  const double phi_petal = M_PI / 9.0; // angle span of one petal
583 
584  // check if in a stripe
585  result = getSearchResult(xcheck, ycheck);
586 
587  // find which stripe
588  if (result == 1)
589  {
590  //std::cout << "on a stripe" << std::endl;
591  //convert coords to radius n angle
592  double r = sqrt(xcheck * xcheck + ycheck * ycheck);
593  double phi = atan(ycheck / xcheck);
594  if ((xcheck < 0.0) && (ycheck > 0.0))
595  {
596  phi = phi + M_PI;
597  }
598  else if ((xcheck > 0.0) && (ycheck < 0.0))
599  {
600  phi = phi + 2.0 * M_PI;
601  }
602  //get angle within first petal
603  double phimod = fmod(phi, phi_petal);
604  double xmod = r * cos(phimod);
605  double ymod = r * sin(phimod);
606 
607  int petalID = phi / phi_petal;
608 
609  int phiID = 0;
610  for (int j = 0; j < nRadii; j++)
611  {
612  if (((R1_e[j] - padfrac_R1) < r) && (r < (R1_e[j] + padfrac_R1)))
613  { // check if radius is in stripe
614  int rID = j;
615  std::cout << "rID: " << rID << std::endl;
616  //'angle' is to the center of a stripe
617  for (int i = 0; i < nGoodStripes_R1_e[j]; i++)
618  {
619  //if (j % 2 == 0){
620  //theta = i*spacing[j];
621  //angle = theta + (spacing[j]/2) - adjust;
622  // look at distance from center line of stripe
623  // if distance from x,y to center line < str_width
624  // calculate slope n then do dist
625 
626  double m = (y3b_R1_e[i][j] - y3a_R1_e[i][j]) / (x3b_R1_e[i][j] - x3a_R1_e[i][j]);
627  /*std::cout << "y2: " << y3b_R1_e[i][j] << std::endl;
628  std::cout << "y1: " << y3a_R1_e[i][j] << std::endl;
629  std::cout << "x2: " << x3b_R1_e[i][j] << std::endl;
630  std::cout << "x1: " << x3a_R1_e[i][j] << std::endl;
631  std::cout << "xc: " << xcheck << std::endl;
632  std::cout << "yc: " << ycheck << std::endl;
633  std::cout << "m: " << m << std::endl; */
634  //std::cout << fabs((-m)*xcheck + ycheck) << std::endl;
635  double dist = fabs((-m) * xmod + ymod) / sqrt(1 + m * m);
636  //std::cout << "dist:" << dist << std::endl;
637  if (dist < ((widthmod_R1_e[j] * str_width_R1_e[i][j]) / 2.0))
638  {
639  phiID = i;
640  //std::cout << "phiID: " << phiID << std::endl;
641  }
642  }
643 
644  std::cout << "nStripesBefore: " << nStripesBefore_R1_e[j] << std::endl;
645  fullID = petalID * nStripesPerPetal + nStripesBefore_R1_e[j] + phiID;
646  //std::cout << "fullID: " << fullID << std::endl;
647  }
648  else if (((R1[j] - padfrac_R1) < r) && (r < (R1[j] + padfrac_R1)))
649  {
650  //std::cout << "R1" << std::endl;
651  for (int i = 0; i < nGoodStripes_R1[j]; i++)
652  {
653  // look at distance from center line of stripe
654  double m = (y3b_R1[i][j] - y3a_R1[i][j]) / (x3b_R1[i][j] - x3a_R1[i][j]);
655  double dist = fabs(m * xmod - ymod) / sqrt(1 + m * m);
656  if (dist < ((widthmod_R1[j] * str_width_R1[i][j]) / 2.0))
657  {
658  phiID = i;
659  }
660  }
661 
662  fullID = petalID * nStripesPerPetal + nStripesBefore_R1[j] + phiID;
663  }
664  else if (((R2[j] - padfrac_R2) < r) && (r < (R2[j] + padfrac_R2)))
665  {
666  //std::cout << "R2" << std::endl;
667  for (int i = 0; i < nGoodStripes_R2[j]; i++)
668  {
669  // look at distance from center line of stripe
670  double m = (y3b_R2[i][j] - y3a_R2[i][j]) / (x3b_R2[i][j] - x3a_R2[i][j]);
671  double dist = fabs(m * xmod - ymod) / sqrt(1 + m * m);
672  if (dist < ((widthmod_R2[j] * str_width_R2[i][j]) / 2.0))
673  {
674  phiID = i;
675  }
676  }
677 
678  fullID = petalID * nStripesPerPetal + nStripesBefore_R2[j] + phiID;
679  }
680  else if (((R3[j] - padfrac_R3) < r) && (r < (R3[j] + padfrac_R3)))
681  {
682  //std::cout << "R3" << std::endl;
683  for (int i = 0; i < nGoodStripes_R3[j]; i++)
684  {
685  // look at distance from center line of stripe
686  double m = (y3b_R3[i][j] - y3a_R3[i][j]) / (x3b_R3[i][j] - x3a_R3[i][j]);
687  double dist = fabs(m * xmod - ymod) / sqrt(1 + m * m);
688  if (dist < ((widthmod_R3[j] * str_width_R3[i][j]) / 2.0))
689  {
690  phiID = i;
691  }
692  }
693 
694  fullID = petalID * nStripesPerPetal + nStripesBefore_R3[j] + phiID;
695  }
696  }
697  }
698  else
699  {
700  fullID = -1;
701  }
702 
703  return fullID;
704 }