Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:20:29

0001 // use #include "" only for your local include and put
0002 // those in the first line(s) before any #include <>
0003 // otherwise you are asking for weird behavior
0004 // (more info - check the difference in include path search when using "" versus <>)
0005 
0006 #include "SepdMon.h"
0007 
0008 #include <onlmon/OnlMon.h>  // for OnlMon
0009 #include <onlmon/OnlMonDB.h>
0010 #include <onlmon/OnlMonServer.h>
0011 #include <onlmon/pseudoRunningMean.h>
0012 #include <onlmon/triggerEnum.h> // for trigger selection
0013 
0014 #include <calobase/TowerInfoDefs.h>
0015 #include <caloreco/CaloWaveformFitting.h>
0016 
0017 #include <Event/Event.h>
0018 #include <Event/eventReceiverClient.h>
0019 #include <Event/msg_profile.h>
0020 
0021 #include <TH1.h>
0022 #include <TH2.h>
0023 #include <TProfile.h>
0024 #include <TRandom.h>
0025 
0026 #include <cmath>
0027 #include <cstdio>  // for printf
0028 #include <fstream>
0029 #include <iostream>
0030 #include <sstream>
0031 #include <string>  // for allocator, string, char_traits
0032 
0033 enum
0034 {
0035   TRGMESSAGE = 1,
0036   FILLMESSAGE = 2
0037 };
0038 
0039 SepdMon::SepdMon(const std::string &name)
0040   : OnlMon(name)
0041 {
0042   // leave ctor fairly empty, its hard to debug if code crashes already
0043   // during a new EpdMon()
0044   return;
0045 }
0046 
0047 SepdMon::~SepdMon()
0048 {
0049   // you can delete NULL pointers it results in a NOOP (No Operation)
0050   std::vector<runningMean *>::iterator rm_it;
0051   for (auto iter : rm_packet_number)
0052   {
0053     delete iter;
0054   }
0055   for (auto iter : rm_packet_length)
0056   {
0057     delete iter;
0058   }
0059   for (auto iter : rm_packet_chans)
0060   {
0061     delete iter;
0062   }
0063   for (auto iter : rm_packet_event)
0064   {
0065     delete iter;
0066   }
0067   if (erc)
0068   {
0069     delete erc;
0070   }
0071   return;
0072 }
0073 
0074 int SepdMon::Init()
0075 {
0076   gRandom->SetSeed(rand());
0077   // read our calibrations from EpdMonData.dat
0078   /*
0079   const char *sepdcalib = getenv("SEPDCALIB");
0080   if (!sepdcalib)
0081   {
0082     std::cout << "SEPDCALIB environment variable not set" << std::endl;
0083     exit(1);
0084   }
0085   std::string fullfile = std::string(sepdcalib) + "/" + "SepdMonData.dat";
0086   std::ifstream calib(fullfile);
0087 
0088   calib.close();
0089    */
0090   // use printf for stuff which should go the screen but not into the message
0091   // system (all couts are redirected)
0092   printf("doing the Init\n");
0093 
0094   // --- copied straight from the MBD code
0095   mbdns = (0x1UL << TriggerEnum::MBD_NS2) | (0x1UL << TriggerEnum::MBD_NS1); // mbd wide triggers
0096   mbdnsvtx10 = (0x1UL << TriggerEnum::MBD_NS2_ZVRTX10) | (0x1UL << TriggerEnum::MBD_NS1_ZVRTX10);
0097   mbdnsvtx30 = (0x1UL << TriggerEnum::MBD_NS2_ZVRTX30);
0098   mbdnsvtx150 = (0x1UL << TriggerEnum::MBD_NS2_ZVRTX150);
0099   mbdtrig = mbdns | mbdnsvtx10 | mbdnsvtx30 | mbdnsvtx150;
0100 
0101 
0102   h_ADC_all_channel = new TH1D("h_ADC_all_channel",";;",768,-0.5,767.5);
0103   h_hits_all_channel = new TH1D("h_hits_all_channel",";;",768,-0.5,767.5);
0104 
0105   p_noiserms_all_channel = new TProfile("p_noiserms_all_channel","",768,0,768,"S");
0106 
0107   int nADCcorr = 500;
0108   double ADCcorrmax = 6e6;
0109   int nhitscorr = 500;
0110   double hitscorrmax = 1000;
0111   h_ADC_corr = new TH2F("h_ADC_corr", ";ADC sum (south); ADC sum (north)", nADCcorr, 0, ADCcorrmax, nADCcorr, 0, ADCcorrmax);
0112   h_hits_corr = new TH2F("h_hits_corr", ";N hits sum (south); N hits sum (north)", nhitscorr, 0, hitscorrmax, nhitscorr, 0, hitscorrmax);
0113 
0114   h_event = new TH1D("h_event", "", 1, 0, 1);
0115 
0116   // waveform processing
0117   h1_waveform_twrAvg = new TH1D("h1_waveform_twrAvg", "", n_samples_show, 0.5, n_samples_show + 0.5);
0118   h1_waveform_time = new TH1D("h1_waveform_time", "", n_samples_show, 0.5, n_samples_show + 0.5);
0119   //h1_waveform_pedestal = new TH1D("h1_waveform_pedestal", "", 42, 1.0e3, 2.0e3);
0120   // --- wider range and more bins, copied from HCal
0121   h1_waveform_pedestal = new TH1F("h1_waveform_pedestal", "", 5e3, 0, 5e3);
0122   h2_sepd_waveform = new TH2F("h2_sepd_waveform", "", n_samples_show, 0.5, n_samples_show + 0.5, 1000, 0, 15000);
0123 
0124   // waveform processing, template vs. fast interpolation
0125   h1_sepd_fitting_sigDiff = new TH1D("h1_fitting_sigDiff", "", 50, 0, 2);
0126   h1_sepd_fitting_pedDiff = new TH1D("h1_fitting_pedDiff", "", 50, 0, 2);
0127   h1_sepd_fitting_timeDiff = new TH1D("h1_fitting_timeDiff", "", 50, -10, 10);
0128 
0129   // packet stuff
0130   h1_packet_number = new TH1D("h1_packet_number", "", 6, packetlow - 0.5, packethigh + 0.5);
0131   h1_packet_length = new TH1D("h1_packet_length", "", 6, packetlow - 0.5, packethigh + 0.5);
0132   h1_packet_chans = new TH1D("h1_packet_chans", "", 6, packetlow - 0.5, packethigh + 0.5);
0133   h1_packet_event = new TH1D("h1_packet_event", "", 6, packetlow - 0.5, packethigh + 0.5);
0134 
0135   for (int i = 0; i < 6; i++)
0136   {
0137     rm_packet_number.push_back(new pseudoRunningMean(1, packet_depth));
0138     rm_packet_length.push_back(new pseudoRunningMean(1, packet_depth));
0139     rm_packet_chans.push_back(new pseudoRunningMean(1, packet_depth));
0140     rm_packet_event.push_back(new pseudoRunningMean(1, packet_depth));
0141   }
0142 
0143   OnlMonServer *se = OnlMonServer::instance();
0144   // register histograms with server otherwise client won't get them
0145   // first histogram uses the TH1->GetName() as key
0146   se->registerHisto(this, h_ADC_all_channel);
0147   se->registerHisto(this, h_hits_all_channel);
0148   se->registerHisto(this, h_ADC_corr);
0149   se->registerHisto(this, h_hits_corr);
0150   se->registerHisto(this, h_event);
0151   se->registerHisto(this, h1_waveform_twrAvg);
0152   se->registerHisto(this, h1_waveform_time);
0153   se->registerHisto(this, h1_waveform_pedestal);
0154   se->registerHisto(this, h2_sepd_waveform);
0155   se->registerHisto(this, h1_packet_number);
0156   se->registerHisto(this, h1_packet_length);
0157   se->registerHisto(this, h1_packet_chans);
0158   se->registerHisto(this, h1_packet_event);
0159   //  se->registerHisto(this, h1_sepd_fitting_sigDiff);
0160   //  se->registerHisto(this, h1_sepd_fitting_pedDiff);
0161   //  se->registerHisto(this, h1_sepd_fitting_timeDiff);
0162 
0163   // save inidividual channel ADC distribution
0164   //for (int ichannel = 0; ichannel < nChannels; ichannel++)
0165   for (int ichannel = 0; ichannel < 768; ichannel++)
0166   {
0167     h_ADC_channel[ichannel] = new TH1D(Form("h_ADC_channel_%d", ichannel), ";ADC;Counts", 1000, 0, 1000);
0168     se->registerHisto(this, h_ADC_channel[ichannel]);
0169   }
0170   se->registerHisto(this, p_noiserms_all_channel);
0171 
0172   // initialize waveform extraction tool
0173   WaveformProcessingFast = new CaloWaveformFitting();
0174 
0175   WaveformProcessingTemp = new CaloWaveformFitting();
0176 
0177   std::string sepdtemplate;
0178   if (getenv("SEPDCALIB"))
0179   {
0180     sepdtemplate = getenv("SEPDCALIB");
0181   }
0182   else
0183   {
0184     sepdtemplate = ".";
0185   }
0186   sepdtemplate += std::string("/testbeam_sepd_template.root");
0187   // WaveformProcessingTemp->initialize_processing(sepdtemplate);
0188 
0189   Reset();
0190 
0191   // if (anaGL1)
0192   // {
0193   //erc = new eventReceiverClient("localhost"); // local testing
0194   erc = new eventReceiverClient("gl1daq"); // 1008 deployment
0195   // }
0196 
0197   return 0;
0198 }
0199 
0200 int SepdMon::BeginRun(const int /* runno */)
0201 {
0202   // if you need to read calibrations on a run by run basis
0203   // this is the place to do it
0204   std::vector<runningMean *>::iterator rm_it;
0205   for (rm_it = rm_packet_number.begin(); rm_it != rm_packet_number.end(); ++rm_it)
0206   {
0207     (*rm_it)->Reset();
0208   }
0209   for (rm_it = rm_packet_length.begin(); rm_it != rm_packet_length.end(); ++rm_it)
0210   {
0211     (*rm_it)->Reset();
0212   }
0213   for (rm_it = rm_packet_chans.begin(); rm_it != rm_packet_chans.end(); ++rm_it)
0214   {
0215     (*rm_it)->Reset();
0216   }
0217   for (rm_it = rm_packet_event.begin(); rm_it != rm_packet_event.end(); ++rm_it)
0218   {
0219     (*rm_it)->Reset();
0220   }
0221   // if (anaGL1)
0222   // {
0223   OnlMonServer *se = OnlMonServer::instance();
0224   se->UseGl1();
0225   // }
0226   return 0;
0227 }
0228 
0229 // simple wavefrom analysis for possibe issues with the wavforProcessor
0230 std::vector<float> SepdMon::getSignal(Packet *p, const int channel)
0231 {
0232   double baseline = 0;
0233   for (int s = 0; s < 3; s++)
0234   {
0235     baseline += p->iValue(s, channel);
0236   }
0237   baseline /= 3.;
0238 
0239   double signal = 0;
0240   float x = 0;
0241   for (int s = 3; s < p->iValue(0, "SAMPLES"); s++)
0242   {
0243     x++;
0244     signal += p->iValue(s, channel) - baseline;
0245   }
0246 
0247   signal /= x;
0248 
0249   // simulate a failure  if ( evtcount > 450 && p->getIdentifier() ==6011) return 0;
0250 
0251   std::vector<float> result;
0252   result.push_back(signal);
0253   result.push_back(2);
0254   result.push_back(1);
0255   return result;
0256 }
0257 
0258 std::vector<float> SepdMon::anaWaveformFast(Packet *p, const int channel)
0259 {
0260   std::vector<float> waveform;
0261   for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
0262   {
0263     waveform.push_back(p->iValue(s, channel));
0264   }
0265   std::vector<std::vector<float>> multiple_wfs;
0266   multiple_wfs.push_back(waveform);
0267 
0268   std::vector<std::vector<float>> fitresults_sepd;
0269   fitresults_sepd = WaveformProcessingFast->calo_processing_fast(multiple_wfs);
0270 
0271   std::vector<float> result;
0272   result = fitresults_sepd.at(0);
0273 
0274   return result;
0275 }
0276 
0277 std::vector<float> SepdMon::anaWaveformTemp(Packet *p, const int channel)
0278 {
0279   std::vector<float> waveform;
0280   for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
0281   {
0282     waveform.push_back(p->iValue(s, channel));
0283   }
0284   std::vector<std::vector<float>> multiple_wfs;
0285   multiple_wfs.push_back(waveform);
0286 
0287   std::vector<std::vector<float>> fitresults_sepd;
0288   fitresults_sepd = WaveformProcessingTemp->process_waveform(multiple_wfs);
0289 
0290   std::vector<float> result;
0291   result = fitresults_sepd.at(0);
0292 
0293   return result;
0294 }
0295 
0296 int SepdMon::process_event(Event *e /* evt */)
0297 {
0298   evtcnt++;
0299   //h1_packet_event->Reset(); // not sure about this...
0300   unsigned int ChannelNumber = 0;
0301   //  float sectorAvg[Nsector] = {0};
0302   // int phi_in = 0;
0303   // float phi;
0304   // float r;
0305   int sumhit_s = 0;
0306   int sumhit_n = 0;
0307   long double sumADC_s = 0;
0308   long double sumADC_n = 0;
0309 
0310   // --- get the trigger info...
0311   bool is_trigger_okay = false;
0312   int evtnr = e->getEvtSequence();
0313   Event* gl1Event = erc->getEvent(evtnr);
0314   // --- only do this insanity for diagnostic purposes and a small number of events
0315   // std::cout << "event number evtnr is " << evtnr << std::endl;
0316   // std::cout << "gl1Event pointer is " << gl1Event << std::endl;
0317   if ( gl1Event )
0318     {
0319       OnlMonServer *se = OnlMonServer::instance();
0320       se->IncrementGl1FoundCounter();
0321       Packet* pgl1 = gl1Event->getPacket(14001);
0322       // --- only do this insanity for diagnostic purposes and a small number of events
0323       // std::cout << "gl1 packet 14001 pointer is " << pgl1 << std::endl;
0324       if ( pgl1 )
0325         {
0326           uint64_t triggervec = pgl1->lValue(0, "ScaledVector");
0327           is_trigger_okay = triggervec & mbdtrig;
0328           // --- only do this insanity for diagnostic purposes and a small number of events
0329           // std::cout << "triggervec is " << triggervec << std::endl;
0330           // std::cout << "mbdtrig is " << mbdtrig << std::endl;
0331           // std::cout << "trigger decision is " << is_trigger_okay << std::endl;
0332           delete pgl1;
0333         }
0334       delete gl1Event;
0335     }
0336 
0337   uint64_t zdc_clock = 0;
0338   Packet* pzdc = e->getPacket(12001);
0339   if ( pzdc )
0340     {
0341       zdc_clock = pzdc->lValue(0,"CLOCK");
0342       // --- only do this insanity for diagnostic purposes and a small number of events
0343       // std::cout << "ZDC clock is " << zdc_clock << std::endl;
0344       delete pzdc;
0345     }
0346   // --- only do this insanity for diagnostic purposes and a small number of events
0347   // else std::cout << "Why no ZDC packet..." << std::endl;
0348 
0349   // loop over packets which contain a single sector
0350   for (int packet = packetlow; packet <= packethigh; packet++)
0351   {
0352     Packet *p = e->getPacket(packet);
0353     int packet_index = packet - packetlow;
0354     int packet_bin = packet - packetlow + 1;
0355     if (p)
0356     {
0357       int one[1] = {1};
0358       rm_packet_number[packet_index]->Add(one);
0359       int packet_length[1] = {p->getLength()};
0360       rm_packet_length[packet_index]->Add(packet_length);
0361 
0362       h1_packet_length->SetBinContent(packet_bin, rm_packet_length[packet_index]->getMean(0));
0363 
0364       // ---
0365       uint64_t p_clock = p->lValue(0,"CLOCK");
0366       long long clock_diff = p_clock-zdc_clock;
0367       double cd = (double)clock_diff;
0368       // --- only do this insanity for diagnostic purposes and a small number of events
0369       // std::cout << "Packet clock is " << p_clock << " and clock diff is " << clock_diff << " " << cd << std::endl;
0370       // --- trying to improve clock diff...
0371       // --- currently we overwrite the histogram with the difference from the latest event
0372       // --- not sure if we want to do that or running mean, which is done for the number, length, channels
0373       // h1_packet_event->SetBinContent(packet - packetlow + 1, p->lValue(0, "CLOCK"));
0374       // h1_packet_event->SetBinContent(packet_bin, clock_diff);
0375       // h1_packet_event->SetBinContent(packet_bin, cd);
0376       rm_packet_event[packet_index]->Add(&cd);
0377       h1_packet_event->SetBinContent(packet_bin, rm_packet_event[packet_index]->getMean(0));
0378       // --- only do this insanity for diagnostic purposes and a small number of events
0379       // std::cout << "Histogram bin " << packet_bin << " center " << h1_packet_event->GetBinCenter(packet_bin) << " bin content " << h1_packet_event->GetBinContent(packet_bin) << std::endl;
0380       int nPacketChannels = p->iValue(0, "CHANNELS");
0381       if (nPacketChannels > m_nChannels)
0382       {
0383         return -1;  // packet is corrupted, reports too many channels
0384       }
0385       // else
0386       // {
0387       //   rm_packet_chans[packet - packetlow]->Add(&nChannels);
0388       //   h1_packet_chans->SetBinContent(packet_bin, rm_packet_chans[packet - packetlow]->getMean(0));
0389       // }
0390       int channel_counter = 0;
0391       for (int c = 0; c < p->iValue(0, "CHANNELS"); c++)
0392       {
0393         // msg << "Filling channel: " << c << " for packet: " << packet << std::endl;
0394         // se->send_message(this, MSG_SOURCE_UNSPECIFIED, MSG_SEV_INFORMATIONAL, msg.str(), TRGMESSAGE);
0395         //  record waveform to show the average waveform
0396         channel_counter++;
0397 
0398         ChannelNumber++;
0399         int ch = ChannelNumber-1;
0400 
0401         // -- bit flipped ADC channels
0402         //bool reject_this_channel = false;
0403         //if ( ( packet == 9001 || packet == 9002 || packet == 9006 ) && c == 30 )
0404         //  reject_this_channel = true;
0405 
0406         //if ( reject_this_channel ) continue;
0407 
0408         // std::vector result =  getSignal(p,c); // simple peak extraction
0409         std::vector<float> resultFast = anaWaveformFast(p, c);  // fast waveform fitting
0410         float signalFast = resultFast.at(0);
0411         float timeFast = resultFast.at(1);
0412         float pedestalFast = resultFast.at(2);
0413         float prepost = p->iValue(c, "PRE") - p->iValue(c, "POST");
0414         if ( prepost > 0 )
0415           {
0416             p_noiserms_all_channel->Fill(ch,prepost);
0417             p_noiserms_all_channel->Fill(ch,-prepost);
0418           }
0419 
0420         // --- Run24pp
0421         //bool is_good_hit = ( signalFast > 50 && signalFast < 3000 );
0422         // --- Run25AuAu
0423         bool is_good_hit = ( signalFast > 50 && signalFast < 15000 );
0424 
0425         // std::vector<float> resultTemp = anaWaveformTemp(p, c);  // template waveform fitting
0426         // float signalTemp = resultTemp.at(0);
0427         // float timeTemp  = resultTemp.at(1);
0428         // float pedestalTemp = resultTemp.at(2);
0429         if (signalFast > hit_threshold)
0430         {
0431           for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
0432           {
0433             h2_sepd_waveform->Fill(s, p->iValue(s, c) - pedestalFast);
0434           }
0435         }
0436         // ---
0437         if ( signalFast > 0 && signalFast < 1e10 )
0438           {
0439             // --- 1d ADC distributions for all channels
0440             h_ADC_channel[ch]->Fill(signalFast);
0441             // --- total ADC vs channel number
0442             h_ADC_all_channel->Fill(ch,signalFast);
0443             // --- total hits vs channel number
0444             if ( is_good_hit ) h_hits_all_channel->Fill(ch);
0445             // --- 1d waveform
0446             h1_waveform_time->Fill(timeFast);
0447             h1_waveform_pedestal->Fill(pedestalFast);
0448           }
0449         // ---
0450 
0451         // h1_sepd_fitting_sigDiff -> Fill(signalFast/signalTemp);
0452         // h1_sepd_fitting_pedDiff -> Fill(pedestalFast/pedestalTemp);
0453         // h1_sepd_fitting_timeDiff -> Fill(timeFast - timeTemp);
0454 
0455         int z_bin = -1;
0456         if ( ch >= 384 && ch <= 767 ) z_bin = 0;
0457         if ( ch <= 383 && ch >= 0 ) z_bin = 1;
0458 
0459         if ( z_bin == 0 && is_good_hit )
0460         {
0461           sumhit_s++;
0462           sumADC_s += signalFast;
0463         }
0464         if ( z_bin == 1 && is_good_hit )
0465         {
0466           sumhit_n++;
0467           sumADC_n += signalFast;
0468         }
0469 
0470       }  // channel loop end
0471     rm_packet_chans[packet_index]->Add(&channel_counter);
0472     h1_packet_chans->SetBinContent(packet_bin, rm_packet_chans[packet_index]->getMean(0));
0473     }    //  if packet good
0474     else
0475     {
0476       ChannelNumber += 128;
0477       int zero[1] = {0};
0478       rm_packet_number[packet_index]->Add(zero);
0479     }
0480     h1_packet_number->SetBinContent(packet_bin, rm_packet_number[packet_index]->getMean(0));
0481     delete p;
0482 
0483   }  // packet id loop end
0484 
0485   h_event->Fill(0);
0486   // h1_waveform_twrAvg->Scale(1. / 32. / 48.);  // average tower waveform
0487   h1_waveform_twrAvg->Scale((float) 1 / ChannelNumber);
0488 
0489   // --- need to make a trigger selection?
0490   if ( is_trigger_okay )
0491     {
0492       h_ADC_corr->Fill(sumADC_s, sumADC_n);
0493       h_hits_corr->Fill(sumhit_s, sumhit_n);
0494     }
0495 
0496   return 0;
0497 
0498 }
0499 
0500 int SepdMon::Reset()
0501 {
0502   // reset our internal counters
0503   evtcnt = 0;
0504   idummy = 0;
0505 
0506   return 0;
0507 }