File indexing completed on 2025-08-06 08:18:51
0001 #include "MbdDigitization.h"
0002
0003 #include <mbd/MbdDefs.h>
0004 #include <mbd/MbdPmtSimContainerV1.h>
0005 #include <mbd/MbdPmtHit.h>
0006
0007 #include <g4main/PHG4Hit.h>
0008 #include <g4main/PHG4HitContainer.h>
0009 #include <g4main/PHG4Particle.h>
0010 #include <g4main/PHG4TruthInfoContainer.h>
0011 #include <g4main/PHG4VtxPoint.h>
0012
0013 #include <fun4all/Fun4AllServer.h>
0014 #include <fun4all/PHTFileServer.h>
0015
0016 #include <phool/PHCompositeNode.h>
0017 #include <phool/PHIODataNode.h>
0018 #include <phool/PHNode.h>
0019 #include <phool/PHNodeIterator.h>
0020 #include <phool/PHObject.h>
0021 #include <phool/PHRandomSeed.h>
0022 #include <phool/getClass.h>
0023 #include <phool/phool.h>
0024 #include <phool/sphenix_constants.h>
0025
0026 #include <TDatabasePDG.h>
0027 #include <TF1.h>
0028 #include <TFile.h>
0029 #include <TH1F.h>
0030 #include <TH2F.h>
0031 #include <TLorentzVector.h>
0032 #include <TString.h>
0033 #include <TSystem.h>
0034 #include <TTree.h>
0035
0036 #include <gsl/gsl_randist.h>
0037 #include <gsl/gsl_rng.h>
0038
0039 #include <cmath>
0040 #include <iostream>
0041
0042
0043 MbdDigitization::MbdDigitization(const std::string &name)
0044 : SubsysReco(name)
0045 , _tres(0.05)
0046 {
0047 std::fill(std::begin(f_pmtq), std::end(f_pmtq), 0.);
0048 std::fill(std::begin(f_pmtnpe), std::end(f_pmtnpe), 0.);
0049 std::fill(std::begin(f_pmtt0), std::end(f_pmtt0), std::numeric_limits<float>::quiet_NaN());
0050 std::fill(std::begin(f_pmtt1), std::end(f_pmtt1), std::numeric_limits<float>::quiet_NaN());
0051 m_RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937);
0052 m_Seed = PHRandomSeed();
0053 gsl_rng_set(m_RandomGenerator, m_Seed);
0054 }
0055
0056 MbdDigitization::~MbdDigitization()
0057 {
0058 gsl_rng_free(m_RandomGenerator);
0059 return;
0060 }
0061
0062
0063 int MbdDigitization::Init(PHCompositeNode *topNode)
0064 {
0065 if ( Verbosity() )
0066 {
0067 std::cout << PHWHERE << std::endl;
0068 }
0069 CreateNodes(topNode);
0070
0071 _pdg = new TDatabasePDG();
0072
0073 gaussian = new TF1("gaussian", "gaus", 0, 20);
0074 gaussian->FixParameter(2, _tres);
0075
0076 return 0;
0077 }
0078
0079
0080 int MbdDigitization::InitRun(PHCompositeNode *topNode)
0081 {
0082 GetNodes(topNode);
0083
0084 _gains = { 135.137, 135.035, 134.861, 134.543, 135.761, 134.942, 134.053, 134.398,
0085 135.568, 134.874, 134.677, 135.614, 135.366, 134.564, 135.143, 135.412, 135.308,
0086 135.752, 134.392, 135.372, 135.025, 135.247, 135.337, 135.396, 133.553, 134.93,
0087 135.917, 135.209, 135.886, 134.914, 134.766, 135.734, 135.343, 134.815, 134.68,
0088 135.214, 135.251, 134.617, 135.182, 134.659, 135.119, 135.022, 134.648, 134.814,
0089 135.1, 134.99, 134.82, 134.844, 135.817, 135.788, 135.469, 135.178, 135.17, 134.938,
0090 135.544, 135.445, 134.872, 134.4, 134.875, 134.852, 134.23, 133.922, 135.46, 134.44,
0091 135.475, 135.716, 135.084, 136.074, 136.198, 136.226, 136.214, 136.1, 136.727,
0092 135.422, 136.258, 136.394, 135.754, 136.072, 136.897, 135.775, 135.902, 135.959,
0093 136.306, 135.846, 135.986, 135.487, 136.404, 134.988, 135.858, 136.511, 136.128,
0094 135.535, 135.984, 136.162, 135.496, 135.104, 135.762, 135.653, 135.379, 135.868,
0095 136.747, 135.606, 136.074, 135.833, 136.382, 135.796, 135.364, 135.985, 135.46,
0096 135.869, 136.068, 135.876, 136.339, 135.48, 136.435, 135.997, 136.01, 136.675,
0097 136.105, 136.423, 135.739, 136.112, 136.523, 135.883, 136.972, 136.741, 135.419, 135.407 };
0098
0099 return 0;
0100 }
0101
0102
0103
0104 int MbdDigitization::process_event(PHCompositeNode * )
0105 {
0106 if ( Verbosity() )
0107 {
0108 std::cout << PHWHERE << std::endl;
0109 }
0110
0111
0112
0113 float len[MbdDefs::MBD_N_PMT] = {0.};
0114 float edep[MbdDefs::MBD_N_PMT] = {0.};
0115 float first_time[MbdDefs::MBD_N_PMT];
0116 std::fill_n(first_time, MbdDefs::MBD_N_PMT, 1e12);
0117 std::fill_n(f_pmtt0, MbdDefs::MBD_N_PMT, 1e12);
0118 std::fill_n(f_pmtt1, MbdDefs::MBD_N_PMT, 1e12);
0119 std::fill_n(f_pmtq, MbdDefs::MBD_N_PMT, 0.);
0120 std::fill_n(f_pmtnpe, MbdDefs::MBD_N_PMT, 0.);
0121
0122
0123
0124 PHG4VtxPoint *vtxp = _truth_container->GetPrimaryVtx(_truth_container->GetPrimaryVertexIndex());
0125 if (vtxp != nullptr)
0126 {
0127 f_vx = vtxp->get_x();
0128 f_vy = vtxp->get_y();
0129 f_vz = vtxp->get_z();
0130 f_vt = vtxp->get_t();
0131
0132 if (Verbosity())
0133 {
0134 std::cout << "VTXP "
0135 << "\t" << f_vx << "\t" << f_vy << "\t" << f_vz << "\t" << f_vt << std::endl;
0136 }
0137 }
0138
0139
0140 if ( Verbosity()>10 )
0141 {
0142 std::cout << "Processing BBC G4 Hits" << std::endl;
0143 }
0144
0145 TLorentzVector v4;
0146 unsigned int nhits = 0;
0147
0148 PHG4HitContainer::ConstRange bbc_hit_range = _bbchits->getHits();
0149 for (auto hit_iter = bbc_hit_range.first; hit_iter != bbc_hit_range.second; hit_iter++)
0150 {
0151 PHG4Hit *this_hit = hit_iter->second;
0152
0153 unsigned int ch = this_hit->get_layer();
0154
0155
0156 int trkid = this_hit->get_trkid();
0157
0158
0159 PHG4Particle *part = _truth_container->GetParticle(trkid);
0160 v4.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e());
0161
0162 int pid = part->get_pid();
0163 TParticlePDG *partinfo = _pdg->GetParticle(pid);
0164 Double_t charge = -9999.;
0165 if (partinfo)
0166 {
0167 charge = partinfo->Charge() / 3;
0168 }
0169 else if (part->isIon())
0170 {
0171 charge = part->get_IonCharge();
0172 }
0173
0174
0175 if (this_hit->get_t(1) < first_time[ch])
0176 {
0177 if (fabs(this_hit->get_t(1)) < sphenix_constants::time_between_crossings)
0178 {
0179 first_time[ch] = this_hit->get_t(1) - vtxp->get_t();
0180 Float_t dt = gsl_ran_gaussian(m_RandomGenerator, _tres);
0181 first_time[ch] += dt;
0182 }
0183 else
0184 {
0185 if (Verbosity())
0186 {
0187 std::cout << "BAD " << ch << "\t" << this_hit->get_t(1) << std::endl;
0188 }
0189 }
0190 }
0191
0192 edep[ch] += this_hit->get_edep();
0193
0194
0195
0196 Double_t beta = v4.Beta();
0197 if (beta > MbdDefs::v_ckov && charge != 0.)
0198 {
0199 len[ch] += this_hit->get_path_length();
0200
0201 _pids[pid] += 1;
0202 }
0203
0204 nhits++;
0205 }
0206
0207 if ( Verbosity()>10 )
0208 {
0209 std::cout << "Found " << nhits << " MBD hits" << std::endl;
0210 std::cout << "Calculating response and storing in MbdPmtHits" << std::endl;
0211 }
0212
0213 for (int ipmt = 0; ipmt < MbdDefs::MBD_N_PMT; ipmt++)
0214 {
0215
0216 if (len[ipmt] > 0.)
0217 {
0218 if (Verbosity() > 0)
0219 {
0220 std::cout << "ipmt " << ipmt << "\t" << len[ipmt] << "\t" << edep[ipmt] << std::endl;
0221 }
0222
0223
0224 f_pmtnpe[ipmt] = len[ipmt] * (120 / 3.0);
0225 float dnpe = gsl_ran_gaussian(m_RandomGenerator, std::sqrt(f_pmtnpe[ipmt]));
0226
0227 float dres = gsl_ran_gaussian(m_RandomGenerator, f_pmtnpe[ipmt]*0.127);
0228
0229 f_pmtnpe[ipmt] += (dnpe+dres);
0230 f_pmtq[ipmt] = f_pmtnpe[ipmt]/_gains[ipmt];
0231
0232
0233 if (first_time[ipmt] < 9999.)
0234 {
0235 f_pmtt0[ipmt] = first_time[ipmt] - 8.346;
0236 f_pmtt1[ipmt] = first_time[ipmt] - 8.346;
0237 }
0238 else
0239 {
0240 if (Verbosity() != 0)
0241 {
0242 std::cout << "ERROR, have hit but no time" << std::endl;
0243 }
0244 }
0245
0246 _bbcpmts->get_pmt(ipmt)->set_pmt(ipmt, f_pmtq[ipmt], f_pmtt0[ipmt], f_pmtt1[ipmt]);
0247 _bbcpmts->get_pmt(ipmt)->set_simpmt(f_pmtnpe[ipmt]);
0248
0249 if (Verbosity() > 0)
0250 {
0251 std::cout << "Adding " << ipmt << ", " << f_pmtq[ipmt] << ", " << f_pmtt0[ipmt] << " , " << f_pmtt1[ipmt] << std::endl;
0252 }
0253 }
0254 else
0255 {
0256
0257 _bbcpmts->get_pmt(ipmt)->set_pmt(ipmt, f_pmtq[ipmt], f_pmtt0[ipmt], f_pmtt1[ipmt]);
0258 _bbcpmts->get_pmt(ipmt)->set_simpmt(f_pmtnpe[ipmt]);
0259 }
0260 }
0261
0262 return 0;
0263 }
0264
0265 void MbdDigitization::CreateNodes(PHCompositeNode *topNode)
0266 {
0267 PHNodeIterator iter(topNode);
0268 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0269 if (!dstNode)
0270 {
0271 std::cout << PHWHERE << "DST Node missing doing nothing" << std::endl;
0272 gSystem->Exit(1);
0273 exit(1);
0274 }
0275
0276 PHCompositeNode *bbcNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "MBD"));
0277 if (!bbcNode)
0278 {
0279 bbcNode = new PHCompositeNode("MBD");
0280 dstNode->addNode(bbcNode);
0281 }
0282
0283
0284 _bbcpmts = findNode::getClass<MbdPmtContainer>(bbcNode, "MbdPmtContainer");
0285 if (!_bbcpmts)
0286 {
0287 _bbcpmts = new MbdPmtSimContainerV1();
0288 PHIODataNode<PHObject> *BbcPmtNode = new PHIODataNode<PHObject>(_bbcpmts, "MbdPmtContainer", "PHObject");
0289 bbcNode->addNode(BbcPmtNode);
0290 }
0291 }
0292
0293
0294 void MbdDigitization::GetNodes(PHCompositeNode *topNode)
0295 {
0296
0297
0298
0299 _truth_container = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0300 if (!_truth_container)
0301 {
0302 std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl;
0303 gSystem->Exit(1);
0304 }
0305
0306
0307 _bbchits = findNode::getClass<PHG4HitContainer>(topNode, "G4HIT_BBC");
0308 if (!_bbchits)
0309 {
0310 std::cout << PHWHERE << " G4HIT_BBC node not found on node tree" << std::endl;
0311 gSystem->Exit(1);
0312 }
0313
0314
0315
0316
0317 _bbcpmts = findNode::getClass<MbdPmtContainer>(topNode, "MbdPmtContainer");
0318 if (!_bbcpmts)
0319 {
0320 std::cout << PHWHERE << " MbdPmtContainer node not found on node tree" << std::endl;
0321 gSystem->Exit(1);
0322 }
0323 }