Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RawClusterBuilderTemplate.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RawClusterBuilderTemplate.cc
2 
3 #include "BEmcCluster.h"
4 #include "BEmcRec.h"
5 #include "BEmcRecCEMC.h"
6 
11 
12 #include <calobase/RawCluster.h>
13 #include <calobase/RawClusterContainer.h>
14 #include <calobase/RawClusterv1.h>
15 #include <calobase/RawTower.h>
16 #include <calobase/RawTowerContainer.h>
17 #include <calobase/RawTowerDefs.h>
18 #include <calobase/RawTowerGeom.h>
19 #include <calobase/RawTowerGeomContainer.h>
20 #include <calobase/TowerInfo.h>
21 #include <calobase/TowerInfoContainer.h>
22 
24 
26 #include <fun4all/SubsysReco.h>
27 
28 #include <phool/PHCompositeNode.h>
29 #include <phool/PHIODataNode.h>
30 #include <phool/PHNode.h>
31 #include <phool/PHNodeIterator.h>
32 #include <phool/PHObject.h>
33 #include <phool/getClass.h>
34 #include <phool/phool.h>
35 
36 #include <cmath>
37 #include <exception>
38 #include <fstream>
39 #include <iostream>
40 #include <map>
41 #include <stdexcept>
42 #include <utility>
43 #include <vector>
44 
46  : SubsysReco(name)
47 {
48 }
49 
51 {
52  // one can delete null pointers
53  delete bemc;
54 }
55 
57 {
58  detector = d;
59 
60  // Create proper BEmcRec object
61 
62  if (detector == "CEMC")
63  {
64  bemc = new BEmcRecCEMC();
65  }
66  else
67  {
68  std::cout << "Warning from RawClusterBuilderTemplate::Detector(): no detector specific class "
69  << Name() << " defined for detector " << detector
70  << ". Default BEmcRec will be used" << std::endl;
71  bemc = new BEmcRec();
72  }
73 
74  // Set vertex
75  float vertex[3] = {0, 0, 0};
76  bemc->SetVertex(vertex);
77  // Set threshold
80 }
81 
83 {
84  std::string url = CDBInterface::instance()->getUrl("EMCPROFILE", fname);
85  bemc->LoadProfile(url);
86 }
87 
89 {
90  if (bemc == nullptr)
91  {
92  std::cout << "Error in RawClusterBuilderTemplate::SetCylindricalGeometry()(): detector is not defined; use RawClusterBuilderTemplate::Detector() to define it" << std::endl;
93  return;
94  }
95 
97 }
98 
100 {
101  if (bemc == nullptr)
102  {
103  std::cout << "Error in RawClusterBuilderTemplate::SetPlanarGeometry()(): detector is not defined; use RawClusterBuilderTemplate::Detector() to define it" << std::endl;
104  return;
105  }
106 
108 }
109 
111 {
112  if (bemc == nullptr)
113  {
114  std::cout << "Error in RawClusterBuilderTemplate::InitRun(): detector is not defined; use RawClusterBuilderTemplate::Detector() to define it" << std::endl;
116  }
117 
118  try
119  {
120  CreateNodes(topNode);
121  }
122  catch (std::exception &e)
123  {
124  std::cout << PHWHERE << ": " << e.what() << std::endl;
125  throw;
126  }
127 
128  std::string towergeomnodename = "TOWERGEOM_" + detector;
129  RawTowerGeomContainer *towergeom = findNode::getClass<RawTowerGeomContainer>(topNode, towergeomnodename);
130  if (!towergeom)
131  {
132  std::cout << PHWHERE << ": Could not find node " << towergeomnodename << std::endl;
134  }
135 
136  int Calo_ID = towergeom->get_calorimeter_id();
137  // std::cout << std::endl << std::endl << std::endl << "Calorimeter ID: " << Calo_ID << std::endl << std::endl << std::endl;
138 
139  int ngeom = 0;
140  int ixmin = 999999;
141  int ixmax = -999999;
142  int iymin = 999999;
143  int iymax = -999999;
144  RawTowerGeomContainer::ConstRange begin_end_geom = towergeom->get_tower_geometries();
145  RawTowerGeomContainer::ConstIterator itr_geom = begin_end_geom.first;
146  for (; itr_geom != begin_end_geom.second; ++itr_geom)
147  {
148  RawTowerGeom *towerg = itr_geom->second;
150  int ix = RawTowerDefs::decode_index2(towerid); // index2 is phi in CYL
151  int iy = RawTowerDefs::decode_index1(towerid); // index1 is eta in CYL
152  if (ixmin > ix)
153  {
154  ixmin = ix;
155  }
156  if (ixmax < ix)
157  {
158  ixmax = ix;
159  }
160  if (iymin > iy)
161  {
162  iymin = iy;
163  }
164  if (iymax < iy)
165  {
166  iymax = iy;
167  }
168  ngeom++;
169  }
170  if (Verbosity() > 1)
171  {
172  std::cout << "Info from RawClusterBuilderTemplate::InitRun(): Init geometry for "
173  << detector << ": N of geom towers: " << ngeom << "; ix = "
174  << ixmin << "-" << ixmax << ", iy = "
175  << iymin << "-" << iymax << std::endl;
176  }
177  if (ixmax < ixmin || iymax < iymin)
178  {
179  std::cout << "Error in RawClusterBuilderTemplate::InitRun(): wrong geometry data for detector "
180  << detector << std::endl;
182  }
183 
184  BINX0 = ixmin;
185  NBINX = ixmax - ixmin + 1;
186  BINY0 = iymin;
187  NBINY = iymax - iymin + 1;
188 
189  bemc->SetDim(NBINX, NBINY);
190 
191  itr_geom = begin_end_geom.first;
192  for (; itr_geom != begin_end_geom.second; ++itr_geom)
193  {
194  RawTowerGeom *towerg = itr_geom->second;
196  // int itype = towerg->get_tower_type();
197  // if( itype==2 ) { // PbSc
198  int ix = RawTowerDefs::decode_index2(towerid); // index2 is phi in CYL
199  int iy = RawTowerDefs::decode_index1(towerid); // index1 is eta in CYL
200  ix -= BINX0;
201  iy -= BINY0;
202 
203  bemc->SetTowerGeometry(ix, iy, towerg->get_center_x(), towerg->get_center_y(), towerg->get_center_z());
204  bemc->SetCalotype(Calo_ID);
205  if (Calo_ID == RawTowerDefs::EEMC ||
206  Calo_ID == RawTowerDefs::EEMC_crystal ||
207  Calo_ID == RawTowerDefs::EEMC_glass)
208  {
209  bemc->SetScinSize(towerg->get_size_z());
210  }
211  }
212 
213  if (!bemc->CompleteTowerGeometry())
214  {
216  }
217 
218  if (bPrintGeom)
219  {
220  std::string fname = "geom_" + detector + ".txt";
221  // bemc->PrintTowerGeometry("geom.txt");
222  bemc->PrintTowerGeometry(fname);
223  // PrintCylGeom(towergeom,"phieta.txt");
224  }
225 
227 }
228 
230 {
231  std::ofstream outfile(fname);
232  if (!outfile.is_open())
233  {
234  std::cout << "Error in BEmcRec::RawClusterBuilderTemplate::PrintCylGeom(): Failed to open file "
235  << fname << std::endl;
236  return;
237  }
238  outfile << NBINX << " " << NBINY << std::endl;
239  for (int ip = 0; ip < NBINX; ip++)
240  {
241  outfile << ip << " " << towergeom->get_phicenter(ip) << std::endl;
242  }
243  for (int ip = 0; ip < NBINY; ip++)
244  {
245  outfile << ip << " " << towergeom->get_etacenter(ip) << std::endl;
246  }
247  outfile.close();
248 }
249 
250 bool RawClusterBuilderTemplate::Cell2Abs(RawTowerGeomContainer * /*towergeom*/, float /*phiC*/, float /*etaC*/, float &phi, float &eta)
251 {
252  phi = eta = 0;
253  return false;
254 }
255 
257 {
258  if (bemc == nullptr)
259  {
260  std::cout << "Error in RawClusterBuilderTemplate::process_event(): detector is not defined; use RawClusterBuilderTemplate::Detector() to define it" << std::endl;
262  }
263 
264  RawTowerContainer *towers = nullptr;
265  if (m_UseTowerInfo < 1)
266  {
267  std::string towernodename = "TOWER_CALIB_" + detector;
268 
269  // Grab the towers
270  towers = findNode::getClass<RawTowerContainer>(topNode, towernodename);
271  if (!towers)
272  {
273  std::cout << PHWHERE << ": Could not find node " << towernodename << std::endl;
275  }
276  }
277 
278  std::string towergeomnodename = "TOWERGEOM_" + detector;
279  RawTowerGeomContainer *towergeom = findNode::getClass<RawTowerGeomContainer>(topNode, towergeomnodename);
280  if (!towergeom)
281  {
282  std::cout << PHWHERE << ": Could not find node " << towergeomnodename << std::endl;
284  }
285  TowerInfoContainer *calib_towerinfos = nullptr;
286  if (m_UseTowerInfo > 0)
287  {
288  std::string towerinfoNodename = "TOWERINFO_CALIB_" + detector;
289  if (!m_inputnodename.empty())
290  {
291  towerinfoNodename = m_inputnodename;
292  }
293 
294  calib_towerinfos = findNode::getClass<TowerInfoContainer>(topNode, towerinfoNodename);
295  if (!calib_towerinfos)
296  {
297  std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__
298  << " " << towerinfoNodename << " Node missing, doing bail out!"
299  << std::endl;
300 
302  }
303  }
304 
305  // Get vertex
306  float vx = 0;
307  float vy = 0;
308  float vz = 0;
309  GlobalVertexMap *vertexmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
310 
311  if (vertexmap && m_UseAltZVertex == 0) // default
312  {
313  if (!vertexmap->empty())
314  {
315  GlobalVertex *vertex = (vertexmap->begin()->second);
316  vx = vertex->get_x();
317  vy = vertex->get_y();
318  vz = vertex->get_z();
319  }
320  }
321 
322  MbdVertexMap *mbdmap = findNode::getClass<MbdVertexMap>(topNode, "MbdVertexMap");
323 
324  if (mbdmap && m_UseAltZVertex == 1)
325  {
326  std::cout << " in mbdmap " << std::endl;
327 
328  MbdVertex *bvertex = nullptr;
329  for (MbdVertexMap::ConstIter mbditer = mbdmap->begin();
330  mbditer != mbdmap->end();
331  ++mbditer)
332  {
333  bvertex = mbditer->second;
334  }
335  // MbdVertex *bvertex = (mbdmap->begin()->second);
336 
337  if (!bvertex)
338  {
340  }
341 
342  vz = bvertex->get_z();
343  }
344 
345  // Set vertex
346  float vertex[3] = {vx, vy, vz};
347  bemc->SetVertex(vertex);
348  // Set threshold
350 
353 
354  _clusters->Reset(); // make sure cluster container is empty before filling it with new clusters
355 
356  // Define vector of towers in EmcModule format to input into BEmc
357  EmcModule vhit;
358  std::vector<EmcModule> HitList;
359  HitList.erase(HitList.begin(), HitList.end());
360  int ich;
361 
362  if (m_UseTowerInfo < 1)
363  {
364  // make the list of towers above threshold
365  RawTowerContainer::ConstRange begin_end = towers->getTowers();
366  RawTowerContainer::ConstIterator itr = begin_end.first;
367 
368  for (; itr != begin_end.second; ++itr)
369  {
370  RawTower *tower = itr->second;
371  // std::cout << " Tower e = " << tower->get_energy()
372  // << " (" << _min_tower_e << ")" << std::endl;
373  if (IsAcceptableTower(tower))
374  {
375  // std::cout << "(" << tower->get_column() << "," << tower->get_row()
376  // << ") (" << tower->get_binphi() << "," << tower->get_bineta()
377  // << ")" << std::endl;
378  // ix = tower->get_column();
380  int ix = RawTowerDefs::decode_index2(towerid); // index2 is phi in CYL
381  int iy = RawTowerDefs::decode_index1(towerid); // index1 is eta in CYL
382  ix -= BINX0;
383  iy -= BINY0;
384  // ix = tower->get_bineta() - BINX0; // eta: index1
385  // iy = tower->get_binphi() - BINY0; // phi: index2
386  if (ix >= 0 && ix < NBINX && iy >= 0 && iy < NBINY)
387  {
388  ich = iy * NBINX + ix;
389  vhit.ich = ich;
390  vhit.amp = tower->get_energy() * fEnergyNorm; // !!! Global Calibration
391  vhit.tof = 0.;
392  HitList.push_back(vhit);
393  }
394  }
395  }
396  }
397  else if (m_UseTowerInfo)
398  {
399  // make the list of towers above threshold
400  // TowerInfoContainer::ConstRange begin_end = calib_towerinfos->getTowers();
401  // TowerInfoContainer::ConstIterator rtiter;
402  unsigned int nchannels = calib_towerinfos->size();
403  // for (rtiter = begin_end.first; rtiter != begin_end.second; ++rtiter)
404  for (unsigned int channel = 0; channel < nchannels; channel++)
405  {
406  TowerInfo *tower_info = calib_towerinfos->get_tower_at_channel(channel);
407 
408  // std::cout << " Tower e = " << tower->get_energy()
409  // << " (" << _min_tower_e << ")" << std::endl;
410  if (IsAcceptableTower(tower_info))
411  {
412  unsigned int towerkey = calib_towerinfos->encode_key(channel);
413  int ieta = calib_towerinfos->getTowerEtaBin(towerkey);
414  int iphi = calib_towerinfos->getTowerPhiBin(towerkey);
415 
417 
418  int ix = RawTowerDefs::decode_index2(key); // index2 is phi in CYL
419  int iy = RawTowerDefs::decode_index1(key); // index1 is eta in CYL
420 
421  ix -= BINX0;
422  iy -= BINY0;
423 
424  if (ix >= 0 && ix < NBINX && iy >= 0 && iy < NBINY)
425  {
426  ich = iy * NBINX + ix;
427  // add key field to vhit
428  vhit.ich = ich;
429  vhit.amp = tower_info->get_energy() * fEnergyNorm; // !!! Global Calibration
430  vhit.tof = tower_info->get_time();
431 
432  HitList.push_back(vhit);
433  }
434  }
435  }
436  }
437 
438  bemc->SetModules(&HitList);
439 
440  // Find clusters (as a set of towers with common edge)
441  int ncl = bemc->FindClusters();
442  if (ncl < 0)
443  {
444  std::cout << "!!! Error in BEmcRec::FindClusters(): numbers of cluster "
445  << ncl << " ?" << std::endl;
447  }
448 
449  // Get pointer to clusters
450  std::vector<EmcCluster> *ClusterList = bemc->GetClusters();
451  std::vector<EmcCluster>::iterator pc;
452 
453  std::vector<EmcCluster>::iterator pp;
454  float ecl, ecore, xcg, ycg, xx, xy, yy;
455  // float xcorr, ycorr;
456  EmcModule hmax;
457  RawCluster *cluster;
458 
459  std::vector<EmcCluster> PList;
460  std::vector<EmcModule> Peaks;
461 
462  float prob, chi2;
463  int ndf;
464  float xg, yg, zg;
465 
466  std::vector<EmcModule>::iterator ph;
467  std::vector<EmcModule> hlist;
468 
469  // ncl = 0;
470  for (pc = ClusterList->begin(); pc != ClusterList->end(); ++pc)
471  {
472  // ecl = pc->GetTotalEnergy();
473  // pc->GetMoments( &xcg, &ycg, &xx, &xy, &yy );
474 
475  int npk = pc->GetSubClusters(PList, Peaks);
476  if (npk < 0)
477  {
479  }
480 
481  // std::cout << " iCl = " << ncl << " (" << npk << "): E ="
482  // << ecl << " x = " << xcg << " y = " << ycg << std::endl;
483 
484  for (pp = PList.begin(); pp != PList.end(); ++pp)
485  {
486  // Cluster energy
487  ecl = pp->GetTotalEnergy();
488  ecore = pp->GetECoreCorrected();
489  // 3x3 energy around center of gravity
490  // e9 = pp->GetE9();
491  // Ecore (basically near 2x2 energy around center of gravity)
492  // ecore = pp->GetECore();
493  // Center of Gravity etc.
494  pp->GetMoments(xcg, ycg, xx, xy, yy);
495 
496  if (m_UseAltZVertex == 2)
497  {
498  xg = -99999; // signal to force zvtx = 0
499  pp->GetGlobalPos(xg, yg, zg);
500  }
501  else
502  {
503  xg = 0; // usual mode, uses regular zvtx
504  pp->GetGlobalPos(xg, yg, zg);
505  }
506 
507  // Tower with max energy
508  hmax = pp->GetMaxTower();
509 
510  // phi = (xcg-float(NPHI)/2.+0.5)/float(NPHI)*2.*M_PI;
511  // eta = (ycg-float(NETA)/2.+0.5)/float(NETA)*2.2; // -1.1<eta<1.1;
512 
513  // Cell2Abs(towergeom,xcg,ycg,phi,eta);
514 
515  // pp->GetCorrPos(&xcorr, &ycorr);
516  // Cell2Abs(towergeom, xcorr, ycorr, phi, eta);
517  // const double ref_radius = towergeom->get_radius();
518 
519  // phi = 0;
520  // if (phi > M_PI) phi -= 2. * M_PI; // convert to [-pi,pi]]
521 
522  // prob = -1;
523  chi2 = 0;
524  ndf = 0;
525  prob = pp->GetProb(chi2, ndf);
526  // std::cout << "Prob/Chi2/NDF = " << prob << " " << chi2
527  // << " " << ndf << " Ecl = " << ecl << std::endl;
528 
529  cluster = new RawClusterv1();
530  cluster->set_energy(ecl);
531  cluster->set_ecore(ecore);
532 
533  cluster->set_r(std::sqrt(xg * xg + yg * yg));
534  cluster->set_phi(std::atan2(yg, xg));
535  cluster->set_z(zg);
536 
537  cluster->set_prob(prob);
538  if (ndf > 0)
539  {
540  cluster->set_chi2(chi2 / ndf);
541  }
542  else
543  {
544  cluster->set_chi2(0);
545  }
546  hlist = pp->GetHitList();
547  ph = hlist.begin();
548  while (ph != hlist.end())
549  {
550  ich = (*ph).ich;
551  int iy = ich / NBINX;
552  int ix = ich % NBINX;
553  // that code needs a closer look - here are the towers
554  // with their energy added to the cluster object where
555  // the id is the tower id
556  // !!!!! Make sure twrkey is correctly extracted
557  // RawTowerDefs::keytype twrkey = RawTowerDefs::encode_towerid(towers->getCalorimeterID(), ix + BINX0, iy + BINY0);
558  const RawTowerDefs::CalorimeterId Calo_ID = towergeom->get_calorimeter_id();
559  RawTowerDefs::keytype twrkey = RawTowerDefs::encode_towerid(Calo_ID, iy + BINY0, ix + BINX0); // Becuase in this part index1 is iy
560  // std::cout << iphi << " " << ieta << ": "
561  // << twrkey << " e = " << (*ph).amp) << std::endl;
562  cluster->addTower(twrkey, (*ph).amp / fEnergyNorm);
563  ++ph;
564  }
565 
566  _clusters->AddCluster(cluster);
567  // ncl++;
568 
569  // std::cout << " ipk = " << ipk << ": E = " << ecl << " E9 = "
570  // << e9 << " x = " << xcg << " y = " << ycg
571  // << " MaxTower: (" << hmax.ich%NPHI << ","
572  // << hmax.ich/NPHI << ") e = " << hmax.amp << std::endl;
573  }
574  }
575 
576  if (chkenergyconservation && towers && _clusters)
577  {
578  double ecluster = _clusters->getTotalEdep();
579  double etower = towers->getTotalEdep();
580  if (ecluster > 0)
581  {
582  if (fabs(etower - ecluster) / ecluster > 1e-9)
583  {
584  std::cout << "energy conservation violation: ETower: " << etower
585  << " ECluster: " << ecluster
586  << " diff: " << etower - ecluster << std::endl;
587  }
588  }
589  else
590  {
591  if (etower != 0)
592  {
593  std::cout << "energy conservation violation: ETower: " << etower
594  << " ECluster: " << ecluster << std::endl;
595  }
596  }
597  }
598  else if (chkenergyconservation)
599  {
600  std::cout << "RawClusterBuilderTemplate : energy conservation check asked for but tower or cluster container is NULL" << std::endl;
601  }
602 
604 }
605 
607 {
608  PHNodeIterator iter(topNode);
609 
610  // Grab the cEMC node
611  PHCompositeNode *dstNode = static_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
612  if (!dstNode)
613  {
614  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
615  throw std::runtime_error("Failed to find DST node in EmcRawTowerBuilder::CreateNodes");
616  }
617 
618  // Get the _det_name subnode
619  PHCompositeNode *cemcNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", detector));
620 
621  // Check that it is there
622  if (!cemcNode)
623  {
624  cemcNode = new PHCompositeNode(detector);
625  dstNode->addNode(cemcNode);
626  }
627 
629  ClusterNodeName = "CLUSTER_" + detector;
630 
631  if (!m_outputnodename.empty())
632  {
634  }
635  else if (m_UseTowerInfo)
636  {
637  ClusterNodeName = "CLUSTERINFO_" + detector;
638  }
639 
641  cemcNode->addNode(clusterNode);
642 }
643 
645 {
646  if(tower->get_energy() < _min_tower_e)
647  {
648  return false;
649  }
650 
652  {
653  if(tower->get_isBadTime())
654  {
655  return false;
656  }
657 
658  if(tower->get_isHot())
659  {
660  return false;
661  }
662 
663  if(tower->get_isBadChi2())
664  {
665  return false;
666  }
667 
668  if(tower->get_isNotInstr())
669  {
670  return false;
671  }
672  }
673  return true;
674 }
675 
677 {
678  if(tower->get_energy() < _min_tower_e)
679  {
680  return false;
681  }
682  return true;
683 }