File indexing completed on 2025-08-03 08:16:06
0001 #include "ZDCNeutronLocPol.h"
0002
0003 #include <calobase/TowerInfoDefs.h>
0004 #include <caloreco/CaloWaveformFitting.h>
0005
0006 #include <calobase/TowerInfoDefs.h>
0007 #include <caloreco/CaloWaveformFitting.h>
0008 #include <ffarawobjects/CaloPacketContainerv1.h>
0009 #include <ffarawobjects/CaloPacketv1.h>
0010 #include <ffarawobjects/Gl1Packetv1.h>
0011 #include <fun4all/Fun4AllReturnCodes.h>
0012
0013 #include <Event/packet.h>
0014
0015 #include <fun4all/Fun4AllReturnCodes.h>
0016 #include <phool/PHCompositeNode.h>
0017 #include <phool/PHIODataNode.h> // for PHIODataNode
0018 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0019 #include <phool/PHObject.h> // for PHObject
0020 #include <phool/getClass.h>
0021 #include <phool/phool.h>
0022 #include <phool/recoConsts.h>
0023
0024 #include <TFile.h>
0025 #include <TH1.h>
0026 #include <TH2.h>
0027 #include <TTree.h>
0028 #include <phool/PHCompositeNode.h>
0029 #include <cmath>
0030 #include <fstream>
0031
0032 R__LOAD_LIBRARY(libuspin.so)
0033
0034
0035 ZDCNeutronLocPol::ZDCNeutronLocPol(const std::string &name)
0036 : SubsysReco(name)
0037 {
0038 std::cout << "ZDCNeutronLocPol::ZDCNeutronLocPol(const std::string &name) Calling ctor" << std::endl;
0039 }
0040
0041
0042 ZDCNeutronLocPol::~ZDCNeutronLocPol()
0043 {
0044 std::cout << "ZDCNeutronLocPol::~ZDCNeutronLocPol() Calling dtor" << std::endl;
0045 }
0046
0047
0048 int ZDCNeutronLocPol::Init(PHCompositeNode * )
0049 {
0050 std::cout << "ZDCNeutronLocPol::Init(PHCompositeNode *topNode) Initializing" << std::endl;
0051
0052 smdHits = new TTree();
0053 smdHits = new TTree("smdHits", "smdHits");
0054 smdHits->SetDirectory(0);
0055 smdHits->Branch("bunchnumber", &bunchnumber, "bunchnumber/I");
0056
0057
0058
0059
0060 smdHits->Branch("showerCutN", &showerCutN, "showerCutN/I");
0061 smdHits->Branch("showerCutS", &showerCutS, "showerCutS/I");
0062 smdHits->Branch("n_x", &n_x, "n_x/F");
0063 smdHits->Branch("n_y", &n_y, "n_y/F");
0064 smdHits->Branch("s_x", &s_x, "s_x/F");
0065 smdHits->Branch("s_y", &s_y, "s_y/F");
0066 smdHits->Branch("zdcN1_adc", &zdcN1_adc, "zdcN1_adc/F");
0067 smdHits->Branch("zdcN2_adc", &zdcN2_adc, "zdcN2_adc/F");
0068 smdHits->Branch("zdcN3_adc", &zdcN3_adc, "zdcN3_adc/F");
0069 smdHits->Branch("zdcS1_adc", &zdcS1_adc, "zdcS1_adc/F");
0070 smdHits->Branch("zdcS2_adc", &zdcS2_adc, "zdcS2_adc/F");
0071 smdHits->Branch("zdcS3_adc", &zdcS3_adc, "zdcS3_adc/F");
0072 smdHits->Branch("veto_NF", &veto_NF, "veto_NF/F");
0073 smdHits->Branch("veto_NB", &veto_NB, "veto_NB/F");
0074 smdHits->Branch("veto_SF", &veto_SF, "veto_SF/F");
0075 smdHits->Branch("veto_SB", &veto_SB, "veto_SB/F");
0076 smdHits->Branch("smdS1_adc", &smdS1_adc, "smdS1_adc/F");
0077 smdHits->Branch("smdS2_adc", &smdS2_adc, "smdS2_adc/F");
0078 smdHits->Branch("smdS6_adc", &smdS6_adc, "smdS6_adc/F");
0079 smdHits->Branch("smdS7_adc", &smdS7_adc, "smdS7_adc/F");
0080
0081 smdHits->Branch("smdN1_adc", &smdN1_adc, "smdN1_adc/F");
0082 smdHits->Branch("smdN2_adc", &smdN2_adc, "smdN2_adc/F");
0083 smdHits->Branch("smdN6_adc", &smdN6_adc, "smdN6_adc/F");
0084 smdHits->Branch("smdN7_adc", &smdN7_adc, "smdN7_adc/F");
0085
0086 smdHits->Branch("smdS1_v_adc", &smdS1_v_adc, "smdS1_v_adc/F");
0087 smdHits->Branch("smdS2_v_adc", &smdS2_v_adc, "smdS2_v_adc/F");
0088 smdHits->Branch("smdS7_v_adc", &smdS7_v_adc, "smdS7_v_adc/F");
0089 smdHits->Branch("smdS8_v_adc", &smdS8_v_adc, "smdS8_v_adc/F");
0090
0091 smdHits->Branch("smdN1_v_adc", &smdN1_v_adc, "smdN1_v_adc/F");
0092 smdHits->Branch("smdN2_v_adc", &smdN2_v_adc, "smdN2_v_adc/F");
0093 smdHits->Branch("smdN7_v_adc", &smdN7_v_adc, "smdN7_v_adc/F");
0094 smdHits->Branch("smdN8_v_adc", &smdN8_v_adc, "smdN8_v_adc/F");
0095
0096
0097 h_waveformZDC = new TH2F("h_waveformZDC", "h_waveformZDC", 17, -0.5, 16.5, 512, -500, 20000);
0098 h_waveformSMD_North = new TH2F("h_waveformSMD_North", "h_waveformSMD_North", 17, -0.5, 16.5, 512, -500, 20000);
0099 h_waveformSMD_South = new TH2F("h_waveformSMD_South", "h_waveformSMD_South", 17, -0.5, 16.5, 512, -500, 20000);
0100 h_waveformVeto_North = new TH2F("h_waveformVeto_North", "h_waveformVeto_North", 17, -0.5, 16.5, 512, -500, 20000);
0101 h_waveformVeto_South = new TH2F("h_waveformVeto_South", "h_waveformVeto_South", 17, -0.5, 16.5, 512, -500, 20000);
0102 h_waveformAll = new TH2F("h_waveformAll", "h_waveformAll", 17, -0.5, 16.5, 512, -500, 20000);
0103
0104 for (int i = 0; i < 32; i++)
0105 {
0106 h_rawADC[i] = new TH1F(Form("rawADC%d", i), Form("rawADC%d", i), 128, 0, 4000);
0107 h_pedADC[i] = new TH1F(Form("pedADC%d", i), Form("pedADC%d", i), 128, 0, 4000);
0108 h_signalADC[i] = new TH1F(Form("signalDC%d", i), Form("signalADC%d", i), 128, 0, 4000);
0109 }
0110
0111 return Fun4AllReturnCodes::EVENT_OK;
0112 }
0113
0114
0115 int ZDCNeutronLocPol::InitRun(PHCompositeNode * )
0116 {
0117 std::cout << "ZDCNeutronLocPol::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl;
0118
0119 evtcnt = 0;
0120
0121 return Fun4AllReturnCodes::EVENT_OK;
0122 }
0123
0124
0125 int ZDCNeutronLocPol::process_event(PHCompositeNode *topNode)
0126 {
0127
0128 if (evtcnt % 10000 == 0)
0129 {
0130 std::cout << "Event: " << evtcnt << std::endl;
0131 }
0132
0133 p_gl1 = findNode::getClass<Gl1Packetv1>(topNode, "GL1Packet");
0134 zdc_cont = findNode::getClass<CaloPacketContainerv1>(topNode, "ZDCPackets");
0135
0136 showerCutN = 0;
0137 showerCutS = 0;
0138
0139 if (p_gl1)
0140 {
0141 bunchnumber = p_gl1->getBunchNumber();
0142 if (evtcnt % 1000 == 0)
0143 {
0144 std::cout << bunchnumber << std::endl;
0145 }
0146 if (zdc_cont->get_npackets() != 1)
0147 {
0148 return Fun4AllReturnCodes::EVENT_OK;
0149 }
0150
0151 CaloPacket *p_zdc = zdc_cont->getPacket(0);
0152
0153 if (p_zdc)
0154 {
0155 int nThresholdNVer = 0;
0156 int nThresholdNHor = 0;
0157 int nThresholdSVer = 0;
0158 int nThresholdSHor = 0;
0159
0160
0161
0162
0163
0164
0165
0166 for (int c = 0; c < p_zdc->iValue(0, "CHANNELS"); c++)
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
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 std::vector<float> resultFast = anaWaveformFast(p_zdc, c);
0225 float signalFast = resultFast.at(0);
0226 float timingFast = resultFast.at(1);
0227 float pedFast = resultFast.at(2);
0228
0229
0230 if (c >= 0 && c < 16)
0231 {
0232 signalFast = (4 < timingFast && timingFast < 10) ? signalFast : 0;
0233 unsigned int towerkey = TowerInfoDefs::decode_zdc(c);
0234 int zdc_side = TowerInfoDefs::get_zdc_side(towerkey);
0235 if (zdc_side == 0)
0236 {
0237 if (c == 0)
0238 {
0239 zdcS1_adc = signalFast;
0240 continue;
0241 }
0242 if (c == 2)
0243 {
0244 zdcS2_adc = signalFast;
0245 continue;
0246 }
0247 if (c == 4)
0248 {
0249 zdcS3_adc = signalFast;
0250 continue;
0251 }
0252 }
0253 else if (zdc_side == 1)
0254 {
0255 if (c == 8)
0256 {
0257 zdcN1_adc = signalFast;
0258 continue;
0259 }
0260 if (c == 10)
0261 {
0262 zdcN2_adc = signalFast;
0263 continue;
0264 }
0265 if (c == 12)
0266 {
0267 zdcN3_adc = signalFast;
0268 continue;
0269 }
0270 }
0271 }
0272
0273
0274
0275 if (c == 16)
0276 {
0277 signalFast = (6 < timingFast && timingFast < 11) ? signalFast : 0;
0278 veto_NF = signalFast;
0279 continue;
0280 }
0281 if (c == 17)
0282 {
0283 signalFast = (6 < timingFast && timingFast < 11) ? signalFast : 0;
0284 veto_NB = signalFast;
0285 continue;
0286 }
0287
0288
0289
0290 if (c >= 48 && c < 63)
0291 {
0292 signalFast = (9 < timingFast) ? signalFast : 0;
0293
0294 rawADC[c - 48] = signalFast + pedFast;
0295 pedADC[c - 48] = pedFast;
0296 signalADC[c - 48] = signalFast;
0297
0298 h_rawADC[c - 48]->Fill(signalFast + pedFast);
0299 h_pedADC[c - 48]->Fill(pedFast);
0300 h_signalADC[c - 48]->Fill(signalFast);
0301 if (c == 48)
0302 {
0303 smdN1_v_adc = signalFast;
0304 }
0305 if (c == 49)
0306 {
0307 smdN2_v_adc = signalFast;
0308 }
0309 if (c == 54)
0310 {
0311 smdN7_v_adc = signalFast;
0312 }
0313 if (c == 55)
0314 {
0315 smdN8_v_adc = signalFast;
0316 }
0317 if (c == 56)
0318 {
0319 smdN1_adc = signalFast;
0320 }
0321 if (c == 57)
0322 {
0323 smdN2_adc = signalFast;
0324 }
0325 if (c == 61)
0326 {
0327 smdN6_adc = signalFast;
0328 }
0329 if (c == 62)
0330 {
0331 smdN7_adc = signalFast;
0332 }
0333 if (c < 56 && signalFast > 5.)
0334 {
0335 nThresholdNHor++;
0336 }
0337 if (c >= 56 && signalFast > 5.)
0338 {
0339 nThresholdNVer++;
0340 }
0341 continue;
0342 }
0343
0344
0345
0346 if (c == 80)
0347 {
0348 signalFast = (6 < timingFast && timingFast < 11) ? signalFast : 0;
0349 veto_SF = signalFast;
0350 continue;
0351 }
0352 if (c == 81)
0353 {
0354 signalFast = (6 < timingFast && timingFast < 11) ? signalFast : 0;
0355 veto_SB = signalFast;
0356 continue;
0357 }
0358
0359
0360 if (c >= 112 && c < 127)
0361 {
0362 signalFast = (7 < timingFast && timingFast < 12) ? signalFast : 0;
0363 rawADC[c - 96] = signalFast + pedFast;
0364 pedADC[c - 96] = pedFast;
0365 signalADC[c - 96] = signalFast;
0366
0367 h_rawADC[c - 96]->Fill(signalFast + pedFast);
0368 h_pedADC[c - 96]->Fill(pedFast);
0369 h_signalADC[c - 96]->Fill(signalFast);
0370 if (c == 112)
0371 {
0372 smdS1_v_adc = signalFast;
0373 }
0374 if (c == 113)
0375 {
0376 smdS2_v_adc = signalFast;
0377 }
0378 if (c == 118)
0379 {
0380 smdS7_v_adc = signalFast;
0381 }
0382 if (c == 119)
0383 {
0384 smdS8_v_adc = signalFast;
0385 }
0386 if (c == 120)
0387 {
0388 smdS1_adc = signalFast;
0389 }
0390 if (c == 121)
0391 {
0392 smdS2_adc = signalFast;
0393 }
0394 if (c == 125)
0395 {
0396 smdS6_adc = signalFast;
0397 }
0398 if (c == 126)
0399 {
0400 smdS7_adc = signalFast;
0401 }
0402 if (c < 120 && signalFast > 5.)
0403 {
0404 nThresholdSHor++;
0405 }
0406 if (c >= 120 && signalFast > 5.)
0407 {
0408 nThresholdSVer++;
0409 }
0410 continue;
0411 }
0412
0413
0414 }
0415
0416
0417 if (nThresholdNHor > 1 && nThresholdNVer > 1)
0418 {
0419 showerCutN = 1;
0420 }
0421
0422 if (nThresholdSHor > 1 && nThresholdSVer > 1)
0423 {
0424 showerCutS = 1;
0425 }
0426
0427
0428 CompSmdAdc();
0429 CompSmdPos();
0430 n_y = smd_pos[0];
0431 n_x = smd_pos[1];
0432 s_y = smd_pos[2];
0433
0434 s_x = smd_pos[3];
0435 smdHits->Fill();
0436 }
0437 }
0438
0439 evtcnt++;
0440
0441 return Fun4AllReturnCodes::EVENT_OK;
0442 }
0443
0444
0445 int ZDCNeutronLocPol::End(PHCompositeNode * )
0446 {
0447 std::cout << "ZDCNeutronLocPol::End(PHCompositeNode *topNode) This is the End..." << std::endl;
0448 TFile *ofile = new TFile(outfile.c_str(), "RECREATE");
0449
0450 smdHits->Write();
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466 ofile->Write();
0467 ofile->Close();
0468 delete (smdHits);
0469
0470 return Fun4AllReturnCodes::EVENT_OK;
0471 }
0472
0473 std::vector<float> ZDCNeutronLocPol::anaWaveformFast(CaloPacket *p, const int channel)
0474 {
0475 std::vector<float> waveform;
0476
0477 waveform.reserve(p->iValue(0, "SAMPLES"));
0478 for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
0479 {
0480 waveform.push_back(p->iValue(s, channel));
0481 }
0482 std::vector<std::vector<float>> multiple_wfs;
0483 multiple_wfs.push_back(waveform);
0484
0485 std::vector<std::vector<float>> fitresults_zdc;
0486 fitresults_zdc = WaveformProcessingFast->calo_processing_fast(multiple_wfs);
0487
0488 std::vector<float> result;
0489 result = fitresults_zdc.at(0);
0490 return result;
0491 }
0492
0493 void ZDCNeutronLocPol::CompSmdAdc()
0494 {
0495 for (int i = 0; i < 15; i++)
0496 {
0497
0498
0499
0500 signalADC[i] = signalADC[i] * smd_north_rgain[i];
0501 signalADC[i + 16] = signalADC[i + 16] * smd_south_rgain[i];
0502 }
0503 }
0504
0505 void ZDCNeutronLocPol::CompSmdPos()
0506 {
0507 float w_ave[4];
0508 float weights[4] = {0};
0509 memset(weights, 0, sizeof(weights));
0510 float w_sum[4];
0511 memset(w_sum, 0, sizeof(w_sum));
0512
0513 float smd_threshold = 5.;
0514
0515
0516 const float hor_scale = 2.0 * 11.0 / 10.5 * sin(3.1415 / 4);
0517 const float ver_scale = 1.5 * 11.0 / 10.5;
0518 float hor_offset = (hor_scale * 8 / 2.0) * (7.0 / 8.0);
0519 float ver_offset = (ver_scale * 7 / 2.0) * (6.0 / 7.0);
0520
0521 for (int i = 0; i < 8; i++)
0522 {
0523 if (signalADC[i] > smd_threshold)
0524 {
0525 weights[0] += signalADC[i];
0526 w_sum[0] += (float) i * signalADC[i];
0527 }
0528
0529 if (signalADC[i + 16] > smd_threshold)
0530 {
0531 weights[2] += signalADC[i + 16];
0532 w_sum[2] += ((float) i + 16.) * signalADC[i + 16];
0533 }
0534 }
0535 for (int i = 0; i < 7; i++)
0536 {
0537 if (signalADC[i + 8] > smd_threshold)
0538 {
0539 weights[1] += signalADC[i + 8];
0540 w_sum[1] += ((float) i + 8.) * signalADC[i + 8];
0541 }
0542
0543 if (signalADC[i + 24] > smd_threshold)
0544 {
0545 weights[3] += signalADC[i + 24];
0546 w_sum[3] += ((float) i + 24.) * signalADC[i + 24];
0547 }
0548 }
0549
0550 if (weights[0] > 0.0)
0551 {
0552 w_ave[0] = w_sum[0] / weights[0];
0553 smd_pos[0] = hor_scale * w_ave[0] - hor_offset;
0554 }
0555 else
0556 {
0557 smd_pos[0] = 0;
0558 }
0559
0560 if (weights[1] > 0.0)
0561 {
0562 w_ave[1] = w_sum[1] / weights[1];
0563 smd_pos[1] = ver_scale * (w_ave[1] - 8.0) - ver_offset;
0564 }
0565 else
0566 {
0567 smd_pos[1] = 0;
0568 }
0569
0570 if (weights[2] > 0.0)
0571 {
0572 w_ave[2] = w_sum[2] / weights[2];
0573 smd_pos[2] = hor_scale * (w_ave[2] - 16.0) - hor_offset;
0574 }
0575 else
0576 {
0577 smd_pos[2] = 0;
0578 }
0579
0580 if (weights[3] > 0.0)
0581 {
0582 w_ave[3] = w_sum[3] / weights[3];
0583 smd_pos[3] = ver_scale * (w_ave[3] - 24.0) - ver_offset;
0584 }
0585 else
0586 {
0587 smd_pos[3] = 0;
0588 }
0589 }
0590
0591 void ZDCNeutronLocPol::setFileName(const std::string &fname)
0592 {
0593 outfile = fname;
0594 }
0595
0596 void ZDCNeutronLocPol::setGainMatch(const std::string &gainfile)
0597 {
0598
0599 float col1;
0600 std::string col2;
0601
0602 std::ifstream gain_infile(gainfile);
0603
0604 if (!gain_infile)
0605 {
0606 std::cout << "No relative gain file: All relative gains set to 1." << std::endl;
0607 return;
0608 }
0609
0610 std::cout << "SMD Relative Gains: " << std::endl;
0611
0612 for (float &i : gain)
0613 {
0614 gain_infile >> col1 >> col2;
0615 i = col1;
0616 }
0617
0618 for (int i = 0; i < 16; i++)
0619 {
0620 smd_north_rgain[i] = gain[i];
0621 std::cout << "N" << i << " " << gain[i] << std::endl;
0622 }
0623
0624 for (int i = 0; i < 16; i++)
0625 {
0626 smd_south_rgain[i] = gain[i + 16];
0627 std::cout << "S" << i << " " << gain[i] << std::endl;
0628 }
0629
0630 gain_infile.close();
0631 }