Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4TpcPadBaselineShift.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4TpcPadBaselineShift.cc
2 
3 #include <trackbase/TpcDefs.h>
4 
5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Wshadow"
7 #include <trackbase/ActsSurfaceMaps.h> // for ActsSurfaceMaps
8 #include <trackbase/ActsTrackingGeometry.h> // for ActsTrackingG...
9 #pragma GCC diagnostic pop
10 
11 #include <trackbase/TrkrClusterContainer.h> // for TrkrClusterCo...
12 #include <trackbase/TrkrClusterHitAssoc.h> // for TrkrClusterHi...
13 #include <trackbase/TrkrHit.h> // for TrkrHit
14 
15 #include <trackbase/TrkrDefs.h> // for hitkey, getLayer
16 #include <trackbase/TrkrHitSet.h>
18 
20 #include <fun4all/SubsysReco.h> // for SubsysReco
21 
24 
25 #include <phool/PHCompositeNode.h>
26 #include <phool/PHNode.h> // for PHNode
27 #include <phool/PHNodeIterator.h>
28 #include <phool/getClass.h>
29 #include <phool/phool.h> // for PHWHERE
30 
31 #include <TF1.h>
32 #include <TFile.h>
33 #include <TTree.h>
34 
35 #include <cmath> // for sqrt, cos, sin
36 #include <iostream>
37 #include <map> // for _Rb_tree_cons...
38 #include <string>
39 #include <utility> // for pair
40 #include <vector>
41 
42 namespace
43 {
44  template <class T>
45  inline constexpr T square(const T &x)
46  {
47  return x * x;
48  }
49 } // namespace
50 
51 int findRBin(float R)
52 {
53  // Finding pad number from the center (bin) for hits
54  int binR = -1;
55  //Realistic binning
56  //double r_bins[r_bins_N+1] = {217.83,
57  // 311.05,317.92,323.31,329.27,334.63,340.59,345.95,351.91,357.27,363.23,368.59,374.55,379.91,385.87,391.23,397.19,402.49,
58  // 411.53,421.70,431.90,442.11,452.32,462.52,472.73,482.94,493.14,503.35,513.56,523.76,533.97,544.18,554.39,564.59,574.76,
59  // 583.67,594.59,605.57,616.54,627.51,638.48,649.45,660.42,671.39,682.36,693.33,704.30,715.27,726.24,737.21,748.18,759.11};
60  const int r_bins_N = 53;
61  double r_bins[r_bins_N + 1];
62  r_bins[0] = 30.3125;
63  double bin_width = 0.625;
64  for (int i = 1; i < r_bins_N; i++)
65  {
66  if (i == 16) bin_width = 0.9375;
67  if (i > 16) bin_width = 1.25;
68  if (i == 31) bin_width = 1.1562;
69  if (i > 31) bin_width = 1.0624;
70 
71  r_bins[i] = r_bins[i - 1] + bin_width;
72  }
73 
74  double R_min = 30;
75  while (R > R_min)
76  {
77  binR += 1;
78  R_min = r_bins[binR];
79  }
80  return binR;
81 }
82 
83 //____________________________________________________________________________..
85  : SubsysReco(name)
86 {
87  std::cout << "PHG4TpcPadBaselineShift::PHG4TpcPadBaselineShift(const std::string &name) Calling ctor" << std::endl;
88 }
89 
91 {
92  bool reject_it = false;
93 
94  // sector boundaries occur every 1/12 of the full phi bin range
95  int PhiBins = layergeom->get_phibins();
96  int PhiBinsSector = PhiBins / 12;
97 
98  double radius = layergeom->get_radius();
99  double PhiBinSize = 2.0 * radius * M_PI / (double) PhiBins;
100 
101  // sector starts where?
102  int sector_lo = sector * PhiBinsSector;
103  int sector_hi = sector_lo + PhiBinsSector - 1;
104 
105  int sector_fiducial_bins = (int) (SectorFiducialCut / PhiBinSize);
106 
107  if (phibin < sector_lo + sector_fiducial_bins || phibin > sector_hi - sector_fiducial_bins)
108  {
109  reject_it = true;
110  }
111 
112  return reject_it;
113 }
114 //____________________________________________________________________________..
116 {
117  std::cout << "PHG4TpcPadBaselineShift::~PHG4TpcPadBaselineShift() Calling dtor" << std::endl;
118 }
119 
120 //____________________________________________________________________________..
122 {
123  //outfile = new TFile(_filename.c_str(), "RECREATE");
124  _hit_z = 0;
125  _hit_r = 0;
126  _hit_phi = 0;
127  _hit_e = 0;
128  _hit_adc = 0;
129  _hit_adc_bls = 0;
130  _hit_layer = -1;
131  _hit_sector = -1;
132  if (_writeTree == 1)
133  {
134  outfile = new TFile(_filename.c_str(), "RECREATE");
135  _rawHits = new TTree("hTree", "tpc hit tree for base-line shift tests");
136  _rawHits->Branch("z", &_hit_z);
137  _rawHits->Branch("r", &_hit_r);
138  _rawHits->Branch("phi", &_hit_phi);
139  _rawHits->Branch("e", &_hit_e);
140  _rawHits->Branch("adc", &_hit_adc);
141  _rawHits->Branch("adc_BLS", &_hit_adc_bls);
142  _rawHits->Branch("hit_layer", &_hit_layer);
143  _rawHits->Branch("_hit_sector", &_hit_sector);
144  }
145  return 0;
146  //std::cout << "PHG4TpcPadBaselineShift::Init(PHCompositeNode *topNode) Initializing" << std::endl;
147  //return Fun4AllReturnCodes::EVENT_OK;
148 }
149 
150 //____________________________________________________________________________..
152 {
153  PHNodeIterator iter(topNode);
154 
155  // Looking for the DST node
156  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
157  if (!dstNode)
158  {
159  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
161  }
162 
163  std::cout << "PHG4TpcPadBaselineShift::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl;
165 }
166 
167 //____________________________________________________________________________..
169 {
170  // int print_layer = 18;
171 
172  if (Verbosity() > 1000)
173  {
174  std::cout << "PHG4TpcPadBaselineShift::Process_Event" << std::endl;
175  }
176 
177  PHNodeIterator iter(topNode);
178  PHCompositeNode *dstNode = static_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
179  if (!dstNode)
180  {
181  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
183  }
184 
185  // get node containing the digitized hits
186  m_hits = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
187  if (!m_hits)
188  {
189  std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl;
191  }
192 
193  // get node for clusters
194  m_clusterlist = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
195  if (!m_clusterlist)
196  {
197  std::cout << PHWHERE << " ERROR: Can't find TRKR_CLUSTER." << std::endl;
199  }
200 
201  // get node for cluster hit associations
202  m_clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode, "TRKR_CLUSTERHITASSOC");
203  if (!m_clusterhitassoc)
204  {
205  std::cout << PHWHERE << " ERROR: Can't find TRKR_CLUSTERHITASSOC" << std::endl;
207  }
208 
209  PHG4TpcCylinderGeomContainer *geom_container =
210  findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode, "CYLINDERCELLGEOM_SVTX");
211  if (!geom_container)
212  {
213  std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl;
215  }
216 
217  m_tGeometry = findNode::getClass<ActsTrackingGeometry>(topNode,
218  "ActsTrackingGeometry");
219  if (!m_tGeometry)
220  {
221  std::cout << PHWHERE
222  << "ActsTrackingGeometry not found on node tree. Exiting"
223  << std::endl;
225  }
226 
227  m_surfMaps = findNode::getClass<ActsSurfaceMaps>(topNode,
228  "ActsSurfaceMaps");
229  if (!m_surfMaps)
230  {
231  std::cout << PHWHERE
232  << "ActsSurfaceMaps not found on node tree. Exiting"
233  << std::endl;
235  }
236 
237  // The hits are stored in hitsets, where each hitset contains all hits in a given TPC readout (layer, sector, side), so clusters are confined to a hitset
238  // The TPC clustering is more complicated than for the silicon, because we have to deal with overlapping clusters
239 
240  // loop over the TPC HitSet objects
242  //const int num_hitsets = std::distance(hitsetrange.first,hitsetrange.second);
243 
244  //Loop over R positions & sectors
245  for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first;
246  hitsetitr != hitsetrange.second;
247  ++hitsetitr)
248  {
249  TrkrHitSet *hitset = hitsetitr->second;
250  unsigned int layer = TrkrDefs::getLayer(hitsetitr->first);
251  int side = TpcDefs::getSide(hitsetitr->first);
252  unsigned int sector = TpcDefs::getSectorId(hitsetitr->first);
253  PHG4TpcCylinderGeom *layergeom = geom_container->GetLayerCellGeom(layer);
254 
255  _hit_sector = sector;
256  _hit_layer = layer;
257 
258  double radius = layergeom->get_radius(); //in cm
259 
260  _hit_r = radius;
261 
262  unsigned short NPhiBins = (unsigned short) layergeom->get_phibins();
263  unsigned short NPhiBinsSector = NPhiBins / 12;
264  unsigned short NZBins = (unsigned short) layergeom->get_zbins();
265  unsigned short NZBinsSide = NZBins / 2;
266  unsigned short NZBinsMin = 0;
267  unsigned short PhiOffset = NPhiBinsSector * sector;
268 
269  if (side == 0)
270  {
271  NZBinsMin = 0;
272  NZBinsMax = NZBins / 2 - 1;
273  }
274  else
275  {
276  NZBinsMin = NZBins / 2;
277  NZBinsMax = NZBins;
278  }
279  unsigned short ZOffset = NZBinsMin;
280  //Gives per pad ADC for particular R and sector in event
281  int perPadADC = 0;
282  unsigned short phibins = NPhiBinsSector;
283  unsigned short phioffset = PhiOffset;
284  unsigned short zbins = NZBinsSide;
285  unsigned short zoffset = ZOffset;
286  float sumADC = perPadADC; // 14 lines later just set to zero
287 
288  //phibins - number of pads in the sector
289  //The Sampa clock time is 18.8 MHz, so the sampling time is 53.2 ns = 1 Z bin.
290  //The Z bin range for one side of the TPC is 0-248.
291  //Check: 249 bins x 53.2 ns = 13.2 microseconds.
292  //The maximum drift time in the TPC is 13.2 microseconds.
293  //So, 53.2 ns / Z bin.
294 
295  TF1 *f1 = new TF1("f1", "[0]*exp(-(x-[1])/[2])", 0, 1000);
296  f1->SetParameter(0, 0.005);
297  f1->SetParameter(1, 0);
298  f1->SetParameter(2, 60); // in terms of 50nsec time bins
299 
300  // sumADC=0.; // this is set to zero 14 lines up (perPadADC is zero)
301  TrkrHitSet::ConstRange hitrangei = hitset->getHits();
302 
303  std::vector<unsigned short> adcval(zbins, 0);
304  // std::multimap<unsigned short, ihit> all_hit_map;
305  // std::vector<ihit> hit_vect;
306  // Loop over phi & z
307  for (TrkrHitSet::ConstIterator hitr = hitrangei.first; hitr != hitrangei.second; ++hitr)
308  {
309  unsigned short phibin = TpcDefs::getPad(hitr->first) - phioffset;
310  unsigned short zbin = TpcDefs::getTBin(hitr->first) - zoffset;
311  float_t fadc = (hitr->second->getAdc()); // proper int rounding +0.5
312  unsigned short adc = 0;
313  if (fadc > 0)
314  {
315  adc = (unsigned short) fadc;
316  }
317  if (phibin >= phibins) continue;
318  if (zbin >= zbins) continue; // zbin is unsigned int, <0 cannot happen
319  adcval[zbin] = (unsigned short) adc;
320  sumADC += adc;
321  }
322  //Define ion-induced charge
323  sumADC /= phibins;
324  float ind_charge = -0.5 * sumADC * _CScale; //CScale is the coefficient related to the capacitance of the bottom layer of the bottom GEM
325  double pi = M_PI;
326 
327  for (TrkrHitSet::ConstIterator hitr = hitrangei.first; hitr != hitrangei.second; ++hitr)
328  {
329  unsigned short phibin = TpcDefs::getPad(hitr->first);
330  unsigned short tbin = TpcDefs::getTBin(hitr->first);
331  // Get the hitkey
333  TrkrHit *hit = nullptr;
334  hit = hitsetitr->second->getHit(hitkey);
335 
336  tbin = TpcDefs::getTBin(hitr->first);
337  phibin = TpcDefs::getPad(hitr->first);
338  double phi_center = layergeom->get_phicenter(phibin);
339  if (phi_center < 0) phi_center += 2 * pi;
340  _hit_phi = phi_center;
341  _hit_z = AdcClockPeriod * MaxTBins * _drift_velocity / 2.0 - layergeom->get_zcenter(tbin) * _drift_velocity;
342  if(side == 0) _hit_z *= -1.0;
343 
344  if (hit) _hit_e = hit->getEnergy();
345  _hit_adc = 0;
346  _hit_adc_bls = 0;
347 
348  float_t fadc = (hitr->second->getAdc()); // proper int rounding +0.5
349  _hit_adc = fadc;
350  _hit_adc_bls = _hit_adc + int(ind_charge);
351 
352  if (hit && _hit_adc > 0)
353  {
354  //Trkr hit has only one value m_adc which is energy and ADC at the same time
355  if (_hit_adc_bls > 0)
356  {
357  hit->setAdc(_hit_adc_bls);
358  }
359  else
360  {
361  hit->setAdc(0);
362  }
363  }
364  if (_writeTree == 1) _rawHits->Fill();
365  }
366 
367  //hitsetitr++;
368  }
369 
370  //pthread_attr_destroy(&attr);
371 
372  // wait for completion of all threads
373  //for( const auto& thread_pair:threads )
374  //{
375  // int rc2 = pthread_join(thread_pair.thread, nullptr);
376  // if (rc2)
377  // { std::cout << "Error:unable to join," << rc2 << std::endl; }
378  //}
379 
380  if (Verbosity() > 0)
381  std::cout << "TPC Clusterizer found " << m_clusterlist->size() << " Clusters " << std::endl;
382  std::cout << "PHG4TpcPadBaselineShift::process_event(PHCompositeNode *topNode) Processing Event" << std::endl;
384 }
385 
386 //____________________________________________________________________________..
387 //int PHG4TpcPadBaselineShift::ResetEvent(PHCompositeNode *topNode)
388 //{
389 // std::cout << "PHG4TpcPadBaselineShift::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl;
390 // return Fun4AllReturnCodes::EVENT_OK;
391 //}
392 
393 //____________________________________________________________________________..
394 //int PHG4TpcPadBaselineShift::EndRun(const int runnumber)
395 //{
396 // std::cout << "PHG4TpcPadBaselineShift::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl;
397 // return Fun4AllReturnCodes::EVENT_OK;
398 //}
399 
400 //____________________________________________________________________________..
402 {
403  if (_writeTree == 1)
404  {
405  outfile->cd();
406  outfile->Write();
407  outfile->Close();
408  std::cout << "PHG4TpcPadBaselineShift::End(PHCompositeNode *topNode) This is the End..." << std::endl;
409  }
410  //return 0;
412 }
413 
414 //____________________________________________________________________________..
415 //int PHG4TpcPadBaselineShift::Reset(PHCompositeNode *topNode)
416 //{
417 // std::cout << "PHG4TpcPadBaselineShift::Reset(PHCompositeNode *topNode) being Reset" << std::endl;
418 // return Fun4AllReturnCodes::EVENT_OK;
419 //}
420 
421 //____________________________________________________________________________..
422 //void PHG4TpcPadBaselineShift::Print(const std::string &what) const
423 //{
424 // std::cout << "PHG4TpcPadBaselineShift::Print(const std::string &what) const Printing info for " << what << std::endl;
425 //}
427 {
428  _CScale = CScale;
429  std::cout << "PHG4TpcPadBaselineShift::setFileName: Scale factor is set to:" << CScale << std::endl;
430 }
432 {
434  std::cout << "PHG4TpcPadBaselineShift::setFileName: Output file name for PHG4TpcPadBaselineShift is set to:" << filename << std::endl;
435 }
437 {
438  _writeTree = f_writeTree;
439  std::cout << "PHG4TpcPadBaselineShift::writeTree: True" << std::endl;
440 }