Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CaloAna.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CaloAna.cc
1 #include "CaloAna.h"
2 
3 // G4Hits includes
4 #include <TLorentzVector.h>
5 #include <g4main/PHG4Hit.h>
7 
8 // G4Cells includes
9 #include <g4detectors/PHG4Cell.h>
11 
12 // Tower includes
13 #include <calobase/RawCluster.h>
14 #include <calobase/RawClusterContainer.h>
15 #include <calobase/RawClusterUtility.h>
16 #include <calobase/RawTower.h>
17 #include <calobase/RawTowerContainer.h>
18 #include <calobase/RawTowerGeom.h>
19 #include <calobase/RawTowerGeomContainer.h>
20 #include <calobase/TowerInfo.h>
21 #include <calobase/TowerInfoContainer.h>
22 #include <calobase/TowerInfoDefs.h>
23 
24 // Cluster includes
25 #include <calobase/RawCluster.h>
26 #include <calobase/RawClusterContainer.h>
27 
30 
31 #include <phool/getClass.h>
32 
35 
36 // MBD
37 #include <mbd/BbcGeom.h>
38 #include <mbd/MbdPmtContainerV1.h>
39 #include <mbd/MbdPmtHit.h>
40 
41 #include <TFile.h>
42 #include <TH1.h>
43 #include <TH2.h>
44 #include <TNtuple.h>
45 #include <TProfile2D.h>
46 #include <TTree.h>
47 
48 #include <Event/Event.h>
49 #include <Event/packet.h>
50 #include <cassert>
51 #include <sstream>
52 #include <string>
53 
54 #include <iostream>
55 #include <utility>
56 #include "TCanvas.h"
57 #include "TF1.h"
58 #include "TFile.h"
59 #include "TH1F.h"
60 
61 #include <cdbobjects/CDBTTree.h> // for CDBTTree
63 #include <phool/recoConsts.h>
64 
65 R__LOAD_LIBRARY(libLiteCaloEvalTowSlope.so)
66 
67 using namespace std;
68 
69 CaloAna::CaloAna(const std::string& name, const std::string& filename)
70  : SubsysReco(name)
71  , detector("HCALIN")
72  , outfilename(filename)
73 {
74  _eventcounter = 0;
75 }
76 
78 {
79  delete hm;
80  delete g4hitntuple;
81  delete g4cellntuple;
82  delete towerntuple;
83  delete clusterntuple;
84 }
85 
87 {
88  hm = new Fun4AllHistoManager(Name());
89  // create and register your histos (all types) here
90 
91  outfile = new TFile(outfilename.c_str(), "RECREATE");
92 
93  // correlation plots
94  for (int i = 0; i < 96; i++) h_mass_eta_lt[i] = new TH1F(Form("h_mass_eta_lt%d", i), "", 50, 0, 0.5);
95 
96  h_cemc_etaphi = new TH2F("h_cemc_etaphi", "", 96, 0, 96, 256, 0, 256);
97 
98  // 1D distributions
99  h_InvMass = new TH1F("h_InvMass", "Invariant Mass", 120, 0, 1.2);
100  h_InvMassMix = new TH1F("h_InvMassMix", "Invariant Mass", 120, 0, 1.2);
101 
102  // cluster QA
103  h_etaphi_clus = new TH2F("h_etaphi_clus", "", 140, -1.2, 1.2, 64, -1 * TMath::Pi(), TMath::Pi());
104  h_clusE = new TH1F("h_clusE", "", 100, 0, 10);
105 
106  h_emcal_e_eta = new TH1F("h_emcal_e_eta", "", 96, 0, 96);
107 
108  h_pt1 = new TH1F("h_pt1", "", 100, 0, 5);
109  h_pt2 = new TH1F("h_pt2", "", 100, 0, 5);
110 
111  h_nclusters = new TH1F("h_nclusters", "", 1000, 0, 1000);
112 
113 
114  return 0;
115 }
116 
118 {
119  _eventcounter++;
120 
121  process_towers(topNode);
122 
124 }
125 
127 {
128  if ((_eventcounter % 1000) == 0) std::cout << _eventcounter << std::endl;
129 
130  // float emcaldownscale = 1000000 / 800;
131 
132  float emcal_hit_threshold = 0.5; // GeV
133 
134  // cuts
135  float maxDr = 1.1;
136  float maxAlpha = 0.6;
137  float clus_chisq_cut = 4;
138  float nClus_ptCut = 0.5;
139  int max_nClusCount = 300;
140 
141  //----------------------------------get vertex------------------------------------------------------//
142 
143  GlobalVertexMap* vertexmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
144  if (!vertexmap)
145  {
146  // std::cout << PHWHERE << " Fatal Error - GlobalVertexMap node is missing"<< std::endl;
147  std::cout << "CaloAna GlobalVertexMap node is missing" << std::endl;
148  // return Fun4AllReturnCodes::ABORTRUN;
149  }
150  float vtx_z = 0;
151  if (vertexmap && !vertexmap->empty())
152  {
153  GlobalVertex* vtx = vertexmap->begin()->second;
154  if (vtx)
155  {
156  vtx_z = vtx->get_z();
157  }
158  }
159 
160  vector<float> ht_eta;
161  vector<float> ht_phi;
162 
163  // if (!m_vtxCut || abs(vtx_z) > _vz) return Fun4AllReturnCodes::EVENT_OK;
164 
165  TowerInfoContainer* towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC");
166  if (towers)
167  {
168  int size = towers->size(); // online towers should be the same!
169  for (int channel = 0; channel < size; channel++)
170  {
172  float offlineenergy = tower->get_energy();
173  unsigned int towerkey = towers->encode_key(channel);
174  int ieta = towers->getTowerEtaBin(towerkey);
175  int iphi = towers->getTowerPhiBin(towerkey);
176  bool isGood = !(tower->get_isBadChi2());
177  if (!isGood && offlineenergy > 0.2)
178  {
179  ht_eta.push_back(ieta);
180  ht_phi.push_back(iphi);
181  }
182  if (isGood) h_emcal_e_eta->Fill(ieta, offlineenergy);
183  if (offlineenergy > emcal_hit_threshold)
184  {
185  h_cemc_etaphi->Fill(ieta, iphi);
186  }
187  }
188  }
189 
190  RawClusterContainer* clusterContainer = findNode::getClass<RawClusterContainer>(topNode, "CLUSTERINFO_CEMC2");
191  if (!clusterContainer)
192  {
193  std::cout << PHWHERE << "funkyCaloStuff::process_event - Fatal Error - CLUSTER_CEMC node is missing. " << std::endl;
194  return 0;
195  }
196 
198  // geometry for hot tower/cluster masking
199  std::string towergeomnodename = "TOWERGEOM_CEMC";
200  RawTowerGeomContainer* m_geometry = findNode::getClass<RawTowerGeomContainer>(topNode, towergeomnodename);
201  if (!m_geometry)
202  {
203  std::cout << Name() << "::"
204  << "CreateNodeTree"
205  << ": Could not find node " << towergeomnodename << std::endl;
206  throw std::runtime_error("failed to find TOWERGEOM node in RawClusterDeadHotMask::CreateNodeTree");
207  }
208 
209  RawClusterContainer::ConstRange clusterEnd = clusterContainer->getClusters();
212  int nClusCount = 0;
213  for (clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
214  {
215  RawCluster* recoCluster = clusterIter->second;
216 
217  CLHEP::Hep3Vector vertex(0, 0, vtx_z);
218  CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
219 
220  float clus_pt = E_vec_cluster.perp();
221  float clus_chisq = recoCluster->get_chi2();
222 
223  if (clus_pt < nClus_ptCut) continue;
224  if (clus_chisq > clus_chisq_cut) continue;
225 
226  nClusCount++;
227  }
228 
229  h_nclusters->Fill(nClusCount);
230 
231  if (nClusCount > max_nClusCount) return Fun4AllReturnCodes::EVENT_OK;
232 
233  float pt1ClusCut = 2; // 1.3
234  float pt2ClusCut = 1.3; // 0.7
235 
236  if (nClusCount > 30)
237  {
238  pt1ClusCut += 1.4 * (nClusCount - 29) / 200.0;
239  pt2ClusCut += 1.4 * (nClusCount - 29) / 200.0;
240  }
241 
242  float pi0ptcut = 1.22 * (pt1ClusCut + pt2ClusCut);
243 
244  vector<float> save_pt;
245  vector<float> save_eta;
246  vector<float> save_phi;
247  vector<float> save_e;
248 
249  for (clusterIter = clusterEnd.first; clusterIter != clusterEnd.second; clusterIter++)
250  {
251  RawCluster* recoCluster = clusterIter->second;
252 
253  CLHEP::Hep3Vector vertex(0, 0, vtx_z);
254  CLHEP::Hep3Vector E_vec_cluster = RawClusterUtility::GetECoreVec(*recoCluster, vertex);
255 
256  float clusE = E_vec_cluster.mag();
257  float clus_eta = E_vec_cluster.pseudoRapidity();
258  float clus_phi = E_vec_cluster.phi();
259  float clus_pt = E_vec_cluster.perp();
260  float clus_chisq = recoCluster->get_chi2();
261  h_clusE->Fill(clusE);
262 
263  if (clus_chisq > clus_chisq_cut) continue;
264 
265  // loop over the towers in the cluster
266  RawCluster::TowerConstRange towerCR = recoCluster->get_towers();
268  bool hotClus = false;
269  float lt_e = -1000;
270  unsigned int lt_eta = -1;
271  for (toweriter = towerCR.first; toweriter != towerCR.second; ++toweriter)
272  {
273  int towereta = m_geometry->get_tower_geometry(toweriter->first)->get_bineta();
274  int towerphi = m_geometry->get_tower_geometry(toweriter->first)->get_binphi();
275  unsigned int key = TowerInfoDefs::encode_emcal(towereta, towerphi);
276  unsigned int channel = towers->decode_key(key);
277  float energy = towers->get_tower_at_channel(channel)->get_energy();
278  if (energy > lt_e)
279  {
280  lt_e = energy;
281  lt_eta = towereta;
282  }
283 
284  for (size_t i = 0; i < ht_eta.size(); i++)
285  if (towerphi == ht_phi[i] && towereta == ht_eta[i])
286  hotClus = true;
287  }
288 
289  if (dynMaskClus && hotClus == true) continue;
290 
291  h_etaphi_clus->Fill(clus_eta, clus_phi);
292 
293  TLorentzVector photon1;
294  photon1.SetPtEtaPhiE(clus_pt, clus_eta, clus_phi, clusE);
295 
296 
297 
298  if (clus_pt < pt1ClusCut) continue;
299 
300  for (clusterIter2 = clusterEnd.first; clusterIter2 != clusterEnd.second; clusterIter2++)
301  {
302  if (clusterIter == clusterIter2)
303  {
304  continue;
305  }
306  RawCluster* recoCluster2 = clusterIter2->second;
307 
308  CLHEP::Hep3Vector E_vec_cluster2 = RawClusterUtility::GetECoreVec(*recoCluster2, vertex);
309 
310  float clus2E = E_vec_cluster2.mag();
311  float clus2_eta = E_vec_cluster2.pseudoRapidity();
312  float clus2_phi = E_vec_cluster2.phi();
313  float clus2_pt = E_vec_cluster2.perp();
314  float clus2_chisq = recoCluster2->get_chi2();
315 
316  if (clus2_pt < pt2ClusCut) continue;
317  if (clus2_chisq > clus_chisq_cut) continue;
318 
319  // loop over the towers in the cluster
320  RawCluster::TowerConstRange towerCR2 = recoCluster2->get_towers();
322  bool hotClus2 = false;
323  for (toweriter2 = towerCR2.first; toweriter2 != towerCR2.second; ++toweriter2)
324  {
325  int towereta = m_geometry->get_tower_geometry(toweriter2->first)->get_bineta();
326  int towerphi = m_geometry->get_tower_geometry(toweriter2->first)->get_binphi();
327 
328  for (size_t i = 0; i < ht_eta.size(); i++)
329  {
330  if (towerphi == ht_phi[i] && towereta == ht_phi[i]) hotClus2 = true;
331  }
332  }
333  if (dynMaskClus && hotClus2 == true) continue;
334 
335  TLorentzVector photon2;
336  photon2.SetPtEtaPhiE(clus2_pt, clus2_eta, clus2_phi, clus2E);
337 
338  if (fabs(clusE - clus2E) / (clusE + clus2E) > maxAlpha) continue;
339 
340  if (photon1.DeltaR(photon2) > maxDr) continue;
341 
342  TLorentzVector pi0 = photon1 + photon2;
343  if (pi0.Pt() < pi0ptcut) continue;
344 
345  h_pt1->Fill(photon1.Pt());
346  h_pt2->Fill(photon2.Pt());
347  h_InvMass->Fill(pi0.M());
348  if (lt_eta > 95) continue;
349  h_mass_eta_lt[lt_eta]->Fill(pi0.M());
350  }
351 } // clus1 loop
352 
353 
354 
355 ht_phi.clear();
356 ht_eta.clear();
357 
359 }
360 
361 int CaloAna::End(PHCompositeNode* /*topNode*/)
362 {
363  outfile->cd();
364 
365  outfile->Write();
366  outfile->Close();
367  delete outfile;
368  hm->dumpHistos(outfilename, "UPDATE");
369  return 0;
370 }
371 
372 std::pair<double, double> CaloAna::fitHistogram(TH1F* h)
373 {
374  TF1* fitFunc = new TF1("fitFunc", "[0]*exp(-0.5*((x-[1])/[2])^2) + [3] + [4]*x + [5]*x^2 + [6]*x^3", h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
375 
376  fitFunc->SetParameter(0, h->GetMaximum());
377  fitFunc->SetParameter(1, target_pi0_mass);
378  fitFunc->SetParameter(2, 0.01);
379  fitFunc->SetParameter(3, 0.0);
380  fitFunc->SetParameter(4, 0.0);
381  fitFunc->SetParameter(5, 0.0);
382  fitFunc->SetParameter(6, 0.0);
383 
384  fitFunc->SetParLimits(1, 0.1, 0.2);
385 
386  // Perform the fit
387  h->Fit("fitFunc", "QN");
388 
389  // Get the mean and its error
390  double mean = fitFunc->GetParameter(1);
391  double errorOnMean = fitFunc->GetParError(1);
392 
393  // Create a pair to store the results
394  std::pair<double, double> result(mean, errorOnMean);
395 
396  return result;
397 }
398 
400 {
401  TFile* fin = new TFile(infile.c_str());
402  cout << "getting hists" << endl;
403  TH1F* h_peak_eta = new TH1F("h_peak_eta", "", 96, 0, 96);
404  if (!fin) cout << "CaloAna::fitEtaSlices null fin" << endl;
405  TH1F* h_M_eta[96];
406  for (int i = 0; i < 96; i++) h_M_eta[i] = (TH1F*) fin->Get(Form("h_mass_eta_lt%d", i));
407 
408  for (int i = 0; i < 96; i++)
409  {
410  if (!h_M_eta[i]) cout << "CaloAna::fitEtaSlices null hist" << endl;
411  std::pair<double, double> result = fitHistogram(h_M_eta[i]);
412  h_peak_eta->SetBinContent(i + 1, result.first);
413  h_peak_eta->SetBinError(i + 1, result.second);
414  }
415  cdbFile = "";
416 
417  CDBTTree* cdbttree1 = new CDBTTree(cdbFile.c_str());
418  CDBTTree* cdbttree2 = new CDBTTree(cdbFile.c_str());
419 
420  string m_fieldname = "Femc_datadriven_qm1_correction";
421 
422  for (int i = 0; i < 96; i++)
423  {
424  for (int j = 0; j < 256; j++)
425  {
426  float correction = target_pi0_mass / h_peak_eta->GetBinContent(i + 1);
427  unsigned int key = TowerInfoDefs::encode_emcal(i, j);
428  float val1 = cdbttree1->GetFloatValue(key, m_fieldname);
429  cdbttree2->SetFloatValue(key, m_fieldname, val1 * correction);
430  }
431  }
432 
433  cdbttree2->Commit();
434  cdbttree2->WriteCDBTTree();
435  delete cdbttree2;
436  delete cdbttree1;
437 
438  TFile* fit_out = new TFile(fitOutFile.c_str(), "recreate");
439  fit_out->cd();
440  h_peak_eta->Write();
441  for (int i = 0; i < 96; i++)
442  {
443  h_M_eta[i]->Write();
444  delete h_M_eta[i];
445  }
446 
447  fin->Close();
448 
449  cout << "finish fitting suc" << endl;
450 
451  return;
452 }