Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-04-05 08:16:06

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 "BbcMon.h"
0007 #include <mbd/MbdEvent.h>
0008 
0009 #include <onlmon/OnlMon.h>
0010 #include <onlmon/OnlMonDB.h>
0011 #include <onlmon/OnlMonServer.h>
0012 #include <onlmon/RunDBodbc.h>
0013 #include <onlmon/triggerEnum.h>
0014 
0015 #include <Event/msg_profile.h>
0016 
0017 #include <Event/Event.h>
0018 #include <Event/EventTypes.h>
0019 #include <Event/packet.h>
0020 #include <Event/eventReceiverClient.h>
0021 
0022 #include <mbd/MbdGeomV1.h>
0023 #include <mbd/MbdOutV2.h>
0024 #include <mbd/MbdRawContainerV1.h>
0025 #include <mbd/MbdPmtContainerV1.h>
0026 #include <mbd/MbdPmtHit.h>
0027 
0028 #include <TF1.h>
0029 #include <TGraphErrors.h>
0030 #include <TH1.h>
0031 #include <TH2.h>
0032 #include <TH2Poly.h>
0033 #include <TString.h>
0034 #include <TSystem.h>
0035 
0036 #include <chrono>
0037 #include <cmath>
0038 #include <cstdio>  // for printf
0039 #include <ctime>
0040 #include <fstream>
0041 #include <iomanip>
0042 #include <iostream>
0043 #include <sstream>
0044 #include <thread>
0045 #include <vector>
0046 
0047 
0048 /*
0049 enum
0050 {
0051   TRGMESSAGE = 1,
0052   FILLMESSAGE = 2
0053 };
0054 */
0055 
0056 BbcMon::BbcMon(const std::string &name)
0057   : OnlMon(name)
0058 {
0059   // leave ctor fairly empty, its hard to debug if code crashes already
0060   // during a new BbcMon()
0061   return;
0062 }
0063 
0064 BbcMon::~BbcMon()
0065 {
0066   delete bevt;
0067   delete _mbdgeom;
0068   delete erc;
0069 
0070   return;
0071 }
0072 
0073 int BbcMon::Init()
0074 {
0075   // use printf for stuff which should go the screen but not into the message
0076   // system (all couts are redirected)
0077   std::cout << "BbcMon::Init()" << std::endl;
0078 
0079   bevt = new MbdEvent();
0080   _mbdgeom = new MbdGeomV1();
0081 
0082   // Set trigger bits
0083   mbdns = (0x1UL << TriggerEnum::MBD_NS2) | (0x1UL << TriggerEnum::MBD_NS1); // mbd wide triggers
0084   mbdnsvtx10 = (0x1UL << TriggerEnum::MBD_NS1_ZVRTX10) | (0x1UL << TriggerEnum::MBD_NS2_ZVRTX10);
0085   mbdnsvtx30 = (0x1UL << TriggerEnum::MBD_NS1_ZVRTX13);
0086   mbdnsvtx150 = (0x1UL << TriggerEnum::MBD_NS1_ZVRTX150);
0087   mbdtrig = mbdns | mbdnsvtx10 | mbdnsvtx30 | mbdnsvtx150;
0088   zdcns = (0x1UL << TriggerEnum::ZDC_NS);
0089   emcal = (0x1UL << TriggerEnum::PHOTON2_MBD_NS1) | (0x1UL << TriggerEnum::PHOTON3_MBD_NS1)
0090           | (0x1UL << TriggerEnum::PHOTON4_MBD_NS1) | (0x1UL << TriggerEnum::PHOTON5_MBD_NS1);
0091   hcal = (0x1UL << TriggerEnum::HCAL_SINGLES);
0092   emcalmbd = emcal | mbdtrig;
0093   hcalmbd = hcal | mbdtrig;
0094   trigmask = mbdtrig | zdcns | emcal | hcal;    // any reasonable trigger
0095 
0096   // read settings from BbcMonData.dat
0097   const char *bbccalib = getenv("BBCCALIB");
0098   if (!bbccalib)
0099   {
0100     std::cout << "BBCCALIB environment variable not set" << std::endl;
0101     exit(1);
0102   }
0103   std::string configfname = std::string(bbccalib) + "/" + "BbcMonData.dat";
0104   std::ifstream configfile(configfname);
0105   if ( configfile.is_open() )
0106   {
0107     std::cout << "MBD: Reading " << configfname << std::endl;
0108     std::string label;
0109     uint64_t trigbit{0};
0110     while ( configfile >> label >> std::hex >> trigbit >> std::dec )
0111     {
0112       if ( label == "#" )
0113       {
0114           continue;
0115       }
0116       else if ( label == "USEGL1" )
0117       {
0118           useGL1 = static_cast<int>(trigbit);
0119       }
0120       else if ( label == "TRIGMASK" )
0121       {
0122           trigmask = trigbit;
0123           std::cout << "Overriding with trigmask " << label << " 0x" << std::hex << trigbit << std::dec << std::endl;
0124       }
0125       else if ( label[0] != '#' && label[0] != '/' )
0126       {
0127         std::cout << "Using trigger " << label << " 0x" << std::hex << trigbit << std::dec << std::endl;
0128       }
0129     }
0130 
0131     configfile.close();
0132   }
0133   else
0134   {
0135     std::cout << "MBD: ERROR, " << configfname << " not found" << std::endl;
0136     exit(1);
0137   }
0138   orig_trigmask = trigmask;
0139 
0140   // get gl1 event receiver
0141   if ( useGL1==1 )
0142   {
0143     erc = new eventReceiverClient(eventReceiverClientHost);
0144     rdb = new RunDBodbc;
0145   }
0146   else if ( useGL1==2 )
0147   {
0148     std::cout << "Connecting to eventserver on localhost" << std::endl;
0149     erc = new eventReceiverClient("localhost");
0150     rdb = new RunDBodbc;
0151   }
0152 
0153   // Book Histograms
0154 
0155   // Trigger Information ----------------------------------------------------
0156   bbc_trigs = new TH1F("bbc_trigs", "Trigger Counts", 64, -0.5, 63.5);
0157   if ( useGL1 )
0158   {
0159     // initialize auto-update trigger histograms
0160     for ( int i = 0; i < TriggerEnum::NUM_MBD_TRIGGERS; i++ ){
0161       std::string name = Form("bbc_zvertex_autoupdate_%i", i);
0162       bbc_zvertex_autoupdate[i] = new TH1F(name.c_str(), 
0163         Form("MBD ZVertex Trigger %s", TriggerEnum::MBTriggerNames[i]),
0164         BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0165       bbc_zvertex_autoupdate[i]->Sumw2();
0166       bbc_zvertex_autoupdate[i]->GetXaxis()->SetTitle("ZVertex [cm]");
0167       bbc_zvertex_autoupdate[i]->GetYaxis()->SetTitle("Number of Event");
0168       bbc_zvertex_autoupdate[i]->GetXaxis()->SetTitleSize(0.05);
0169       bbc_zvertex_autoupdate[i]->GetYaxis()->SetTitleSize(0.05);
0170       bbc_zvertex_autoupdate[i]->GetXaxis()->SetTitleOffset(0.70);
0171       bbc_zvertex_autoupdate[i]->GetYaxis()->SetTitleOffset(1.75);
0172       bbc_zvertex_autoupdate[i]->GetXaxis()->SetLabelSize(0.07);
0173       bbc_zvertex_autoupdate[i]->GetXaxis()->SetTickSize(0.1);
0174     }
0175   }
0176 
0177   // Nhit Distributions
0178   bbc_south_nhit = new TH1F("bbc_south_nhit","MBD.S Nhits",64,-0.5,63.5);
0179   bbc_north_nhit = new TH1F("bbc_north_nhit","MBD.N Nhits",64,-0.5,63.5);
0180   for (int iarm=0; iarm<2; iarm++)
0181   {
0182     TString name = "bbc_nhit_emcal"; name += iarm;
0183     bbc_nhit_emcal[iarm] = new TH1F(name,"MBD Nhits, EMCAL trig",64,-0.5,63.5);
0184     name = "bbc_nhit_hcal"; name += iarm;
0185     bbc_nhit_hcal[iarm] = new TH1F(name,"MBD Nhits, JET trig",64,-0.5,63.5);
0186     name = "bbc_nhit_emcalmbd"; name += iarm;
0187     bbc_nhit_emcalmbd[iarm] = new TH1F(name,"MBD Nhits, EMCAL&&MBD trig",64,-0.5,63.5);
0188     name = "bbc_nhit_hcalmbd"; name += iarm;
0189     bbc_nhit_hcalmbd[iarm] = new TH1F(name,"MBD Nhits, JET&&MBD trig",64,-0.5,63.5);
0190   }
0191   for(int i = 0; i < nPacketStatus; i++)
0192   {
0193     h1_packet_status[i] = new TH1F(Form("h1_packet_status_%d",i),"",2,1000.5, 1002.5);
0194   }
0195 
0196 
0197 
0198   // TDC Distribution ----------------------------------------------------
0199 
0200   bbc_tdc = new TH2F("bbc_tdc", "BBC Raw TDC Distribution",
0201                      nPMT_BBC, -.5, nPMT_BBC - .5,
0202                      BbcMonDefs::nBIN_TDC, 0, BbcMonDefs::tdc_max_overflow * BbcMonDefs::TDC_CONVERSION_FACTOR);
0203   //std::cout << "BBCTDC " << (uint64_t)bbc_tdc << std::endl;
0204 
0205   // TDC Overflow Deviation ----------------------------------------------
0206   bbc_tdc_overflow = new TH2F("bbc_tdc_overflow", "MBD TDC Overflow Deviation",
0207                               nPMT_BBC, -.5, nPMT_BBC - .5,
0208                               int(BbcMonDefs::VIEW_OVERFLOW_MAX - BbcMonDefs::VIEW_OVERFLOW_MIN + 1),
0209                               BbcMonDefs::VIEW_OVERFLOW_MIN - .5, BbcMonDefs::VIEW_OVERFLOW_MAX + .5);
0210 
0211   std::ostringstream name, title;
0212 
0213   // TDC Overflow Distribution for each PMT ------------------------------
0214   for (int ipmt = 0; ipmt < nPMT_BBC; ipmt++)
0215   {
0216     name << "bbc_tdc_overflow_" << std::setw(3) << std::setfill('0') << ipmt;
0217     title << "MBD TDC Overflow Deviation of #" << std::setw(3) << std::setfill('0') << ipmt;
0218     bbc_tdc_overflow_each[ipmt] = new TH1F(name.str().c_str(), title.str().c_str(),
0219                                            int(BbcMonDefs::VIEW_OVERFLOW_MAX - BbcMonDefs::VIEW_OVERFLOW_MIN + 1),
0220                                            BbcMonDefs::VIEW_OVERFLOW_MIN, BbcMonDefs::VIEW_OVERFLOW_MAX);
0221     name.str("");
0222     name.clear();
0223     title.str("");
0224     title.clear();
0225   }
0226 
0227   // ADC Distribution --------------------------------------------------------
0228 
0229   bbc_adc = new TH2F("bbc_adc", "MBD ADC(Charge) Distribution", nPMT_BBC, -.5, nPMT_BBC - .5, BbcMonDefs::nBIN_ADC, 0, BbcMonDefs::MAX_ADC_MIP);
0230 
0231   bbc_tdc_armhittime = new TH2F("bbc_tdc_armhittime", "Arm-Hit-Time Correlation of North and South MBD",
0232                                 64, BbcMonDefs::min_armhittime, BbcMonDefs::max_armhittime,
0233                                 64, BbcMonDefs::min_armhittime, BbcMonDefs::max_armhittime);
0234   bbc_tdc_armhittime->GetXaxis()->SetTitle("South [ns]");
0235   bbc_tdc_armhittime->GetYaxis()->SetTitle("North [ns]");
0236 
0237   // Vertex Distributions --------------------------------------------------------
0238 
0239   bbc_zvertex = new TH1F("bbc_zvertex", "MBD ZVertex, main trigger", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0240   bbc_zvertex->Sumw2();
0241   bbc_zvertex->GetXaxis()->SetTitle("ZVertex [cm]");
0242   bbc_zvertex->GetYaxis()->SetTitle("Number of Event");
0243   bbc_zvertex->GetXaxis()->SetTitleSize(0.05);
0244   bbc_zvertex->GetYaxis()->SetTitleSize(0.05);
0245   bbc_zvertex->GetXaxis()->SetTitleOffset(0.70);
0246   bbc_zvertex->GetYaxis()->SetTitleOffset(1.75);
0247   bbc_zvertex->GetXaxis()->SetLabelSize(0.07);
0248   bbc_zvertex->GetXaxis()->SetTickSize(0.1);
0249 
0250   bbc_zvertex_alltrigger = new TH1F("bbc_zvertex_alltrigger", "MBD ZVertex, all triggers",
0251                                     BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0252   bbc_zvertex_alltrigger->Sumw2();
0253   bbc_zvertex_alltrigger->GetXaxis()->SetTitle("ZVertex [cm]");
0254   bbc_zvertex_alltrigger->GetYaxis()->SetTitle("Number of Event");
0255   bbc_zvertex_alltrigger->GetXaxis()->SetTitleSize(0.05);
0256   bbc_zvertex_alltrigger->GetYaxis()->SetTitleSize(0.05);
0257   bbc_zvertex_alltrigger->GetXaxis()->SetTitleOffset(0.70);
0258   bbc_zvertex_alltrigger->GetYaxis()->SetTitleOffset(1.75);
0259   bbc_zvertex_alltrigger->GetXaxis()->SetLabelSize(0.07);
0260   bbc_zvertex_alltrigger->GetXaxis()->SetTickSize(0.1);
0261 
0262   bbc_zvertex_short = new TH1F("bbc_zvertex_short", "MBD ZVertex (NS, wide), short time scale",
0263                                BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0264   bbc_zvertex_short->Sumw2();
0265   bbc_zvertex_short->GetXaxis()->SetTitle("ZVertex [cm]");
0266   bbc_zvertex_short->GetYaxis()->SetTitle("Number of Event");
0267   bbc_zvertex_short->GetXaxis()->SetTitleSize(0.05);
0268   bbc_zvertex_short->GetYaxis()->SetTitleSize(0.05);
0269   bbc_zvertex_short->GetXaxis()->SetTitleOffset(0.70);
0270   bbc_zvertex_short->GetYaxis()->SetTitleOffset(1.75);
0271 
0272   bbc_zvertex_prime_short = new TH1F("bbc_zvertex_prime_short", "MBD ZVertex (NS, prime), short time scale",
0273                                BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0274   bbc_zvertex_prime_short->Sumw2();
0275   bbc_zvertex_prime_short->GetXaxis()->SetTitle("ZVertex [cm]");
0276   bbc_zvertex_prime_short->GetYaxis()->SetTitle("Number of Event");
0277   bbc_zvertex_prime_short->GetXaxis()->SetTitleSize(0.05);
0278   bbc_zvertex_prime_short->GetYaxis()->SetTitleSize(0.05);
0279   bbc_zvertex_prime_short->GetXaxis()->SetTitleOffset(0.70);
0280   bbc_zvertex_prime_short->GetYaxis()->SetTitleOffset(1.75);
0281 
0282   bbc_zvertex_ns = new TH1F("bbc_zvertex_ns", "MBD zvertex_ns, main trigger", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0283   bbc_zvertex_ns->GetXaxis()->SetTitle("zvertex [cm]");
0284   bbc_zvertex_ns->GetYaxis()->SetTitle("Number of Event");
0285   bbc_zvertex_ns->GetXaxis()->SetTitleSize(0.05);
0286   bbc_zvertex_ns->GetYaxis()->SetTitleSize(0.05);
0287   bbc_zvertex_ns->GetXaxis()->SetTitleOffset(0.70);
0288   bbc_zvertex_ns->GetYaxis()->SetTitleOffset(1.75);
0289   bbc_zvertex_ns->GetXaxis()->SetLabelSize(0.07);
0290   bbc_zvertex_ns->GetXaxis()->SetTickSize(0.1);
0291 
0292   bbc_zvertex_10 = new TH1F("bbc_zvertex_10", "MBD ZVertex (|z|<10)",
0293                              BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0294   bbc_zvertex_10->GetXaxis()->SetTitle("ZVertex [cm]");
0295   bbc_zvertex_10->GetYaxis()->SetTitle("Number of Event");
0296   bbc_zvertex_10->GetXaxis()->SetTitleSize(0.05);
0297   bbc_zvertex_10->GetYaxis()->SetTitleSize(0.05);
0298   bbc_zvertex_10->GetXaxis()->SetTitleOffset(0.70);
0299   bbc_zvertex_10->GetYaxis()->SetTitleOffset(1.75);
0300   bbc_zvertex_10->GetXaxis()->SetLabelSize(0.05);
0301   bbc_zvertex_10->GetXaxis()->SetTickSize(0.1);
0302 
0303   bbc_zvertex_30 = new TH1F("bbc_zvertex_30", "MBD ZVertex (|z|<30)",
0304                             BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0305   bbc_zvertex_30->GetXaxis()->SetTitle("ZVertex [cm]");
0306   bbc_zvertex_30->GetYaxis()->SetTitle("Number of Event");
0307   bbc_zvertex_30->GetXaxis()->SetTitleSize(0.05);
0308   bbc_zvertex_30->GetYaxis()->SetTitleSize(0.05);
0309   bbc_zvertex_30->GetXaxis()->SetTitleOffset(0.70);
0310   bbc_zvertex_30->GetYaxis()->SetTitleOffset(1.75);
0311   bbc_zvertex_30->GetXaxis()->SetLabelSize(0.05);
0312   bbc_zvertex_30->GetXaxis()->SetTickSize(0.1);
0313 
0314   bbc_zvertex_60 = new TH1F("bbc_zvertex_60", "MBD ZVertex (|z|<60)",
0315                             BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0316   bbc_zvertex_60->GetXaxis()->SetTitle("ZVertex [cm]");
0317   bbc_zvertex_60->GetYaxis()->SetTitle("Number of Event");
0318   bbc_zvertex_60->GetXaxis()->SetTitleSize(0.05);
0319   bbc_zvertex_60->GetYaxis()->SetTitleSize(0.05);
0320   bbc_zvertex_60->GetXaxis()->SetTitleOffset(0.70);
0321   bbc_zvertex_60->GetYaxis()->SetTitleOffset(1.75);
0322   bbc_zvertex_60->GetXaxis()->SetLabelSize(0.05);
0323   bbc_zvertex_60->GetXaxis()->SetTickSize(0.1);
0324 
0325   bbc_zvertex_ns_chk = new TH1F("bbc_zvertex_ns_chk", "MBD ZVertex (|z|<10)",
0326                              BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0327   bbc_zvertex_ns_chk->GetXaxis()->SetTitle("ZVertex [cm]");
0328   bbc_zvertex_ns_chk->GetYaxis()->SetTitle("Number of Event");
0329   bbc_zvertex_ns_chk->GetXaxis()->SetTitleSize(0.05);
0330   bbc_zvertex_ns_chk->GetYaxis()->SetTitleSize(0.05);
0331   bbc_zvertex_ns_chk->GetXaxis()->SetTitleOffset(0.70);
0332   bbc_zvertex_ns_chk->GetYaxis()->SetTitleOffset(1.75);
0333   bbc_zvertex_ns_chk->GetXaxis()->SetLabelSize(0.05);
0334   bbc_zvertex_ns_chk->GetXaxis()->SetTickSize(0.1);
0335 
0336   bbc_zvertex_10_chk = new TH1F("bbc_zvertex_10_chk", "MBD ZVertex (|z|<10)",
0337                              BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0338   bbc_zvertex_10_chk->GetXaxis()->SetTitle("ZVertex [cm]");
0339   bbc_zvertex_10_chk->GetYaxis()->SetTitle("Number of Event");
0340   bbc_zvertex_10_chk->GetXaxis()->SetTitleSize(0.05);
0341   bbc_zvertex_10_chk->GetYaxis()->SetTitleSize(0.05);
0342   bbc_zvertex_10_chk->GetXaxis()->SetTitleOffset(0.70);
0343   bbc_zvertex_10_chk->GetYaxis()->SetTitleOffset(1.75);
0344   bbc_zvertex_10_chk->GetXaxis()->SetLabelSize(0.05);
0345   bbc_zvertex_10_chk->GetXaxis()->SetTickSize(0.1);
0346 
0347   bbc_zvertex_30_chk = new TH1F("bbc_zvertex_30_chk", "MBD ZVertex (|z|<30)",
0348                             BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0349   bbc_zvertex_30_chk->GetXaxis()->SetTitle("ZVertex [cm]");
0350   bbc_zvertex_30_chk->GetYaxis()->SetTitle("Number of Event");
0351   bbc_zvertex_30_chk->GetXaxis()->SetTitleSize(0.05);
0352   bbc_zvertex_30_chk->GetYaxis()->SetTitleSize(0.05);
0353   bbc_zvertex_30_chk->GetXaxis()->SetTitleOffset(0.70);
0354   bbc_zvertex_30_chk->GetYaxis()->SetTitleOffset(1.75);
0355   bbc_zvertex_30_chk->GetXaxis()->SetLabelSize(0.05);
0356   bbc_zvertex_30_chk->GetXaxis()->SetTickSize(0.1);
0357 
0358   bbc_zvertex_60_chk = new TH1F("bbc_zvertex_60_chk", "MBD ZVertex (|z|<60)",
0359                             BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0360   bbc_zvertex_60_chk->GetXaxis()->SetTitle("ZVertex [cm]");
0361   bbc_zvertex_60_chk->GetYaxis()->SetTitle("Number of Event");
0362   bbc_zvertex_60_chk->GetXaxis()->SetTitleSize(0.05);
0363   bbc_zvertex_60_chk->GetYaxis()->SetTitleSize(0.05);
0364   bbc_zvertex_60_chk->GetXaxis()->SetTitleOffset(0.70);
0365   bbc_zvertex_60_chk->GetYaxis()->SetTitleOffset(1.75);
0366   bbc_zvertex_60_chk->GetXaxis()->SetLabelSize(0.05);
0367   bbc_zvertex_60_chk->GetXaxis()->SetTickSize(0.1);
0368 
0369   bbc_zvertex_zdcns = new TH1F("bbc_zvertex_zdcns", "MBD zvertex, ZDCNS trig", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0370   bbc_zvertex_zdcns->GetXaxis()->SetTitle("zvertex [cm]");
0371   bbc_zvertex_zdcns->GetYaxis()->SetTitle("Number of Event");
0372   bbc_zvertex_zdcns->GetXaxis()->SetTitleSize(0.05);
0373   bbc_zvertex_zdcns->GetYaxis()->SetTitleSize(0.05);
0374   bbc_zvertex_zdcns->GetXaxis()->SetTitleOffset(0.70);
0375   bbc_zvertex_zdcns->GetYaxis()->SetTitleOffset(1.75);
0376   bbc_zvertex_zdcns->GetXaxis()->SetLabelSize(0.07);
0377   bbc_zvertex_zdcns->GetXaxis()->SetTickSize(0.1);
0378 
0379   bbc_zvertex_emcal = new TH1F("bbc_zvertex_emcal", "MBD zvertex, PHOTON trig", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0380   bbc_zvertex_emcal->GetXaxis()->SetTitle("zvertex [cm]");
0381   bbc_zvertex_emcal->GetYaxis()->SetTitle("Number of Event");
0382   bbc_zvertex_emcal->GetXaxis()->SetTitleSize(0.05);
0383   bbc_zvertex_emcal->GetYaxis()->SetTitleSize(0.05);
0384   bbc_zvertex_emcal->GetXaxis()->SetTitleOffset(0.70);
0385   bbc_zvertex_emcal->GetYaxis()->SetTitleOffset(1.75);
0386   bbc_zvertex_emcal->GetXaxis()->SetLabelSize(0.07);
0387   bbc_zvertex_emcal->GetXaxis()->SetTickSize(0.1);
0388 
0389   bbc_zvertex_hcal = new TH1F("bbc_zvertex_hcal", "MBD zvertex, JET trig", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0390   bbc_zvertex_hcal->GetXaxis()->SetTitle("zvertex [cm]");
0391   bbc_zvertex_hcal->GetYaxis()->SetTitle("Number of Event");
0392   bbc_zvertex_hcal->GetXaxis()->SetTitleSize(0.05);
0393   bbc_zvertex_hcal->GetYaxis()->SetTitleSize(0.05);
0394   bbc_zvertex_hcal->GetXaxis()->SetTitleOffset(0.70);
0395   bbc_zvertex_hcal->GetYaxis()->SetTitleOffset(1.75);
0396   bbc_zvertex_hcal->GetXaxis()->SetLabelSize(0.07);
0397   bbc_zvertex_hcal->GetXaxis()->SetTickSize(0.1);
0398 
0399   bbc_zvertex_emcalmbd = new TH1F("bbc_zvertex_emcalmbd", "MBD zvertex, PHOTON&&MBD trig", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0400   bbc_zvertex_emcalmbd->GetXaxis()->SetTitle("zvertex [cm]");
0401   bbc_zvertex_emcalmbd->GetYaxis()->SetTitle("Number of Event");
0402   bbc_zvertex_emcalmbd->GetXaxis()->SetTitleSize(0.05);
0403   bbc_zvertex_emcalmbd->GetYaxis()->SetTitleSize(0.05);
0404   bbc_zvertex_emcalmbd->GetXaxis()->SetTitleOffset(0.70);
0405   bbc_zvertex_emcalmbd->GetYaxis()->SetTitleOffset(1.75);
0406   bbc_zvertex_emcalmbd->GetXaxis()->SetLabelSize(0.07);
0407   bbc_zvertex_emcalmbd->GetXaxis()->SetTickSize(0.1);
0408 
0409   bbc_zvertex_hcalmbd = new TH1F("bbc_zvertex_hcalmbd", "MBD zvertex, JET&&MBD trig", BbcMonDefs::zvtnbin, BbcMonDefs::min_zvertex, BbcMonDefs::max_zvertex);
0410   bbc_zvertex_hcalmbd->GetXaxis()->SetTitle("zvertex [cm]");
0411   bbc_zvertex_hcalmbd->GetYaxis()->SetTitle("Number of Event");
0412   bbc_zvertex_hcalmbd->GetXaxis()->SetTitleSize(0.05);
0413   bbc_zvertex_hcalmbd->GetYaxis()->SetTitleSize(0.05);
0414   bbc_zvertex_hcalmbd->GetXaxis()->SetTitleOffset(0.70);
0415   bbc_zvertex_hcalmbd->GetYaxis()->SetTitleOffset(1.75);
0416   bbc_zvertex_hcalmbd->GetXaxis()->SetLabelSize(0.07);
0417   bbc_zvertex_hcalmbd->GetXaxis()->SetTickSize(0.1);
0418 
0419   f_zvtx = new TF1("f_zvtx", "gaus", -30., 30.);
0420   bbc_nevent_counter = new TH1F("bbc_nevent_counter",
0421                                 "The nEvent Counter bin1:Total Event bin2:Collision Event bin3:Laser Event bin7:TrigCut",
0422                                 16, 0, 16);
0423 
0424   // bbc_tzero_zvtx = new TH2F("bbc_tzero_zvtx",
0425   //     "TimeZero vs ZVertex", 100, -200, 200, 110, -11, 11 );
0426   bbc_tzero_zvtx = new TH2F("bbc_tzero_zvtx", "TimeZero vs ZVertex", 100, -200, 200, 110, -16, 16);
0427   bbc_tzero_zvtx->SetXTitle("ZVertex [cm]");
0428   bbc_tzero_zvtx->SetYTitle("TimeZero[ns]");
0429 
0430   bbc_avr_hittime = new TH1F("bbc_avr_hittime", "MBD Average Hittime", 128, 0, 24);
0431   bbc_avr_hittime->Sumw2();
0432   bbc_avr_hittime->GetXaxis()->SetTitle("Avr HitTime [ns]");
0433   bbc_avr_hittime->GetYaxis()->SetTitle("Number of Event");
0434   bbc_avr_hittime->GetXaxis()->SetTitleSize(0.05);
0435   bbc_avr_hittime->GetYaxis()->SetTitleSize(0.05);
0436   bbc_avr_hittime->GetXaxis()->SetTitleOffset(0.70);
0437   bbc_avr_hittime->GetYaxis()->SetTitleOffset(1.75);
0438 
0439   // should make plots of the raw tdc for time channels
0440   // bbc_south_hittime = new TH1F("bbc_south_hittime", "BBC South Hittime", 164, -100, 16300);
0441   // bbc_north_hittime = new TH1F("bbc_north_hittime", "BBC North Hittime", 164, -100, 16300);
0442   bbc_south_hittime = new TH1F("bbc_south_hittime", "MBD South Hittime", 150, -15, 15);
0443   bbc_north_hittime = new TH1F("bbc_north_hittime", "MBD North Hittime", 150, -15, 15);
0444 
0445   bbc_south_hittime->GetXaxis()->SetTitle("South HitTime [ns]");
0446   bbc_south_hittime->GetYaxis()->SetTitle("Number of Event");
0447   bbc_south_hittime->GetXaxis()->SetTitleSize(0.05);
0448   bbc_south_hittime->GetYaxis()->SetTitleSize(0.05);
0449   bbc_south_hittime->GetXaxis()->SetTitleOffset(0.70);
0450   bbc_south_hittime->GetYaxis()->SetTitleOffset(1.75);
0451 
0452   bbc_north_hittime->GetXaxis()->SetTitle("North HitTime [ns]");
0453   bbc_north_hittime->GetYaxis()->SetTitle("Number of Event");
0454   bbc_north_hittime->GetXaxis()->SetTitleSize(0.05);
0455   bbc_north_hittime->GetYaxis()->SetTitleSize(0.05);
0456   bbc_north_hittime->GetXaxis()->SetTitleOffset(0.70);
0457   bbc_north_hittime->GetYaxis()->SetTitleOffset(1.75);
0458 
0459   // bbc_south_chargesum = new TH1F("bbc_south_chargesum", "BBC South ChargeSum [MIP]", 128, 0, BbcMonDefs::MAX_CHARGE_SUM);
0460   // bbc_north_chargesum = new TH1F("bbc_north_chargesum", "BBC North ChargeSum [MIP]", 128, 0, BbcMonDefs::MAX_CHARGE_SUM);
0461   bbc_south_chargesum = new TH1F("bbc_south_chargesum", "BBC South ChargeSum [AU]", 128, 0, BbcMonDefs::MAX_CHARGE_SUM);
0462   bbc_north_chargesum = new TH1F("bbc_north_chargesum", "BBC North ChargeSum [AU]", 128, 0, BbcMonDefs::MAX_CHARGE_SUM);
0463 
0464   bbc_north_chargesum->SetTitle("MBD ChargeSum [MIP]");
0465   bbc_north_chargesum->GetXaxis()->SetTitle("ChargeSum [MIP]");
0466   // bbc_north_chargesum->GetXaxis()->SetTitle("North ChargeSum [MIP]");
0467   bbc_north_chargesum->GetYaxis()->SetTitle("Number of Event");
0468   bbc_north_chargesum->GetXaxis()->SetTitleSize(0.05);
0469   bbc_north_chargesum->GetYaxis()->SetTitleSize(0.05);
0470   bbc_north_chargesum->GetXaxis()->SetTitleOffset(0.70);
0471   bbc_north_chargesum->GetYaxis()->SetTitleOffset(1.75);
0472 
0473   // bbc_south_chargesum->GetXaxis()->SetTitle("South ChargeSum [MIP]");
0474   bbc_south_chargesum->GetYaxis()->SetTitle("Number of Event");
0475   bbc_south_chargesum->GetXaxis()->SetTitleSize(0.05);
0476   bbc_south_chargesum->GetYaxis()->SetTitleSize(0.05);
0477   bbc_south_chargesum->GetXaxis()->SetTitleOffset(0.70);
0478   bbc_south_chargesum->GetYaxis()->SetTitleOffset(1.75);
0479 
0480   // scale down factor for each trigger
0481   bbc_prescale_hist = new TH1F("bbc_prescale_hist", "prescales", 64, 0, 64);
0482   bbc_prescale_hist->SetXTitle("trigger");
0483 
0484   // waveforms
0485   bbc_time_wave = new TH2F("bbc_time_wave", "MBD time waveforms by ch", BbcMonDefs::BBC_MAXSAMPLES, -0.5, BbcMonDefs::BBC_MAXSAMPLES - 0.5, 128, 0, 128);
0486   bbc_charge_wave = new TH2F("bbc_charge_wave", "MBD charge waveforms by ch", BbcMonDefs::BBC_MAXSAMPLES, -0.5, BbcMonDefs::BBC_MAXSAMPLES - 0.5, 128, 0, 128);
0487 
0488   bbc_time_wave->GetXaxis()->SetTitle("Sample");
0489   bbc_time_wave->GetYaxis()->SetTitle("Ch");
0490   bbc_time_wave->GetXaxis()->SetTitleSize(0.05);
0491   bbc_time_wave->GetYaxis()->SetTitleSize(0.05);
0492   bbc_time_wave->GetXaxis()->SetTitleOffset(0.70);
0493   bbc_time_wave->GetYaxis()->SetTitleOffset(0.75);
0494   bbc_charge_wave->GetXaxis()->SetTitle("Sample");
0495   bbc_charge_wave->GetYaxis()->SetTitle("Ch");
0496   bbc_charge_wave->GetXaxis()->SetTitleSize(0.05);
0497   bbc_charge_wave->GetYaxis()->SetTitleSize(0.05);
0498   bbc_charge_wave->GetXaxis()->SetTitleOffset(0.70);
0499   bbc_charge_wave->GetYaxis()->SetTitleOffset(0.75);
0500 
0501   bbc_runvtx = new TH1F("bbc_runvtx","running vtx",2000,0,2000);
0502   bbc_runvtxerr = new TH1F("bbc_runvtxerr","running vtx err",2000,0,2000);
0503   bbc_runvtxtime = new TH1F("bbc_runvtxtime","running vtx time",2000,0,2000);
0504 
0505   // hitmaps
0506   bbc_south_hitmap = new TH2Poly();
0507   bbc_south_hitmap->SetName("bbc_south_hitmap");
0508   bbc_south_hitmap->SetTitle("MBD South Hitmap");
0509   bbc_south_hitmap->GetXaxis()->SetTitle("x (cm)");
0510   bbc_south_hitmap->GetYaxis()->SetTitle("y (cm)");
0511   bbc_south_hitmap->GetXaxis()->SetTitleSize(0.05);
0512   bbc_south_hitmap->GetYaxis()->SetTitleSize(0.05);
0513   bbc_south_hitmap->GetXaxis()->SetTitleOffset(0.70);
0514   bbc_south_hitmap->GetYaxis()->SetTitleOffset(0.70);
0515   bbc_south_hitmap->SetMinimum(0.001);
0516 
0517   bbc_north_hitmap = new TH2Poly();
0518   bbc_north_hitmap->SetName("bbc_north_hitmap");
0519   bbc_north_hitmap->SetTitle("MBD North Hitmap");
0520   bbc_north_hitmap->GetXaxis()->SetTitle("x (cm)");
0521   bbc_north_hitmap->GetYaxis()->SetTitle("y (cm)");
0522   bbc_north_hitmap->GetXaxis()->SetTitleSize(0.05);
0523   bbc_north_hitmap->GetYaxis()->SetTitleSize(0.05);
0524   bbc_north_hitmap->GetXaxis()->SetTitleOffset(0.70);
0525   bbc_north_hitmap->GetYaxis()->SetTitleOffset(0.70);
0526   bbc_north_hitmap->SetMinimum(0.001);
0527 
0528   // Get the detector geometry
0529   Double_t x[6];  // x,y location of the 6 points of the BBC hexagonal PMT's, in cm
0530   Double_t y[6];
0531   for (int ipmt = 0; ipmt < 128; ipmt++)
0532   {
0533     float xcent = _mbdgeom->get_x(ipmt);
0534     float ycent = _mbdgeom->get_y(ipmt);
0535     int arm = _mbdgeom->get_arm(ipmt);
0536     std::cout << ipmt << "\t" << xcent << "\t" << ycent << std::endl;
0537 
0538     // create hexagon
0539     x[0] = xcent - 0.8;  // in cm
0540     y[0] = ycent + 1.4;
0541     x[1] = xcent + 0.8;
0542     y[1] = ycent + 1.4;
0543     x[2] = xcent + 1.6;
0544     y[2] = ycent;
0545     x[3] = xcent + 0.8;
0546     y[3] = ycent - 1.4;
0547     x[4] = xcent - 0.8;
0548     y[4] = ycent - 1.4;
0549     x[5] = xcent - 1.6;
0550     y[5] = ycent;
0551 
0552     if (arm == 0)
0553     {
0554       bbc_south_hitmap->AddBin(6, x, y);
0555     }
0556     else if (arm == 1)
0557     {
0558       bbc_north_hitmap->AddBin(6, x, y);
0559     }
0560   }
0561 
0562   // register histograms with server otherwise client won't get them
0563   OnlMonServer *se = OnlMonServer::instance();
0564 
0565   se->registerHisto(this, bbc_trigs);
0566   for ( int i = 0; i < TriggerEnum::NUM_MBD_TRIGGERS; i++ ){
0567       se->registerHisto(this, bbc_zvertex_autoupdate[i]);
0568   }
0569   se->registerHisto(this, bbc_south_nhit);
0570   se->registerHisto(this, bbc_north_nhit);
0571   for (int iarm=0; iarm<2; iarm++)
0572   {
0573       se->registerHisto(this, bbc_nhit_emcal[iarm]);
0574       se->registerHisto(this, bbc_nhit_hcal[iarm]);
0575       se->registerHisto(this, bbc_nhit_emcalmbd[iarm]);
0576       se->registerHisto(this, bbc_nhit_hcalmbd[iarm]);
0577   }
0578   se->registerHisto(this, bbc_adc);
0579   se->registerHisto(this, bbc_tdc);
0580   se->registerHisto(this, bbc_tdc_overflow);
0581   for (auto &ipmt : bbc_tdc_overflow_each)
0582   {
0583       se->registerHisto(this, ipmt);
0584   }
0585 
0586   se->registerHisto(this, bbc_tdc_armhittime);
0587   se->registerHisto(this, bbc_zvertex);
0588   se->registerHisto(this, bbc_zvertex_alltrigger);
0589   se->registerHisto(this, bbc_zvertex_ns);
0590   se->registerHisto(this, bbc_zvertex_10);
0591   se->registerHisto(this, bbc_zvertex_30);
0592   se->registerHisto(this, bbc_zvertex_60);
0593   se->registerHisto(this, bbc_zvertex_ns_chk);
0594   se->registerHisto(this, bbc_zvertex_10_chk);
0595   se->registerHisto(this, bbc_zvertex_30_chk);
0596   se->registerHisto(this, bbc_zvertex_60_chk);
0597   se->registerHisto(this, bbc_zvertex_zdcns);
0598   se->registerHisto(this, bbc_zvertex_emcal);
0599   se->registerHisto(this, bbc_zvertex_hcal);
0600   se->registerHisto(this, bbc_zvertex_emcalmbd);
0601   se->registerHisto(this, bbc_zvertex_hcalmbd);
0602   se->registerHisto(this, bbc_nevent_counter);
0603   se->registerHisto(this, bbc_tzero_zvtx);
0604   se->registerHisto(this, bbc_prescale_hist);
0605   se->registerHisto(this, bbc_avr_hittime);
0606   se->registerHisto(this, bbc_north_hittime);
0607   se->registerHisto(this, bbc_south_hittime);
0608   se->registerHisto(this, bbc_north_chargesum);
0609   se->registerHisto(this, bbc_south_chargesum);
0610   se->registerHisto(this, bbc_north_hitmap);
0611   se->registerHisto(this, bbc_south_hitmap);
0612   /*
0613   se->registerHisto(this, bbc_tmax[0]);
0614   se->registerHisto(this, bbc_tmax[1]);
0615   */
0616   se->registerHisto(this, bbc_time_wave);
0617   se->registerHisto(this, bbc_charge_wave);
0618   se->registerHisto(this, bbc_runvtx);
0619   se->registerHisto(this, bbc_runvtxerr);
0620   se->registerHisto(this, bbc_runvtxtime);
0621   for (int i = 0; i < nPacketStatus; i++)
0622   {
0623     se->registerHisto(this, h1_packet_status[i]);
0624   }
0625 
0626   /*
0627   dbvars = new OnlMonDB(ThisName);  // use monitor name for db table name
0628   DBVarInit();
0629   */
0630   Reset();
0631 
0632   m_mbdout = new MbdOutV2();
0633   m_mbdraws = new MbdRawContainerV1();
0634   m_mbdpmts = new MbdPmtContainerV1();
0635 
0636   // prep the vtx to MCR info
0637   char hname[1024];
0638   gethostname(hname,sizeof(hname)-1);
0639   sendflagfname = "/home/phnxrc/operations/mbd/mbd2mcr.";
0640   sendflagfname += hname;
0641   std::cout << "sendflagfname " << sendflagfname << "\t" << hname << std::endl;
0642   fillnumber = 0;
0643   /*
0644   // as of 7/16/25, we just use whatever the last setting was (always send unless toggled)
0645   if ( useGL1==1 )
0646   {
0647     UpdateSendFlag( 1 );
0648   }
0649   */
0650 
0651   // prep the reset vtx info
0652   zresetflagfname = "/home/phnxrc/operations/mbd/mbdzreset.";
0653   zresetflagfname += hname;
0654   UpdateZResetFlag( 0 );
0655 
0656   gl1badflagfname = "/home/phnxrc/operations/mbd/mbdgl1bypass.";
0657   gl1badflagfname += hname;
0658   std::cout << "gl1badflagfname " << gl1badflagfname << "\t" << hname << std::endl;
0659 
0660   return 0;
0661 }
0662 
0663 int BbcMon::BeginRun(const int runno)
0664 {
0665   // if you need to read calibrations on a run by run basis
0666   // this is the place to do it
0667   std::cout << "BbcMon::BeginRun(), run " << runno << std::endl;
0668   Reset();
0669   if ( useGL1 )
0670   {
0671     OnlMonServer *se = OnlMonServer::instance();
0672     se->UseGl1();
0673   }
0674   bevt->InitRun();
0675 
0676   // new behavior as of 7/16/25: keep vtx setting between fills
0677   int prev_fill = fillnumber;
0678   int current_fill = GetFillNumber();
0679   if ( prev_fill==0 || current_fill!=prev_fill )
0680   {
0681     std::cout << "MBD: Found new fill " << current_fill << std::endl;
0682     fillnumber = current_fill;
0683     /*
0684     if ( useGL1==1 )
0685     {
0686       UpdateSendFlag( 1 );
0687     }
0688     */
0689   }
0690 
0691   // Always start with no z-reset
0692   UpdateZResetFlag( 0 );
0693 
0694   // Get Start Time
0695   tstart = std::time(nullptr);
0696   
0697   // get gl1badflag on new run
0698   GetGL1BadFlag();
0699 
0700   uint64_t trigs_enabled = 0;
0701   if ( rdb != nullptr )
0702   {
0703     std::vector<int> scaledowns;
0704     rdb->GetScaledowns( scaledowns, runno );
0705     bbc_prescale_hist->Reset();
0706     if (scaledowns.empty())
0707     {
0708       std::cout << "could not read scaledowns from run db, sleeping 1 minute and trying again" << std::endl;
0709       std::this_thread::sleep_for(std::chrono::milliseconds(1000*60)); // sleep for 1 minute
0710       rdb->GetScaledowns( scaledowns, runno );
0711     }
0712     if (!scaledowns.empty())
0713     {
0714       for ( int itrig = 0; itrig < 64; itrig++)
0715       {
0716         bbc_prescale_hist->SetBinContent( itrig+1, scaledowns[itrig] );
0717         std::cout << "scaledowns " << itrig << "\t" << scaledowns[itrig] << std::endl;
0718 
0719         if ( scaledowns[itrig] >= 0 )
0720         {
0721             trigs_enabled |= (0x1UL<<itrig);
0722         }
0723       }
0724     }
0725     else
0726     {
0727       std::cout << "could not read scaledowns from run db setting all scaledowns to 1" << std::endl;
0728       trigs_enabled = std::numeric_limits<uint64_t>::max();
0729     }
0730   }
0731   std::cout << "trigs_enabled 0x" << std::hex << trigs_enabled << std::dec << std::endl;
0732 
0733   mbdbest = GetMinBiasTrigBit( trigs_enabled );
0734   mbdwidebest = GetMinBiasWideTrigBit( trigs_enabled );
0735 
0736   if ( mbdbest == std::numeric_limits<uint64_t>::max() )
0737   {
0738     std::cout << "Oddball run without a proper MB trigger, using all triggers instead" << std::endl;
0739     trigmask = std::numeric_limits<uint64_t>::max();
0740     std::cout << std::hex << "trigmask " << trigmask << std::dec << std::endl;
0741   }
0742   else
0743   {
0744     trigmask = orig_trigmask;
0745   }
0746 
0747   dclock = 0xffffffffffffffffUL;
0748   gl1_offset = 0;
0749 
0750   return 0;
0751 }
0752 
0753 int BbcMon::GetFillNumber()
0754 {
0755   TString retval = gSystem->GetFromPipe( "/home/phnxrc/mbd/chiu/mbd_operations/httpRequestDemo.py -g ringSpec.blue fillNumberM | awk 'NR==1 {print $3}'" );
0756   if ( retval.IsDec() )
0757   {
0758     int fill = retval.Atoi();
0759     return fill;
0760   }
0761 
0762   std::cerr << PHWHERE << "GetFromPipe() failed with retval " << retval << std::endl;
0763   return 0; // default if we get back a junk value
0764 }
0765 
0766 uint64_t BbcMon::GetMinBiasTrigBit(uint64_t trigs_enabled)
0767 {
0768   // look for MB triggers, and select lowest prescale
0769   std::vector<int> widebits = {
0770     TriggerEnum::MBD_NS2_ZVRTX10,
0771     TriggerEnum::MBD_NS1_ZVRTX10,
0772     TriggerEnum::MBD_NS1_ZVRTX13,
0773     TriggerEnum::MBD_NS1,
0774     TriggerEnum::MBD_NS2,
0775     TriggerEnum::MBD_NS1_ZVRTX150,
0776   };
0777   
0778   int best_scaledown = 999999999;
0779   int best_trig = -1;
0780   float zcut = 1000.;
0781   for ( int itrig : widebits )
0782   {
0783     int scaledown = bbc_prescale_hist->GetBinContent( itrig + 1 );
0784     std::cout << "BEST_TRIG " << itrig << "\t" << scaledown << std::endl;
0785     if ( scaledown>=0 && scaledown<best_scaledown )
0786     {
0787       best_scaledown = scaledown;
0788       best_trig = itrig;
0789       switch (itrig)
0790       {
0791         case TriggerEnum::MBD_NS1_ZVRTX10:
0792           zcut = 10.;
0793           break;
0794         case TriggerEnum::MBD_NS2_ZVRTX10:
0795           zcut = 10.;
0796           break;
0797         case TriggerEnum::MBD_NS1_ZVRTX13:
0798           zcut = 13.3;
0799           break;
0800         case TriggerEnum::MBD_NS1_ZVRTX150:
0801           zcut = 150.;
0802           break;
0803       }
0804     }
0805   }
0806 
0807   if ( best_trig>=0 )
0808   {
0809     std::cout << "BEST MBDTRIG IS " << best_trig << std::endl;
0810     bbc_nevent_counter->SetBinContent(7,zcut);
0811     return ( 0x1UL << best_trig );
0812   }
0813 
0814   // no MBD only trigger, look for ZDC trigger
0815   if ( (zdcns&trigs_enabled) == zdcns )
0816   {
0817     return zdcns;
0818   }
0819 
0820   // no match, use any trigger
0821   return std::numeric_limits<uint64_t>::max();
0822 }
0823 
0824 uint64_t BbcMon::GetMinBiasWideTrigBit(uint64_t trigs_enabled)
0825 {
0826   // look for MB triggers, and select lowest prescale
0827   std::vector<int> widebits = {
0828     TriggerEnum::MBD_NS1,
0829     TriggerEnum::MBD_NS2,
0830     TriggerEnum::MBD_NS1_ZVRTX150
0831   };
0832   
0833   int best_scaledown = 99999999;
0834   int best_trig = -1;
0835   for ( int itrig : widebits )
0836   {
0837     int scaledown = bbc_prescale_hist->GetBinContent( itrig + 1 );
0838     if ( scaledown>=0 && scaledown<best_scaledown )
0839     {
0840       best_scaledown = scaledown;
0841       best_trig = itrig;
0842     }
0843   }
0844 
0845   if ( best_trig>=0 )
0846   {
0847     std::cout << "BEST WIDE MBDTRIG IS " << best_trig << std::endl;
0848     return ( 0x1UL << best_trig );
0849   }
0850 
0851   // no MBD only trigger, look for ZDC trigger
0852   if ( (zdcns&trigs_enabled) == zdcns )
0853   {
0854     std::cout << "BEST WIDE MBDTRIG IS ZDCNS" << std::endl;
0855     return zdcns;
0856   }
0857 
0858   // no match, use any trigger
0859   return std::numeric_limits<uint64_t>::max();
0860 }
0861 
0862 int BbcMon::UpdateSendFlag(const int flag)
0863 {
0864   sendflag = flag;
0865   std::ofstream sendflagfile( sendflagfname );
0866   if ( sendflagfile.is_open() )
0867   {
0868     sendflagfile << sendflag << std::endl;
0869   }
0870   else
0871   {
0872     static int ctr = 0;
0873     if ( ctr < 10 )
0874     {
0875       std::cout << "unable to open file " << sendflagfname << std::endl;
0876       ctr++;
0877     }
0878     return 0;
0879   }
0880   sendflagfile.close();
0881   return 1;
0882 }
0883 
0884 int BbcMon::GetSendFlag()
0885 {
0886   std::ifstream sendflagfile( sendflagfname );
0887   if ( sendflagfile.is_open() )
0888   {
0889     sendflagfile >> sendflag;
0890   }
0891   else
0892   {
0893     static int ctr = 0;
0894     if ( ctr < 10 )
0895     {
0896       std::cout << "unable to open file " << sendflagfname << std::endl;
0897       ctr++;
0898     }
0899     sendflag = 0;
0900   }
0901   sendflagfile.close();
0902 
0903   return sendflag;
0904 }
0905 
0906 int BbcMon::UpdateZResetFlag(const int flag)
0907 {
0908   zresetflag = flag;
0909   std::ofstream zresetflagfile( zresetflagfname );
0910   if ( zresetflagfile.is_open() )
0911   {
0912     zresetflagfile << zresetflag << std::endl;
0913   }
0914   else
0915   {
0916     static int ctr = 0;
0917     if ( ctr < 10 )
0918     {
0919       std::cout << "unable to open file " << zresetflagfname << std::endl;
0920       ctr++;
0921     }
0922     return 0;
0923   }
0924   zresetflagfile.close();
0925   return 1;
0926 }
0927 
0928 int BbcMon::GetZResetFlag()
0929 {
0930   std::ifstream zresetflagfile( zresetflagfname );
0931   if ( zresetflagfile.is_open() )
0932   {
0933     zresetflagfile >> zresetflag;
0934   }
0935   else
0936   {
0937     static int ctr = 0;
0938     if ( ctr < 10 )
0939     {
0940       std::cout << "unable to open file " << zresetflagfname << std::endl;
0941       ctr++;
0942     }
0943     zresetflag = 0;
0944   }
0945   zresetflagfile.close();
0946 
0947   return zresetflag;
0948 }
0949 
0950 int BbcMon::UpdateGL1BadFlag(const int flag)
0951 {
0952   gl1badflag = flag;
0953   std::ofstream gl1badflagfile( gl1badflagfname );
0954   if ( gl1badflagfile.is_open() )
0955   {
0956     gl1badflagfile << gl1badflag << std::endl;
0957   }
0958   else
0959   {
0960     static int ctr = 0;
0961     if ( ctr < 10 )
0962     {
0963       std::cout << "unable to open file " << gl1badflagfname << std::endl;
0964       ctr++;
0965     }
0966     return 0;
0967   }
0968   gl1badflagfile.close();
0969   std::cout << "YYY setting gl1bad " << gl1badflag << std::endl;
0970   return 1;
0971 }
0972 
0973 int BbcMon::GetGL1BadFlag()
0974 {
0975   std::ifstream gl1badflagfile( gl1badflagfname );
0976   if ( gl1badflagfile.is_open() )
0977   {
0978     gl1badflagfile >> gl1badflag;
0979   }
0980   else
0981   {
0982     static int ctr = 0;
0983     if ( ctr < 10 )
0984     {
0985       std::cout << "unable to open file " << gl1badflagfname << std::endl;
0986       ctr++;
0987     }
0988     gl1badflag = 0;
0989   }
0990   gl1badflagfile.close();
0991   //std::cout << "XXX gl1badflag " << gl1badflag << std::endl;
0992 
0993   return gl1badflag;
0994 }
0995 
0996 int BbcMon::FindGoodGL1(Event*& gl1evt, Packet*& gl1p, uint64_t fem_clock)
0997 {
0998   // Save originals
0999   Event *orig_e = gl1evt;
1000   Packet *orig_p = gl1p;
1001 
1002   //std::cout << "In FindGoodGL1" << orig_e << "\t" << orig_p << std::endl;
1003 
1004   // try up to 100 gl1 before
1005   for (int ievt = 1; ievt<=100; ievt++)
1006   {
1007     int evt2try = f_evt - gl1_offset - ievt;
1008     gl1evt = erc->getEvent( evt2try );
1009     if ( gl1evt )
1010     {
1011       gl1p = gl1evt->getPacket(14001);
1012       if ( gl1p )
1013       {
1014         uint64_t pre_dclock = ( gl1p->lValue(0,"BCO") - fem_clock )&0xffffffffUL;
1015         if ( pre_dclock == dclock )
1016         {
1017           gl1_offset = f_evt - evt2try;
1018           std::cout << "Found correct gl1, prev event " << ievt << "\t" << gl1_offset << "\t" << evt2try << std::endl;
1019           std::cout << "New pointers " << gl1evt << "\t" << gl1p << std::endl;
1020           if ( orig_e != gl1evt )
1021           {
1022             delete orig_e;
1023           }
1024           if ( orig_p != gl1p )
1025           {
1026             delete orig_p;
1027           }
1028           return 1;
1029         }
1030         delete gl1p;
1031       }
1032       delete gl1evt;
1033     }
1034     else
1035     {
1036       // ran out of gl1 in buffer, use originals
1037       gl1evt = orig_e;
1038       gl1p = orig_p;
1039       return -1;
1040     }
1041   }
1042 
1043   gl1evt = orig_e;
1044   gl1p = orig_p;
1045   return -1;    // not found
1046 }
1047 
1048 int BbcMon::EndRun(const int /* runno */)
1049 {
1050   // This does nothing for now, but can put summary info here for debugging
1051 
1052   return 0;
1053 }
1054 
1055 int BbcMon::process_event(Event *evt)
1056 {
1057   /*
1058   if (evt->getEvtType() == 9)  // spin patterns stored in BeginRun
1059   {
1060     std::cout << "Found begin run event " << std::endl;
1061     Packet *pBlueFillNumber = evt->getPacket(14915);
1062     //pYellFillNumber = evt->getPacket(packet_YELLFILLNUMBER);
1063     if ( pBlueFillNumber )
1064     {
1065       int fillnumberBlue = pBlueFillNumber->iValue(0);
1066       std::cout << "Blue fill number " << fillnumberBlue << std::endl;
1067       delete pBlueFillNumber;
1068     }
1069   }
1070   */
1071 
1072   if (evt->getEvtType() != DATAEVENT)
1073   {
1074     return 0;
1075   }
1076 
1077   f_evt = evt->getEvtSequence();
1078 
1079   if ( f_evt==100 ) std::cout << "skipto " << skipto << std::endl;
1080   if ( f_evt < skipto )
1081   {
1082       if ( (f_evt%10000)==0 )
1083       {
1084           std::cout << "skipping " << f_evt << ", skipto = " << skipto << std::endl;
1085       }
1086       return 0;
1087   }
1088 
1089   if ( Verbosity() && f_evt%1000 == 0 )
1090   {
1091     std::cout << "mbd evt " << f_evt << "\t" << useGL1 << std::endl;
1092   }
1093 
1094 
1095   evtcnt++;
1096   bbc_nevent_counter->Fill(0);
1097 
1098   [[maybe_unused]] OnlMonServer *se = OnlMonServer::instance();
1099 
1100   std::array<Packet *,2> p;
1101   p[0] = evt->getPacket(1001);
1102   p[1] = evt->getPacket(1002);
1103 
1104   // Check that we have both MBD/BBC packets
1105   if (!p[0] || !p[1])
1106   {
1107     std::ostringstream msg;
1108     msg << "MBD packet not found";
1109     se->send_message(this, MSG_SOURCE_BBC, MSG_SEV_WARNING, msg.str(), 1);
1110     msg.str("");
1111     bbc_nevent_counter->Fill(3);  // bad event, missing packets
1112 
1113     delete p[0];
1114     delete p[1];
1115 
1116     return 0;
1117   }
1118 
1119   h1_packet_status[p[0]->getStatus()]->Fill(1001);
1120   h1_packet_status[p[1]->getStatus()]->Fill(1002);
1121 
1122   // Check that both MBD/BBC packets have good checksums, and get clocks
1123 
1124   if ((p[0]->iValue(0, "EVENCHECKSUMOK") == 0) || (p[0]->iValue(0, "ODDCHECKSUMOK") == 0) ||
1125       (p[1]->iValue(0, "EVENCHECKSUMOK") == 0) || (p[1]->iValue(0, "ODDCHECKSUMOK") == 0))
1126   {
1127     std::ostringstream msg;
1128     msg << "MBD packets have bad checksum(s)";
1129     se->send_message(this, MSG_SOURCE_BBC, MSG_SEV_WARNING, msg.str(), 1);
1130     msg.str("");
1131     bbc_nevent_counter->Fill(4);  // bad event, missing packets
1132 
1133     delete p[0];
1134     delete p[1];
1135 
1136     return 0;
1137   }
1138 
1139   // Get clocks
1140   uint64_t clock0 = p[0]->lValue(0,"CLOCK");
1141   uint64_t clock1 = p[1]->lValue(0,"CLOCK");
1142   // check that they are the same...
1143   if ( clock0 != clock1 )
1144   {
1145     static int ctr = 0;
1146     if (evtcnt==1)
1147     {
1148       ctr = 0;
1149     }
1150 
1151     if ( ctr<10 )
1152     {
1153       std::cout << "ERROR, XMIT clocks differ, 0x" << std::hex << clock0 << "\t0x" << clock1 << std::dec << std::endl;
1154       ctr++;
1155     }
1156   }
1157 
1158   // Check event numbers
1159   int evt0 = p[0]->iValue(0,"EVTNR");
1160   int evt1 = p[1]->iValue(0,"EVTNR");
1161   int evtx = (f_evt&0xffffffff) - 2;      // xmit evt num, low 16 bits
1162 
1163   if ( (evt0 != evtx) || (evt1 != evtx) )
1164   {
1165     static int ctr = 0;
1166     if (evtcnt==1)
1167     {
1168       ctr = 0;
1169     }
1170 
1171     if ( ctr<5 )
1172     {
1173       std::cout << "ERROR, XMIT evtnum differs from pkts, " << evtx << "\t" << evt0 << "\t" << evt1 << std::endl;
1174       ctr++;
1175     }
1176   }
1177 
1178   delete p[0];
1179   delete p[1];
1180 
1181   if ( (f_evt%1000)==0 )
1182   {
1183     GetGL1BadFlag();
1184   }
1185 
1186   // Reset Z-Vertex Histograms
1187   int zreset = GetZResetFlag();
1188   if ( zreset == 1 )
1189   {
1190     bbc_zvertex->Reset();
1191     bbc_zvertex_alltrigger->Reset();
1192     bbc_zvertex_ns->Reset();
1193     bbc_zvertex_10->Reset();
1194     bbc_zvertex_30->Reset();
1195     bbc_zvertex_60->Reset();
1196     bbc_zvertex_ns_chk->Reset();
1197     bbc_zvertex_10_chk->Reset();
1198     bbc_zvertex_30_chk->Reset();
1199     bbc_zvertex_60_chk->Reset();
1200     bbc_zvertex_zdcns->Reset();
1201     bbc_zvertex_emcal->Reset();
1202     bbc_zvertex_hcal->Reset();
1203     bbc_zvertex_emcalmbd->Reset();
1204     bbc_zvertex_hcalmbd->Reset();
1205 
1206     UpdateZResetFlag( 0 );
1207   }
1208 
1209   // Get Trigger Info
1210   if ( useGL1 )
1211   {
1212     
1213     triggervec = 0UL;
1214     triginput = 0UL;
1215     trigraw = 0UL;
1216     triglive = 0UL;
1217     trigscaled = 0UL;
1218     Event *gl1Event = erc->getEvent( f_evt - gl1_offset );
1219     //std::cout << "gl1event " << (uint64_t)gl1Event << "\t" << f_evt << std::endl;
1220 
1221     if (gl1Event)
1222     {      
1223         se->IncrementGl1FoundCounter();
1224         //std::cout << "Found gl1event " << f_evt << std::endl;
1225         Packet* p_gl1 = gl1Event->getPacket(14001);
1226         if (p_gl1)
1227         {
1228             gl1_bco = p_gl1->lValue(0,"BCO");
1229             // get dclock
1230             if ( dclock == 0xffffffffffffffffUL )
1231             {
1232               dclock = (gl1_bco - clock0)&0xffffffffUL;
1233               std::cout << "DCLOCK = 0x" << std::hex << dclock << std::dec << std::endl;
1234             }
1235             else
1236             {
1237               uint64_t curr_dclock = (p_gl1->lValue(0,"BCO") - clock0)&0xffffffffUL;
1238               if ( curr_dclock != dclock )
1239               {
1240                 static int ctr = 0;
1241                 // Look for a good GL1
1242                 if ( ctr<10 )
1243                 {
1244                   std::cout << "ERROR, dclocks differ, 0x" << std::hex << dclock << "\t0x" << curr_dclock << std::dec << std::endl;
1245                   std::cout << "clocks: 0x" << std::hex << gl1_bco << "\t0x" << clock0 << std::dec << std::endl;
1246                   std::cout << "evt nums: " << f_evt << "\t" << evtx << "\t" << evt0 << "\t" << evt1 << std::endl;
1247                   ctr++;
1248                 }
1249 
1250                 int retval = FindGoodGL1( gl1Event, p_gl1, clock0 );
1251 
1252                 if ( retval == -1 ) 
1253                 {
1254                   bbc_nevent_counter->Fill(7);    // still bad clock
1255                 }
1256                 else
1257                 {
1258                   // if gl1 re-aligns, we reset the bad evt counter
1259                   bbc_nevent_counter->SetBinContent(8,0);
1260                   ctr = 0;
1261                 }
1262               }
1263             }
1264 
1265             triggervec = static_cast<uint64_t>( p_gl1->lValue(0,"TriggerVector") );
1266             triginput = static_cast<uint64_t>( p_gl1->lValue(0,"TriggerInput") );
1267             //std::cout << "trig " << std::hex << triggervec << "\t" << triginput << std::dec << std::endl;
1268 
1269             trigraw = static_cast<uint64_t>( p_gl1->lValue(0,"TriggerInput") );
1270             triglive = static_cast<uint64_t>( p_gl1->lValue(0,"LiveVector") );
1271             trigscaled = static_cast<uint64_t>( p_gl1->lValue(0,"ScaledVector") );
1272 
1273             triggervec = trigscaled;
1274             /*
1275             if( ((triggervec&mbdtrig)==0) && ((triggervec&zdcns)==0) ){
1276                 // if no mbd or zdcns bit is set, then we use the live vector
1277                 // to determine if this is a valid event
1278                 triggervec = triglive;
1279                 std::cout << "I am using the live vector for this event" << std::endl;
1280             }
1281             */
1282 
1283             /*
1284                std::cout << "TRIGS" << std::hex << std::endl;
1285                std::cout << "TrigInp\t" << std::setw(12) << triginput << std::endl;
1286                std::cout << "TrigVec\t" << std::setw(12) << triggervec << std::endl;
1287                std::cout << "RAW\t" << std::setw(12) << trigraw << std::endl;
1288                std::cout << "LIVE\t" << std::setw(12) << triglive << std::endl;
1289                std::cout << "SCALED\t" << std::setw(12) << trigscaled << std::endl;
1290                std::cout << "BUSY\t" << std::setw(12) << busy << std::endl;
1291                std::cout << std::dec << std::endl;
1292                */
1293 
1294             for (int itrig = 0; itrig < 64; itrig++ )
1295             {
1296                 uint64_t trigbit = 0x1UL << itrig;
1297                 if ( (triggervec&trigbit) != 0 )
1298                 {
1299                     bbc_trigs->Fill( itrig );
1300                 }
1301             }
1302 
1303             delete p_gl1;
1304         }
1305         delete gl1Event;
1306     }
1307   }
1308   else
1309   {
1310       // if we don't use GL1, set every trig bit true
1311       triggervec = std::numeric_limits<uint64_t>::max();
1312   }
1313 
1314   // calculate BBC
1315   bevt->Clear();
1316   bevt->SetRawData(evt,m_mbdraws,m_mbdpmts);
1317 
1318   if (bevt->calib_is_done() == 0)
1319   {
1320       return 0;
1321   }
1322 
1323   // Skip if this doesn't have a relevant trigger
1324   // (Can use any trigger for sampmax calib, in principle)
1325   if ( ((triggervec&trigmask) == 0UL) && (gl1badflag==0) )
1326   {
1327       if ( f_evt%1000 == 0 )
1328       {
1329           std::cout << "skipping " << f_evt << "\t" << std::hex << triggervec
1330               << "\t" << trigmask << std::dec << std::endl;
1331       }
1332       return 0;
1333   }
1334 
1335   bevt->Calculate(m_mbdpmts, m_mbdout);
1336 
1337   bbc_nevent_counter->Fill(1);
1338   double zvtx = m_mbdout->get_zvtx();
1339   double t0 = m_mbdout->get_t0();
1340   double qsum[2] = {0, 0};
1341   qsum[0] = m_mbdout->get_q(0);
1342   qsum[1] = m_mbdout->get_q(1);
1343   int south_nhits = m_mbdout->get_npmt(0);
1344   int north_nhits = m_mbdout->get_npmt(1);
1345 
1346   static int counter = 0;
1347   evtcnt++;
1348   if (counter < 10)
1349   {
1350       std::cout << "zt\t" << f_evt << "\t" << zvtx << "\t" << t0 << std::endl;
1351       counter++;
1352   }
1353 
1354   for ( int i = 0; i < TriggerEnum::NUM_MBD_TRIGGERS; i++ ){
1355     if ( (triggervec&TriggerEnum::MBTriggers[i]) != 0 )
1356     {
1357       bbc_last_update_ticker[i]++;
1358       if ( bbc_last_update_ticker[i] > zvtx_autoupdate_ticker ){
1359         for ( int ix = 0; ix < BbcMonDefs::zvtnbin; ix++ )
1360         {
1361           bbc_zvertex_autoupdate[i]->SetBinContent( ix+1, 0 ); // zero out the histogram
1362         }
1363         bbc_last_update_ticker[i] = 0;
1364       }
1365       bbc_zvertex_autoupdate[i]->Fill(zvtx);
1366     } // end of trigger check
1367   } // end of loop over triggers
1368 
1369   // vertex and t0
1370   //std::cout << "mbdns " << std::hex << mbdns << std::dec << std::endl;
1371   if ( (triggervec&mbdbest)!=0 )
1372   {
1373       bbc_nevent_counter->Fill(5);  // num BBCNS triggers
1374 
1375       bbc_zvertex->Fill(zvtx);
1376       bbc_zvertex_prime_short->Fill(zvtx);
1377       bbc_south_nhit->Fill( south_nhits );
1378       bbc_north_nhit->Fill( north_nhits );
1379   } 
1380   if ( (triggervec&mbdwidebest)!=0 )
1381   {
1382       bbc_zvertex_ns->Fill(zvtx);
1383       bbc_zvertex_short->Fill(zvtx);
1384       bbc_zvertex_ns_chk->Fill(zvtx);
1385 
1386       if ( triglive&mbdnsvtx10 )
1387       {
1388           bbc_zvertex_10_chk->Fill(zvtx);
1389       }
1390       if ( triglive&mbdnsvtx30 )
1391       {
1392           bbc_zvertex_30_chk->Fill(zvtx);
1393       }
1394       if ( triglive&mbdnsvtx150 )
1395       {
1396           bbc_zvertex_60_chk->Fill(zvtx);
1397       }
1398   }
1399   // else if ( (triglive&mbdns)!=0 ) 
1400   // {
1401   //     bbc_nevent_counter->Fill(5);  // num BBCNS triggers
1402 
1403   //     bbc_zvertex->Fill(zvtx);
1404   //     bbc_zvertex_short->Fill(zvtx);
1405   //     bbc_zvertex_ns->Fill(zvtx);
1406   //     bbc_south_nhit->Fill( south_nhits );
1407   //     bbc_north_nhit->Fill( north_nhits );
1408 
1409   //     if ( triginput&mbdnsvtx10 )
1410   //     {
1411   //         bbc_zvertex_10_chk->Fill(zvtx);
1412   //     }
1413   //     if ( triginput&mbdnsvtx30 )
1414   //     {
1415   //         bbc_zvertex_30_chk->Fill(zvtx);
1416   //     }
1417   //     if ( triginput&mbdnsvtx150 )
1418   //     {
1419   //         bbc_zvertex_60_chk->Fill(zvtx);
1420   //     }
1421 
1422   // }
1423 
1424   if ( triggervec&mbdnsvtx10 )
1425   {
1426       bbc_zvertex_10->Fill(zvtx);
1427   }
1428   if ( triggervec&mbdnsvtx30 )
1429   {
1430       bbc_zvertex_30->Fill(zvtx);
1431   }
1432   if ( triggervec&mbdnsvtx150 )
1433   {
1434       bbc_zvertex_60->Fill(zvtx);
1435   }
1436   if ( triggervec&zdcns )
1437   {
1438       bbc_zvertex_zdcns->Fill(zvtx);
1439   }
1440   if ( triggervec&emcal )
1441   {
1442       bbc_zvertex_emcal->Fill(zvtx);
1443       bbc_nhit_emcal[0]->Fill( south_nhits );
1444       bbc_nhit_emcal[1]->Fill( north_nhits );
1445   }
1446   if ( triggervec&hcal )
1447   {
1448       bbc_zvertex_hcal->Fill(zvtx);
1449       bbc_nhit_hcal[0]->Fill( south_nhits );
1450       bbc_nhit_hcal[1]->Fill( north_nhits );
1451   }
1452   if ( triggervec&emcalmbd )
1453   {
1454       bbc_zvertex_emcalmbd->Fill(zvtx);
1455       bbc_nhit_emcalmbd[0]->Fill( south_nhits );
1456       bbc_nhit_emcalmbd[1]->Fill( north_nhits );
1457   }
1458   if ( triggervec&hcalmbd )
1459   {
1460       bbc_zvertex_hcalmbd->Fill(zvtx);
1461       bbc_nhit_hcalmbd[0]->Fill( south_nhits );
1462       bbc_nhit_hcalmbd[1]->Fill( north_nhits );
1463   }
1464 
1465   // now fill in histograms when gl1 bypass is requested
1466   if ( gl1badflag )
1467   {
1468       bbc_zvertex_ns->Fill(zvtx);
1469       bbc_zvertex_10->Fill(zvtx);
1470   }
1471   //with all triggers
1472   bbc_zvertex_alltrigger->Fill(zvtx);
1473 
1474   // only process for primary mbd or zdcns trigger
1475   if ( ((triggervec&mbdtrig) == 0) && ((triggervec&zdcns)==0) && (gl1badflag==0) )
1476   {
1477       return 0;
1478   }
1479 
1480   bbc_tzero_zvtx->Fill(zvtx, t0);
1481 
1482   //== Send zvtx to MCR
1483   if ( prev_send_time == 0 )
1484   {
1485       prev_send_time = time(0);
1486   }
1487   time_t timediff = time(0) - prev_send_time;
1488 
1489   // send the vtx at a min of 5 seconds of data, and when we have > 1000 events
1490   // or we always send at 60 seconds if the above two conditions are not satisfied
1491   if ( ((timediff > 5) && (bbc_zvertex_short->Integral() >= 1000)) ||
1492        ((timediff > 60) && bbc_zvertex_short->GetEntries()>10) )
1493   {
1494       f_zvtx->SetRange(-75., 75.);
1495       f_zvtx->SetParameters(250, 0., 10);
1496 
1497       bbc_zvertex_short->Fit(f_zvtx, "RNQL");
1498 
1499       // Report z-vertex mean and width
1500       Double_t mean = f_zvtx->GetParameter(1);
1501       Double_t rms = f_zvtx->GetParameter(2);
1502       // we should do a check of a good fit here (skip for now)
1503       Double_t meanerr = f_zvtx->GetParError(1);
1504       Double_t rmserr = f_zvtx->GetParError(2);
1505 
1506       // For debugging
1507       if ( fabs(mean) > 20. )
1508       {
1509           double m = bbc_zvertex_short->GetMean();
1510           double me = bbc_zvertex_short->GetMeanError();
1511           double ent = bbc_zvertex_short->GetEntries();
1512           std::cout << "ZZZZ " << m << "\t" << me << "\t" << ent << std::endl;
1513           bbc_zvertex_short->Print("ALL");
1514       }
1515 
1516       std::ostringstream msg;
1517       msg << "MBD zvertex mean/width: " << mean << " " << rms << " " << meanerr << " " << rmserr;
1518       se->send_message(this, MSG_SOURCE_BBC, MSG_SEV_INFORMATIONAL, msg.str(), 1);
1519       std::cout << "MBD zvtx mean/width: " << mean << " " << rms << " " << meanerr << " " << rmserr << std::endl;
1520 
1521       if ( useGL1==1 && GetSendFlag() == 1 )
1522       {
1523         TString cmd = "/home/phnxrc/mbd/chiu/mbd_operations/httpRequestDemo.py -s sphenix.detector zMeanM "; cmd += mean;
1524         cmd += "; /home/phnxrc/mbd/chiu/mbd_operations/httpRequestDemo.py -s sphenix.detector zRmsM "; cmd += rms;
1525         gSystem->Exec( cmd );
1526       }
1527 
1528       // Fill histograms that keep track of running vtx
1529       std::time_t currtime = time(0) - tstart;  // delta-T from BeginRun() time
1530       std::cout << "currtime " << static_cast<Float_t>(currtime) << "\t" << time(0) << "\t" << tstart << std::endl;
1531       int n = bbc_runvtx->GetEntries();
1532       bbc_runvtx->SetBinContent( n+1, mean );
1533       bbc_runvtxerr->SetBinContent( n+1, meanerr );
1534       bbc_runvtxtime->SetBinContent( n+1, static_cast<Float_t>(currtime) );
1535 
1536       bbc_zvertex_short->Reset();
1537       
1538       prev_send_time = time(0);
1539   }
1540 
1541   for (int ipmt = 0; ipmt < 128; ipmt++)
1542   {
1543       float q = m_mbdpmts->get_pmt(ipmt)->get_q();
1544       bbc_adc->Fill(ipmt, q);
1545 
1546       // std::cout << f_evt << "\tipmt " << ipmt << "\t" << q << "\t";
1547       if (q > 0.5)
1548       {
1549           float tt = m_mbdpmts->get_pmt(ipmt)->get_time();
1550           if (ipmt < 64)
1551           {
1552               bbc_south_hittime->Fill(tt);
1553           }
1554           else
1555           {
1556               bbc_north_hittime->Fill(tt);
1557           }
1558 
1559           // std::cout << tq;
1560       }
1561       // std::cout << std::endl;
1562   }
1563 
1564   // charge
1565   bbc_south_chargesum->Fill(qsum[0]);
1566   bbc_north_chargesum->Fill(qsum[1]);
1567 
1568   // raw waveforms
1569   for (int ipmt = 0; ipmt < 128; ipmt++)
1570   {
1571       int tch = (ipmt / 8) * 16 + ipmt % 8;
1572       MbdSig *bbcsig = bevt->GetSig(tch);
1573       TGraphErrors *gwave = bbcsig->GetGraph();
1574       Int_t n = gwave->GetN();
1575       Double_t *x = gwave->GetX();
1576       Double_t *y = gwave->GetY();
1577       // make a threshold cut 
1578       for (int jsamp = 0; jsamp < n; jsamp++)
1579       {
1580           if ( y[jsamp]>20 )
1581           {
1582               for (int isamp = 0; isamp < n; isamp++)
1583               {
1584                   bbc_time_wave->Fill(x[isamp], ipmt, y[isamp]);
1585               }
1586               break;
1587           }
1588       }
1589 
1590       int qch = tch + 8;
1591       bbcsig = bevt->GetSig(qch);
1592       gwave = bbcsig->GetGraph();
1593       n = gwave->GetN();
1594       x = gwave->GetX();
1595       y = gwave->GetY();
1596       for (int isamp = 0; isamp < n; isamp++)
1597       {
1598           bbc_charge_wave->Fill(x[isamp], ipmt, y[isamp]);
1599       }
1600 
1601       // hit map
1602       float q = m_mbdpmts->get_pmt(ipmt)->get_q();
1603 
1604       if ( q>0. )
1605       {
1606           float xcent = _mbdgeom->get_x(ipmt);
1607           float ycent = _mbdgeom->get_y(ipmt);
1608           int arm = _mbdgeom->get_arm(ipmt);
1609           //std::cout << "q " << arm << "\t" << q << std::endl;
1610           if (arm == 0)
1611           {
1612               bbc_south_hitmap->Fill(xcent, ycent, q);
1613           }
1614           else if (arm == 1)
1615           {
1616               bbc_north_hitmap->Fill(xcent, ycent, q);
1617           }
1618       }
1619   }
1620 
1621   return 0;
1622 }
1623 
1624 int BbcMon::Reset()
1625 {
1626     // reset our internal counters
1627     evtcnt = 0;
1628     // idummy = 0;
1629 
1630     bbc_south_nhit->Reset();
1631     bbc_north_nhit->Reset();
1632     for (int iarm=0; iarm<2; iarm++)
1633     {
1634         bbc_nhit_emcal[iarm]->Reset();
1635         bbc_nhit_hcal[iarm]->Reset();
1636         bbc_nhit_emcalmbd[iarm]->Reset();
1637         bbc_nhit_hcalmbd[iarm]->Reset();
1638     }
1639     bbc_adc->Reset();
1640     bbc_tdc->Reset();
1641     bbc_tdc_overflow->Reset();
1642     bbc_tdc_armhittime->Reset();
1643     bbc_nevent_counter->Reset();
1644     bbc_zvertex->Reset();
1645     bbc_zvertex_short->Reset();
1646     bbc_zvertex_prime_short->Reset();
1647     bbc_zvertex_ns->Reset();
1648     bbc_zvertex_10->Reset();
1649     bbc_zvertex_30->Reset();
1650     bbc_zvertex_60->Reset();
1651     bbc_zvertex_ns_chk->Reset();
1652     bbc_zvertex_10_chk->Reset();
1653     bbc_zvertex_30_chk->Reset();
1654     bbc_zvertex_60_chk->Reset();
1655     bbc_zvertex_zdcns->Reset();
1656     bbc_zvertex_emcal->Reset();
1657     bbc_zvertex_hcal->Reset();
1658     bbc_zvertex_emcalmbd->Reset();
1659     bbc_zvertex_hcalmbd->Reset();
1660     bbc_tzero_zvtx->Reset();
1661     bbc_avr_hittime->Reset();
1662     bbc_south_hittime->Reset();
1663     bbc_north_hittime->Reset();
1664     bbc_south_chargesum->Reset();
1665     bbc_north_chargesum->Reset();
1666     bbc_prescale_hist->Reset();
1667     bbc_time_wave->Reset();
1668     bbc_charge_wave->Reset();
1669     bbc_runvtx->Reset();
1670     bbc_runvtxerr->Reset();
1671     bbc_runvtxtime->Reset();
1672     for ( int i = 0; i < TriggerEnum::NUM_MBD_TRIGGERS; i++ ){
1673       bbc_zvertex_autoupdate[i]->Reset();
1674       bbc_last_update_ticker[i] = 0;
1675     } 
1676 
1677     return 0;
1678 }
1679 
1680 int BbcMon::DBVarInit()
1681 {
1682     // variable names are not case sensitive
1683     /*
1684        std::string varname;
1685        varname = "bbcmoncount";
1686        dbvars->registerVar(varname);
1687        varname = "bbcmondummy";
1688        dbvars->registerVar(varname);
1689        varname = "bbcmonnew";
1690        dbvars->registerVar(varname);
1691        if (verbosity > 0)
1692        {
1693        dbvars->Print();
1694        }
1695        dbvars->DBInit();
1696        */
1697     return 0;
1698 }
1699 
1700 void BbcMon::set_skipto(const int s)
1701 {
1702   skipto = s;
1703   std::cout << "set skip " << skipto << std::endl;
1704 }