File indexing completed on 2025-08-03 08:11:32
0001 #include "BBCStudy.h"
0002
0003 #include <phool/phool.h>
0004 #include <phool/getClass.h>
0005 #include <g4main/PHG4HitContainer.h>
0006 #include <g4main/PHG4TruthInfoContainer.h>
0007 #include <g4main/PHG4Particle.h>
0008 #include <g4main/PHG4Hit.h>
0009 #include <g4main/PHG4VtxPoint.h>
0010 #include <fun4all/PHTFileServer.h>
0011 #include <fun4all/Fun4AllServer.h>
0012 #include <ffaobjects/EventHeaderv1.h>
0013 #include <mbd/MbdOut.h>
0014 #include <mbd/MbdPmtContainer.h>
0015 #include <mbd/MbdPmtHit.h>
0016 #include <mbd/MbdGeom.h>
0017 #include <mbd/MbdDefs.h>
0018
0019 #include <TFile.h>
0020 #include <TTree.h>
0021 #include <TH1F.h>
0022 #include <TH2F.h>
0023 #include <TF1.h>
0024 #include <TCanvas.h>
0025 #include <TString.h>
0026 #include <TLorentzVector.h>
0027
0028 #include <TDatabasePDG.h>
0029 #include <TRandom3.h>
0030 #include <TSystem.h>
0031
0032 #include <iostream>
0033 #include <cmath>
0034
0035 using namespace std;
0036 using namespace MbdDefs;
0037
0038
0039
0040
0041 BBCStudy::BBCStudy(const string &name) : SubsysReco(name),
0042 _tree( 0 ),
0043 f_evt( 0 ),
0044 _pdg( 0 ),
0045 _rndm( 0 ),
0046 _tres( 0.05 ),
0047 _savefname( "bbcstudy.root" ),
0048 _savefile( 0 )
0049 {
0050
0051 }
0052
0053
0054 int BBCStudy::Init(PHCompositeNode *topNode)
0055 {
0056 cout << PHWHERE << " Saving to file " << _savefname << endl;
0057
0058 _savefile = new TFile( _savefname.c_str(), "RECREATE" );
0059
0060
0061 _tree = new TTree("t","BBC Study");
0062 _tree->Branch("evt",&f_evt,"evt/I");
0063 _tree->Branch("bimp",&f_bimp,"bimp/F");
0064 _tree->Branch("ncoll",&f_ncoll,"ncoll/I");
0065 _tree->Branch("npart",&f_npart,"npart/I");
0066 _tree->Branch("vx",&f_vx,"vx/F");
0067 _tree->Branch("vy",&f_vy,"vy/F");
0068 _tree->Branch("vz",&f_vz,"vz/F");
0069 _tree->Branch("bns",&f_bbcn[0],"bns/S");
0070 _tree->Branch("bnn",&f_bbcn[1],"bnn/S");
0071 _tree->Branch("bqs",&f_bbcq[0],"bqs/F");
0072 _tree->Branch("bqn",&f_bbcq[1],"bqn/F");
0073 _tree->Branch("bts",&f_bbct[0],"bts/F");
0074 _tree->Branch("btn",&f_bbct[1],"btn/F");
0075 _tree->Branch("btes",&f_bbcte[0],"btes/F");
0076 _tree->Branch("bten",&f_bbcte[1],"bten/F");
0077 _tree->Branch("bz",&f_bbcz,"bz/F");
0078 _tree->Branch("bt0",&f_bbct0,"bt0/F");
0079
0080 _pdg = TDatabasePDG::Instance();
0081 _rndm = new TRandom3(0);
0082
0083 TString name, title;
0084 for (int ipmt=0; ipmt<MbdDefs::MBD_N_PMT; ipmt++)
0085 {
0086 name = "h_bbcq"; name += ipmt;
0087 title = "bbc charge, ch "; title += ipmt;
0088 h_bbcq[ipmt] = new TH1F(name,title,1200,0,120*90);
0089
0090
0091
0092
0093
0094
0095 }
0096
0097 for (int iarm=0; iarm<2; iarm++)
0098 {
0099 name = "h_bbcqtot"; name += iarm;
0100 title = "bbc charge, arm "; title += iarm;
0101 h_bbcqtot[iarm] = new TH1F(name,title,1200,0,120*60);
0102
0103
0104 name = "hevt_bbct"; name += iarm;
0105 title = "bbc times, arm "; title += iarm;
0106 hevt_bbct[iarm] = new TH1F(name,title,200,7.5,11.5);
0107 hevt_bbct[iarm]->SetLineColor(4);
0108 }
0109 h2_bbcqtot = new TH2F("h2_bbcqtot","north BBCQ vs South BBCQ",300,0,120*900,300,0,120*900);
0110
0111 h_ztrue = new TH1F("h_ztrue","true z-vtx",600,-30,30);
0112 h_tdiff = new TH1F("h_tdiff","dt (measured - true_time)",6000,-3,3);
0113 h2_tdiff_ch = new TH2F("h2_tdiff_ch","dt (measured - true time) vs ch",MBD_N_PMT,-0.5,MBD_N_PMT-0.5,200,-2,2);
0114
0115 gaussian = new TF1("gaussian","gaus",0,20);
0116 gaussian->FixParameter(2,0.05);
0117
0118 c_bbct = new TCanvas("c_bbct","BBC Times",1200,800);
0119 c_bbct->Divide(1,2);
0120
0121 return 0;
0122 }
0123
0124
0125 int BBCStudy::InitRun(PHCompositeNode *topNode)
0126 {
0127 _bbcgeom = new MbdGeom();
0128 GetNodes(topNode);
0129
0130 return 0;
0131 }
0132
0133
0134
0135 int BBCStudy::process_event(PHCompositeNode *topNode)
0136 {
0137 nprocessed++;
0138
0139
0140
0141 f_evt = _evtheader->get_EvtSequence();
0142 if(f_evt%1==0) cout << PHWHERE << "Event " << f_evt << "\t" << ", nprocessed = " << nprocessed << endl;
0143
0144
0145 f_bbcn[0] = 0;
0146 f_bbcn[1] = 0;
0147 f_bbcq[0] = 0.;
0148 f_bbcq[1] = 0.;
0149 f_bbct[0] = -9999.;
0150 f_bbct[1] = -9999.;
0151 f_bbcte[0] = -9999.;
0152 f_bbcte[1] = -9999.;
0153 f_bbcz = NAN;
0154 f_bbct0 = NAN;
0155 hevt_bbct[0]->Reset();
0156 hevt_bbct[1]->Reset();
0157
0158
0159 f_bimp = _evtheader->get_ImpactParameter();
0160 f_ncoll = _evtheader->get_ncoll();
0161 f_npart = _evtheader->get_npart();
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 PHG4VtxPoint *vtxp = _truth_container->GetPrimaryVtx( _truth_container->GetPrimaryVertexIndex() );
0192 if ( vtxp != 0 )
0193 {
0194 f_vx = vtxp->get_x();
0195 f_vy = vtxp->get_y();
0196 f_vz = vtxp->get_z();
0197 f_vt = vtxp->get_t();
0198
0199 if ( f_evt<20 )
0200 {
0201 cout << "VTXP " << "\t" << f_vx << "\t" << f_vy << "\t" << f_vz << "\t" << f_vt << endl;
0202 }
0203
0204 h_ztrue->Fill( f_vz );
0205
0206 }
0207
0208
0209
0210 PHG4TruthInfoContainer::ConstVtxRange vtx_range = _truth_container->GetVtxRange();
0211 unsigned int nvtx = 0;
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 if ( f_evt<20 )
0233 {
0234 cout << "Num Vertices = " << nvtx << "\t" << _truth_container->GetNumVertices() << endl;
0235
0236 }
0237
0238
0239
0240 float len[MbdDefs::MBD_N_PMT] = {0.};
0241 float edep[MbdDefs::MBD_N_PMT] = {0.};
0242 float first_time[MbdDefs::MBD_N_PMT];
0243 std::fill_n(first_time, MbdDefs::MBD_N_PMT, 1e12);
0244
0245
0246 unsigned int nhits = 0;
0247
0248 TLorentzVector v4;
0249
0250
0251 PHG4HitContainer::ConstRange bbc_hit_range = _bbchits->getHits();
0252 for (auto hit_iter = bbc_hit_range.first; hit_iter != bbc_hit_range.second; hit_iter++)
0253 {
0254 PHG4Hit *this_hit = hit_iter->second;
0255
0256 unsigned int ipmt = this_hit->get_layer();
0257 int arm = ipmt/64;;
0258
0259 int trkid = this_hit->get_trkid();
0260 if ( trkid>0 && f_evt<20 ) cout << "TRKID " << trkid << endl;
0261
0262 PHG4Particle *part = _truth_container->GetParticle( trkid );
0263 v4.SetPxPyPzE( part->get_px(), part->get_py(), part->get_pz(), part->get_e() );
0264
0265 int pid = part->get_pid();
0266 TParticlePDG *partinfo = _pdg->GetParticle( pid );
0267 Double_t charge = -9999.;
0268 if ( partinfo )
0269 {
0270 charge = partinfo->Charge()/3;
0271 }
0272 else if ( part->isIon() )
0273 {
0274 charge = part->get_IonCharge();
0275 }
0276
0277 Double_t beta = v4.Beta();
0278
0279
0280
0281
0282 float xsign = 1.;
0283 float zsign = -1.;
0284 if ( arm == 1 )
0285 {
0286 xsign = -1.;
0287 zsign = 1.;
0288 }
0289
0290 float tube_x = _bbcgeom->get_x(ipmt);
0291 float tube_y = _bbcgeom->get_y(ipmt);
0292 float tube_z = zsign*253.;
0293 float flight_z = fabs(tube_z - vtxp->get_z());
0294
0295 float flight_time = sqrt( tube_x*tube_x + tube_y*tube_y + flight_z*flight_z )/C;
0296 float tdiff = this_hit->get_t(1) - ( vtxp->get_t() + flight_time );
0297
0298
0299 if ( this_hit->get_t(1) < first_time[ipmt] )
0300 {
0301 if ( fabs( this_hit->get_t(1) ) < 106.5 )
0302 {
0303 first_time[ipmt] = this_hit->get_t(1) - vtxp->get_t();
0304 Float_t dt = static_cast<float>( _rndm->Gaus( 0, _tres ) );
0305 first_time[ipmt] += dt;
0306 }
0307 else
0308 {
0309 cout << "BAD " << ipmt << "\t" << this_hit->get_t(1) << endl;
0310 }
0311 }
0312
0313 if ( f_evt<10 )
0314 {
0315 cout << "hit " << ipmt << "\t" << trkid << "\t" << pid
0316
0317 << "\t" << beta
0318 << "\t" << this_hit->get_path_length()
0319 << "\t" << this_hit->get_edep()
0320
0321
0322
0323 << "\t" << this_hit->get_x(1)
0324 << "\t" << this_hit->get_y(1)
0325 << "\t" << this_hit->get_z(1)
0326 << "\t" << this_hit->get_t(1)
0327 << "\t" << tdiff
0328 << endl;
0329
0330
0331 }
0332
0333 edep[ipmt] += this_hit->get_edep();
0334
0335
0336
0337 if ( beta > MbdDefs::v_ckov && charge != 0. )
0338 {
0339 len[ipmt] += this_hit->get_path_length();
0340
0341 if ( trkid>0 )
0342 {
0343 h_tdiff->Fill( tdiff );
0344 h2_tdiff_ch->Fill( ipmt, tdiff );
0345 }
0346
0347 _pids[pid] += 1;
0348 }
0349
0350
0351 if ( part->get_track_id() != trkid )
0352 {
0353 cout << "ERROR " << endl;
0354 }
0355
0356 nhits++;
0357 }
0358
0359 if ( f_evt<20 )
0360 {
0361 cout << "******** " << f_evt << " **************" << endl;
0362 }
0363
0364
0365
0366 for (int iarm=0; iarm<2; iarm++)
0367 {
0368 f_bbct[iarm] = 0.;
0369 }
0370
0371 vector<float> hit_times[2];
0372
0373 for (int ipmt=0; ipmt<MbdDefs::MBD_N_PMT; ipmt++)
0374 {
0375
0376
0377 int arm = _bbcgeom->get_arm(ipmt);
0378
0379
0380 if ( len[ipmt]>0. )
0381 {
0382 if ( f_evt<20 )
0383 {
0384 cout << "ipmt " << ipmt << "\t" << len[ipmt] << "\t" << edep[ipmt] << endl;
0385 }
0386
0387
0388 float npe = len[ipmt]*(120/3.0);
0389 float dnpe = static_cast<float>( _rndm->Gaus( 0, sqrt(npe) ) );
0390
0391 npe += dnpe;
0392
0393 f_bbcq[arm] += npe;
0394
0395 h_bbcq[ipmt]->Fill( npe );
0396 h_bbcqtot[arm]->Fill( npe );
0397
0398
0399 if ( first_time[ipmt] < 9999. )
0400 {
0401
0402 hevt_bbct[arm]->Fill( first_time[ipmt] );
0403 hit_times[arm].push_back( first_time[ipmt] );
0404
0405 f_bbct[arm] += first_time[ipmt];
0406
0407
0408 }
0409 else
0410 {
0411 cout << "ERROR, have hit but no time" << endl;
0412 }
0413
0414
0415 ++f_bbcn[arm];
0416 }
0417 }
0418
0419
0420 if ( f_bbcn[0]>0 && f_bbcn[1]> 0 )
0421 {
0422 for (int iarm=0; iarm<2; iarm++)
0423 {
0424 c_bbct->cd(iarm+1);
0425
0426 std::sort( hit_times[iarm].begin(), hit_times[iarm].end() );
0427 float earliest = hit_times[iarm][0];
0428
0429 gaussian->SetParameter(0,5);
0430 gaussian->SetParameter(1, earliest);
0431 gaussian->SetRange(6, earliest+ 5*0.05);
0432
0433
0434
0435 hevt_bbct[iarm]->Fit(gaussian,"BLR");
0436 hevt_bbct[iarm]->Draw();
0437
0438 if ( f_bbcn[iarm] > 0 )
0439 {
0440
0441 f_bbct[iarm] = gaussian->GetParameter(1);
0442 f_bbcte[iarm] = earliest;
0443 }
0444 }
0445
0446
0447 f_bbcz = (f_bbct[0] - f_bbct[1])*C/2.0;
0448 f_bbct0 = (f_bbct[0] + f_bbct[1])/2.0;
0449
0450 }
0451
0452 c_bbct->Modified();
0453 c_bbct->Update();
0454
0455 if ( fabs(f_bbcz-f_vz)>5.0 && f_bbcn[0]>1 && f_bbcn[1]>1 )
0456 {
0457 string response;
0458 cout << "Event " << f_evt << " ? ";
0459
0460
0461 TString name = "evt_"; name += f_evt; name += ".png";
0462 c_bbct->SaveAs( name );
0463 }
0464
0465 h2_bbcqtot->Fill( f_bbcq[0], f_bbcq[1] );
0466
0467 _tree->Fill();
0468
0469
0470
0471 return 0;
0472 }
0473
0474
0475 void BBCStudy::GetNodes(PHCompositeNode *topNode)
0476 {
0477
0478
0479
0480 _truth_container = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0481 if(!_truth_container && f_evt<10) cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << endl;
0482
0483
0484 _bbchits = findNode::getClass<PHG4HitContainer> (topNode, "G4HIT_BBC");
0485 if(!_bbchits && f_evt<10) cout << PHWHERE << " G4HIT_BBC node not found on node tree" << endl;
0486
0487 _evtheader = findNode::getClass<EventHeaderv1>(topNode, "EventHeader");
0488 if (!_evtheader && f_evt<10) cout << PHWHERE << " G4HIT_BBC node not found on node tree" << endl;
0489
0490 }
0491
0492
0493 int BBCStudy::End(PHCompositeNode *topNode)
0494 {
0495 _savefile->cd();
0496 _savefile->Write();
0497 _savefile->Close();
0498
0499
0500 cout << "PIDs of Particles that hit BBC" << endl;
0501 unsigned int ipid = 0;
0502 double npart = 0;
0503 for (auto & pid : _pids)
0504 {
0505 npart += pid.second;
0506 }
0507 for (auto & pid : _pids)
0508 {
0509 cout << pid.first << "\t" << pid.second << "\t" << pid.second/npart << endl;
0510 ipid++;
0511 }
0512 cout << "There were " << ipid << " different particle types" << endl;
0513
0514 return 0;
0515 }
0516
0517 void BBCStudy::CheckDST(PHCompositeNode *topNode)
0518 {
0519
0520 _bbcout = findNode::getClass<MbdOut>(topNode, "MbdOut");
0521 if(!_bbcout && f_evt<4) cout << PHWHERE << " MbdOut node not found on node tree" << endl;
0522
0523
0524 _bbcpmts = findNode::getClass<MbdPmtContainer>(topNode, "MbdPmtContainer");
0525 if(!_bbcpmts && f_evt<4) cout << PHWHERE << " MbdPmtContainer node not found on node tree" << endl;
0526
0527 Float_t bbcz = _bbcout->get_zvtx();
0528 if ( f_bbcz != bbcz )
0529 {
0530 cout << "ERROR, f_bbcz != bbcz, " << f_bbcz << "\t" << bbcz << endl;
0531 }
0532
0533 for (int iarm=0; iarm<2; iarm++)
0534 {
0535 if ( f_bbcq[iarm] != _bbcout->get_q(iarm) )
0536 {
0537 cout << "ERROR, f_bbcq != bbcq, arm " << iarm << "\t" << f_bbcq[iarm] << "\t" << _bbcout->get_q(iarm) << endl;
0538 }
0539 }
0540
0541 }