File indexing completed on 2025-08-03 08:11:32
0001 #include "BbcCheck.h"
0002
0003 #include <phool/phool.h>
0004 #include <phool/getClass.h>
0005 #include <phool/recoConsts.h>
0006 #include <fun4all/Fun4AllServer.h>
0007 #include <ffaobjects/EventHeaderv1.h>
0008 #include <ffarawobjects/Gl1Packet.h>
0009 #include <fun4all/Fun4AllReturnCodes.h>
0010
0011 #include <mbd/MbdDefs.h>
0012 #include <mbd/MbdOut.h>
0013 #include <mbd/MbdPmtContainer.h>
0014 #include <mbd/MbdPmtHit.h>
0015 #include <mbd/MbdGeom.h>
0016
0017 #include <calobase/TowerInfoContainer.h>
0018 #include <calobase/TowerInfo.h>
0019 #include <globalvertex/GlobalVertexMap.h>
0020 #include <globalvertex/GlobalVertex.h>
0021 #include <globalvertex/MbdVertexMap.h>
0022 #include <globalvertex/MbdVertex.h>
0023
0024 #include <TFile.h>
0025 #include <TTree.h>
0026 #include <TH1F.h>
0027 #include <TH2F.h>
0028 #include <TGraphErrors.h>
0029 #include <TF1.h>
0030 #include <TCanvas.h>
0031 #include <TString.h>
0032 #include <TLorentzVector.h>
0033
0034 #include <TSystem.h>
0035
0036 #include <iostream>
0037 #include <cmath>
0038 #include <cstdio>
0039
0040 using namespace std;
0041 using namespace MbdDefs;
0042
0043
0044 BbcCheck::BbcCheck(const string &name) : SubsysReco(name),
0045 f_evt( 0 ),
0046 _tres( 0.05 ),
0047 _savefname( "bbcstudy.root" ),
0048 _savefile( 0 )
0049 {
0050
0051 }
0052
0053
0054 int BbcCheck::Init(PHCompositeNode *topNode)
0055 {
0056 cout << PHWHERE << " Saving to file " << _savefname << endl;
0057
0058 _savefile = new TFile( _savefname.c_str(), "RECREATE" );
0059
0060 _tree = new TTree("t","BbcCheck");
0061 _tree->Branch("run",&f_run,"run/I");
0062 _tree->Branch("ch",&f_ch,"ch/I");
0063 _tree->Branch("qmean",&f_qmean,"qmean/F");
0064 _tree->Branch("qmerr",&f_qmerr,"qmerr/F");
0065
0066 _tree2 = new TTree("t2","BbcCheck Event Tree");
0067 _tree2->Branch("run",&f_run,"run/I");
0068 _tree2->Branch("evt",&f_evt,"evt/I");
0069 _tree2->Branch("cross",&f_cross,"cross/S");
0070 _tree2->Branch("rtrig",&f_rtrig,"rtrig/l");
0071 _tree2->Branch("ltrig",&f_ltrig,"ltrig/l");
0072 _tree2->Branch("strig",&f_strig,"strig/l");
0073 _tree2->Branch("bz",&f_bz,"bz/F");
0074
0075 TString name, title;
0076 for (int ipmt=0; ipmt<128; ipmt++)
0077 {
0078 name = "h_q"; name += ipmt;
0079 title = "bbc charge, ch "; title += ipmt;
0080 h_bbcq[ipmt] = new TH1F(name,title,1200,0,60);
0081
0082
0083 name = "g_bbcq"; name += ipmt;
0084 title = "mbdq, ch "; title += ipmt;
0085 g_bbcq[ipmt] = new TGraphErrors();
0086 g_bbcq[ipmt]->SetName(name);
0087 g_bbcq[ipmt]->SetTitle(name);
0088
0089
0090
0091
0092
0093
0094 }
0095
0096 for (int iarm=0; iarm<2; iarm++)
0097 {
0098 name = "h_bbcqtot"; name += iarm;
0099 title = "bbc charge, arm "; title += iarm;
0100 h_bbcqtot[iarm] = new TH1F(name,title,1400,0,1400);
0101
0102 name = "h2_bbcqtot_bz"; name += iarm;
0103 title = "bbc charge, arm "; title += iarm; title += " vs z";
0104 h2_bbcqtot_bz[iarm] = new TH2F(name,title,20,-50.,50.,1000,0.,3000.);
0105
0106
0107 name = "hevt_bbct"; name += iarm;
0108 title = "bbc times, arm "; title += iarm;
0109 hevt_bbct[iarm] = new TH1F(name,title,200,7.5,11.5);
0110 hevt_bbct[iarm]->SetLineColor(4);
0111 }
0112 h_bbcqsum = new TH1F("h_bbcqsum","MBD/BBC north + south charge sum",3000,0.,3000.);
0113 h2_bbcqsum = new TH2F("h2_bbcqsum","north BBCQ vs South BBCQ",1400,0.,1400.,1400,0.,1400.);
0114
0115 h2_bbcqsum_bz = new TH2F("h2_bbcqsum_bz","BBCQsum vs z",20,-50.,50.,1000,0.,3000.);
0116
0117 h_zdce = new TH1F("h_zdce","ZDC Energy",820,-50,4050);
0118 h_zdcse = new TH1F("h_zdcse","ZDC.S Energy",500,0,250);
0119 h_zdcne = new TH1F("h_zdcne","ZDC.N Energy",500,0,250);
0120 h_zdctimecut = new TH1F("h_zdctimecut", "zdctimecut", 50, -17.5 , 32.5);
0121
0122 h_emcale = new TH1F("h_emcale","Emcal Energy",3000,-100,2900);
0123 h_emcaltimecut = new TH1F("h_emcaltimecut", "emcaltimecut", 50, -17.5 , 32.5);
0124
0125 h_ohcale = new TH1F("h_ohcale","OHCAL Energy",1000,-100,900);
0126 h_ohcaltimecut = new TH1F("h_ohcaltimecut", "ohcaltimecut", 50, -17.5 , 32.5);
0127
0128 h_ihcale = new TH1F("h_ihcale","IHCAL Energy",1000,-100,900);
0129 h_ihcaltimecut = new TH1F("h_ihcaltimecut", "ihcaltimecut", 50, -17.5 , 32.5);
0130
0131 h_bz = new TH1F("h_bz","MBD z-vertex",1200,-300,300);
0132 h_bz->SetXTitle("z_{VTX} [cm]");
0133 for (int itrig=0; itrig<5; itrig++)
0134 {
0135 name = "h_bz"; name += itrig;
0136 title = "MBD z-vertex, trig "; title += itrig;
0137 h_bztrig[itrig] = new TH1F(name,title,1200,-300,300);
0138 h_bztrig[itrig]->SetXTitle("z_{VTX} [cm]");
0139 }
0140
0141 h_bpmt_bad = new TH1F("h_bpmt_bad","PMT for BAD MBD z-vertex",128,0,128);
0142
0143
0144 for (int ipmt=0; ipmt<128; ipmt++)
0145 {
0146 name = "h2_slew"; name += ipmt;
0147 title = "slew curve, ch "; title += ipmt;
0148 h2_slew[ipmt] = new TH2F(name,title,4000,0.,100,1100,-5,6);
0149 }
0150 h2_tq = new TH2F("h2_tq","ch vs tq",900,-150,150,128,-0.5,128-0.5);
0151 h2_tt = new TH2F("h2_tt","ch vs tt",900,-150,150,128,-0.5,128-0.5);
0152
0153 gaussian = new TF1("gaussian","gaus",0,20);
0154 gaussian->FixParameter(2,0.05);
0155
0156 c_bbct = new TCanvas("c_bbct","BBC Times",1200,800);
0157 c_bbct->Divide(1,2);
0158
0159
0160 mbdtrigbits.push_back(0x0400);
0161 mbdtrigbits.push_back(0x0800);
0162 mbdtrigbits.push_back(0x1000);
0163 mbdtrigbits.push_back(0x2000);
0164 mbdtrigbits.push_back(0x4000);
0165
0166 return 0;
0167 }
0168
0169
0170 int BbcCheck::InitRun(PHCompositeNode *topNode)
0171 {
0172 recoConsts *rc = recoConsts::instance();
0173 f_run = rc->get_IntFlag("RUNNUMBER");
0174
0175 GetNodes(topNode);
0176
0177 return 0;
0178 }
0179
0180
0181
0182 int BbcCheck::process_event(PHCompositeNode *topNode)
0183 {
0184
0185 _gl1raw = findNode::getClass<Gl1Packet>(topNode, "GL1Packet");
0186 if(!_gl1raw && f_evt<4) cout << PHWHERE << " Gl1Packet node not found on node tree" << endl;
0187
0188 nprocessed++;
0189
0190 f_evt = _evtheader->get_EvtSequence();
0191 if (f_evt%1000==0) cout << PHWHERE << "Event " << f_evt << "\t" << ", nprocessed = " << nprocessed << endl;
0192
0193
0194 if ( _gl1raw != nullptr )
0195 {
0196 const uint64_t MBDTRIGS = 0x7c00;
0197 const uint64_t ZDCNS = 0x8;
0198
0199 f_cross = _gl1raw->getBunchNumber();
0200 f_rtrig = _gl1raw->getTriggerVector();
0201 f_ltrig = _gl1raw->getLiveVector();
0202 f_strig = _gl1raw->getScaledVector();
0203
0204 if ( (f_strig&MBDTRIGS) == 0 )
0205 {
0206 return Fun4AllReturnCodes::ABORTEVENT;
0207 }
0208
0209 if ( nprocessed<10 )
0210 {
0211 std::cout << "Trig " << nprocessed << std::endl;
0212 std::cout << hex;
0213 std::cout << "Raw\t" << f_rtrig << std::endl;
0214 std::cout << "Live\t" << f_ltrig << std::endl;
0215 std::cout << "Scaled\t" << f_strig << std::endl;
0216 std::cout << "AND\t" << (f_strig&MBDTRIGS) << std::endl;
0217 std::cout << dec;
0218
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228 }
0229
0230
0231 f_bbcn[0] = 0;
0232 f_bbcn[1] = 0;
0233 f_bbcq[0] = 0.;
0234 f_bbcq[1] = 0.;
0235 f_bbct[0] = -9999.;
0236 f_bbct[1] = -9999.;
0237 f_bbcte[0] = -9999.;
0238 f_bbcte[1] = -9999.;
0239 f_bz = NAN;
0240 f_bbct0 = NAN;
0241 hevt_bbct[0]->Reset();
0242 hevt_bbct[1]->Reset();
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 CheckDST(topNode);
0258
0259 _tree2->Fill();
0260 return 0;
0261 }
0262
0263
0264 void BbcCheck::GetNodes(PHCompositeNode *topNode)
0265 {
0266
0267
0268 _evtheader = findNode::getClass<EventHeaderv1>(topNode, "EventHeader");
0269 if (!_evtheader && f_evt<10) cout << PHWHERE << " EventHeader node not found on node tree" << endl;
0270
0271
0272 _mbdout = findNode::getClass<MbdOut>(topNode, "MbdOut");
0273 if(!_mbdout && f_evt<4) cout << PHWHERE << " MbdOut node not found on node tree" << endl;
0274
0275
0276 _mbdpmts = findNode::getClass<MbdPmtContainer>(topNode, "MbdPmtContainer");
0277 if(!_mbdpmts && f_evt<4) cout << PHWHERE << " MbdPmtContainer node not found on node tree" << endl;
0278
0279
0280 }
0281
0282
0283 int BbcCheck::End(PHCompositeNode *topNode)
0284 {
0285 _savefile->cd();
0286
0287 Double_t nevents = h_bbcqsum->Integral();
0288 h_bbcqsum->Fill(-1000,nevents);
0289 h_bbcqtot[0]->Fill(-1000,nevents);
0290 h_bbcqtot[1]->Fill(-1000,nevents);
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 for (int ipmt=0; ipmt<BBC_N_PMT; ipmt++)
0302 {
0303
0304
0305
0306 f_ch = ipmt;
0307 f_qmean = h_bbcq[ipmt]->GetMean();
0308 f_qmerr = h_bbcq[ipmt]->GetMeanError();
0309 _tree->Fill();
0310 cout << f_run << "\t" << f_ch << "\t" << f_qmean << "\t" << f_qmerr << endl;
0311
0312 g_bbcq[ipmt]->SetPoint(0,f_run,f_qmean);
0313 g_bbcq[ipmt]->SetPointError(0,0,f_qmerr);
0314 g_bbcq[ipmt]->Write();
0315 }
0316
0317 cout << "Nevents processed integral " << nprocessed << "\t" << nevents << "\t" << nevents/nprocessed << endl;
0318 _savefile->Write();
0319 _savefile->Close();
0320
0321 return 0;
0322 }
0323
0324 void BbcCheck::CheckDST(PHCompositeNode *topNode)
0325 {
0326
0327
0328
0329 Float_t bqs = _mbdout->get_q(0);
0330 Float_t bqn = _mbdout->get_q(1);
0331 f_bz = _mbdout->get_zvtx();
0332 Float_t btarm[2];
0333 btarm[0] = _mbdout->get_time(0);
0334 btarm[1] = _mbdout->get_time(1);
0335
0336
0337
0338
0339 MbdVertexMap *mbdvtxmap = findNode::getClass<MbdVertexMap>(topNode, "MbdVertexMap");
0340 if ( mbdvtxmap && !mbdvtxmap->empty() )
0341 {
0342 MbdVertex *vtx = mbdvtxmap->begin()->second;
0343 if ( vtx )
0344 {
0345 float vtx_z = vtx->get_z();
0346 if ( !isnan(f_bz) && vtx_z != f_bz )
0347 {
0348 cout << "ERROR, mbdvertexmap does not match " << vtx_z << "\t" << f_bz << endl;
0349 }
0350 else
0351 {
0352 static int counter = 0;
0353 if ( counter<3 )
0354 {
0355 cout << "GOOD, mbdvertexmap vertex matches " << vtx_z << "\t" << f_bz << endl;
0356 counter++;
0357 }
0358 }
0359 }
0360 }
0361 else
0362 {
0363 static int counter = 0;
0364 if ( counter < 4 )
0365 {
0366 if ( mbdvtxmap && mbdvtxmap->empty() )
0367 {
0368 cout << "MbdVertexMap is empty" << endl;
0369 }
0370 else
0371 {
0372 cout << "MbdVertexMap not found" << endl;
0373 }
0374 counter++;
0375 }
0376 }
0377
0378
0379 GlobalVertexMap *vertexmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
0380 if ( vertexmap && !vertexmap->empty() )
0381 {
0382 GlobalVertex *vtx = vertexmap->begin()->second;
0383 if ( vtx )
0384 {
0385 float vtx_z = vtx->get_z();
0386 if ( vtx_z != f_bz )
0387 {
0388 cout << "ERROR, vertices do not match " << vtx_z << "\t" << f_bz << endl;
0389 }
0390 else
0391 {
0392 static int counter = 0;
0393 if ( counter<3 )
0394 {
0395 cout << "GOOD, globalvertexmap vertex matches " << vtx_z << "\t" << f_bz << endl;
0396 counter++;
0397 }
0398 }
0399 }
0400 }
0401 else
0402 {
0403 static int counter = 0;
0404 if ( counter < 4 )
0405 {
0406 if ( vertexmap && vertexmap->empty() )
0407 {
0408 cout << "GlobalVertexMap is empty" << endl;
0409 }
0410 else
0411 {
0412 cout << "GlobalVertexMap not found" << endl;
0413 }
0414 counter++;
0415 }
0416 }
0417
0418
0419 if ( fabs(f_bz)>3000. ) return;
0420
0421
0422
0423 Float_t r = 1.0;
0424
0425 h_bbcqsum->Fill( (bqn+bqs)*r );
0426 h_bbcqtot[0]->Fill( bqs*r );
0427 h_bbcqtot[1]->Fill( bqn*r );
0428 h2_bbcqsum->Fill( bqn*r, bqs*r );
0429
0430 h2_bbcqtot_bz[0]->Fill( f_bz, bqs );
0431 h2_bbcqtot_bz[1]->Fill( f_bz, bqn );
0432 h2_bbcqsum_bz->Fill( f_bz, bqn+bqs );
0433
0434
0435
0436
0437 for (int ipmt=0; ipmt<128; ipmt++)
0438 {
0439 int arm = ipmt/64;
0440
0441 Float_t q = _mbdpmts->get_pmt(ipmt)->get_q();
0442 Float_t t = _mbdpmts->get_pmt(ipmt)->get_time();
0443 Float_t tt = _mbdpmts->get_pmt(ipmt)->get_tt();
0444 Float_t tq = _mbdpmts->get_pmt(ipmt)->get_tq();
0445
0446
0447 if ( fabs(t) < 25. )
0448 {
0449 h_bbcq[ipmt]->Fill( q*r );
0450 }
0451
0452 h2_tt->Fill( t, ipmt );
0453 h2_tq->Fill( tq, ipmt );
0454
0455 h2_slew[ipmt]->Fill( q, t - btarm[arm] );
0456
0457
0458 }
0459
0460 h_bz->Fill( f_bz );
0461 for (size_t itrig=0; itrig<mbdtrigbits.size(); itrig++)
0462 {
0463 if ( f_ltrig&mbdtrigbits[itrig] )
0464 {
0465 h_bztrig[itrig]->Fill( f_bz );
0466 }
0467 }
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 }
0478
0479 int BbcCheck::Getpeaktime(TH1 * h)
0480 {
0481 int getmaxtime, tcut = -1;
0482
0483 for(int bin = 1; bin < h->GetNbinsX()+1; bin++)
0484 {
0485 double c = h->GetBinContent(bin);
0486 double max = h->GetMaximum();
0487 int bincenter = h->GetBinCenter(bin);
0488 if(max == c)
0489 {
0490 getmaxtime = bincenter;
0491 if(getmaxtime != -1) tcut = getmaxtime;
0492 }
0493 }
0494
0495 return tcut;
0496 }
0497
0498 void BbcCheck::process_gl1( PHCompositeNode *topNode )
0499 {
0500 TowerInfoContainer* zdctowers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_ZDC");
0501 if (zdctowers)
0502 {
0503 int max_zdc_t = Getpeaktime( h_zdctimecut );
0504 int range = 1;
0505 double zdc_etot = 0.;
0506 double zdc_e[2] {0.,0.};
0507
0508 int size = zdctowers->size();
0509 for (int ich = 0; ich < size; ich++)
0510 {
0511 TowerInfo* zdctower = zdctowers->get_tower_at_channel(ich);
0512 float zdce = zdctower->get_energy();
0513 int zdct = zdctowers->get_tower_at_channel(ich)->get_time();
0514 h_zdctimecut->Fill( zdct );
0515
0516 if ( (zdct < (max_zdc_t - range)) || (zdct > (max_zdc_t + range)) )
0517 {
0518 continue;
0519 }
0520
0521
0522 if (ich==0||ich==2||ich==4)
0523 {
0524 zdc_e[0] += zdce;
0525 }
0526 else if (ich == 8 || ich == 10 || ich == 12)
0527 {
0528 zdc_e[1] += zdce;
0529 }
0530
0531 }
0532
0533 h_zdcse->Fill( zdc_e[0] );
0534 h_zdcne->Fill( zdc_e[1] );
0535 zdc_etot = zdc_e[0] + zdc_e[1];
0536 h_zdce->Fill( zdc_etot );
0537 }
0538 }
0539
0540
0541 void BbcCheck::process_zdc( PHCompositeNode *topNode )
0542 {
0543 TowerInfoContainer* zdctowers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_ZDC");
0544 if (zdctowers)
0545 {
0546 int max_zdc_t = Getpeaktime( h_zdctimecut );
0547 int range = 1;
0548 double zdc_etot = 0.;
0549
0550 int size = zdctowers->size();
0551 for (int ich = 0; ich < size; ich++)
0552 {
0553 TowerInfo* zdctower = zdctowers->get_tower_at_channel(ich);
0554 float zdce = zdctower->get_energy();
0555 int zdct = zdctowers->get_tower_at_channel(ich)->get_time();
0556 h_zdctimecut->Fill( zdct );
0557
0558 if (ich == 0 || ich == 2 || ich == 4 || ich == 8 || ich == 10 || ich == 12)
0559 {
0560 if( zdct > (max_zdc_t - range) && zdct < (max_zdc_t + range))
0561 {
0562 zdc_etot += zdce;
0563 }
0564 }
0565 }
0566
0567 h_zdce->Fill( zdc_etot);
0568 }
0569 }
0570
0571
0572 void BbcCheck::process_emcal( PHCompositeNode *topNode )
0573 {
0574 TowerInfoContainer* towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_CEMC");
0575 if (towers)
0576 {
0577 int max_emcal_t = Getpeaktime( h_emcaltimecut );
0578 int range = 1;
0579 double etot = 0.;
0580
0581 int size = towers->size();
0582 for (int channel = 0; channel < size;channel++)
0583 {
0584 TowerInfo* tower = towers->get_tower_at_channel(channel);
0585 float energy = tower->get_energy();
0586 int t = towers->get_tower_at_channel(channel)->get_time();
0587 h_emcaltimecut->Fill(t);
0588
0589 if( abs(t - max_emcal_t) < range )
0590 {
0591 etot += energy;
0592 }
0593 }
0594
0595 h_emcale->Fill(etot);
0596 }
0597 }
0598
0599 void BbcCheck::process_ohcal( PHCompositeNode *topNode )
0600 {
0601 TowerInfoContainer* towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALOUT");
0602 if (towers)
0603 {
0604 int max_hcal_t = Getpeaktime( h_ohcaltimecut );
0605 int range = 1;
0606 double etot = 0.;
0607
0608 int size = towers->size();
0609 for (int channel = 0; channel < size;channel++)
0610 {
0611 TowerInfo* tower = towers->get_tower_at_channel(channel);
0612 float energy = tower->get_energy();
0613 int t = towers->get_tower_at_channel(channel)->get_time();
0614 h_ohcaltimecut->Fill(t);
0615
0616 if( abs(t - max_hcal_t) < range )
0617 {
0618 etot += energy;
0619 }
0620 }
0621
0622 h_ohcale->Fill(etot);
0623 }
0624 }
0625
0626 void BbcCheck::process_ihcal( PHCompositeNode *topNode )
0627 {
0628 TowerInfoContainer* towers = findNode::getClass<TowerInfoContainer>(topNode, "TOWERINFO_CALIB_HCALIN");
0629 if (towers)
0630 {
0631 int max_hcal_t = Getpeaktime( h_ihcaltimecut );
0632 int range = 1;
0633 double etot = 0.;
0634
0635 int size = towers->size();
0636 for (int channel = 0; channel < size;channel++)
0637 {
0638 TowerInfo* tower = towers->get_tower_at_channel(channel);
0639 float energy = tower->get_energy();
0640 int t = towers->get_tower_at_channel(channel)->get_time();
0641 h_ihcaltimecut->Fill(t);
0642
0643 if( abs(t - max_hcal_t) < range )
0644 {
0645 etot += energy;
0646 }
0647 }
0648
0649 h_ihcale->Fill(etot);
0650 }
0651 }
0652