Back to home page

sPhenix code displayed by LXR

 
 

    


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

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 "ZdcMon.h"
0007 
0008 #include <onlmon/OnlMon.h>  // for OnlMon
0009 #include <onlmon/OnlMonDB.h>
0010 #include <onlmon/OnlMonServer.h>
0011 
0012 #include <Event/msg_profile.h>
0013 #include <calobase/TowerInfoDefs.h>
0014 #include <caloreco/CaloWaveformFitting.h>
0015 
0016 #include <Event/Event.h>
0017 #include <Event/EventTypes.h>
0018 #include <Event/msg_profile.h>
0019 
0020 #include <TH1.h>
0021 #include <TH2.h>
0022 #include <TProfile.h>
0023 #include <TRandom.h>
0024 
0025 #include <cmath>
0026 #include <cstdio>  // for printf
0027 #include <fstream>
0028 #include <iostream>
0029 #include <sstream>
0030 #include <string>  // for allocator, string, char_traits
0031 
0032 enum
0033 {
0034   TRGMESSAGE = 1,
0035   FILLMESSAGE = 2
0036 };
0037 
0038 ZdcMon::ZdcMon(const std::string &name)
0039   : OnlMon(name)
0040 {
0041   // leave ctor fairly empty, its hard to debug if code crashes already
0042   // during a new ZdcMon()
0043   return;
0044 }
0045 
0046 ZdcMon::~ZdcMon()
0047 {
0048   // you can delete NULL pointers it results in a NOOP (No Operation)
0049   return;
0050 }
0051 
0052 int ZdcMon::Init()
0053 {
0054   const float MAX_ENERGY1 = 1500.; // previously 12000 for AuAu
0055   const float MAX_ENERGY2 = 1500.; // previously 30000 for AuAu
0056   const float MAX_WFAMP = 20000.;
0057   const float MIN_ENERGY1 = 0.;
0058   const float MIN_ENERGY2 = 0.;
0059   const int BIN_NUMBER1 = 250;
0060   const int BIN_NUMBER2 = 550;
0061   const int SMD_ADC_BIN = 360;
0062   //const float MAX_SMD_ADC = 18000.; // AuAu
0063   const float MAX_SMD_ADC = 12000.; // pp
0064   const int BIN_WF = 1000;
0065     
0066   //  gRandom->SetSeed(rand());
0067   // read our calibrations from ZdcMonData.dat
0068   const char *zdccalib = getenv("ZDCCALIB");
0069   if (!zdccalib)
0070   {
0071     std::cout << "ZDCCALIB environment variable not set" << std::endl;
0072     exit(1);
0073   }
0074   std::string fullfile = std::string(zdccalib) + "/" + "ZdcMonData.dat";
0075   std::ifstream calib(fullfile);
0076   calib.close();
0077 
0078   //getting gains
0079   float col1, col2, col3;
0080   std::string gainfile = std::string(zdccalib) + "/" + "/ZdcCalib.pmtgain";
0081   std::ifstream gain_infile(gainfile);
0082   std::ostringstream msg(gainfile);
0083 
0084   if (!gain_infile)
0085   {
0086     msg << gainfile << " could not be opened.";
0087     OnlMonServer *se = OnlMonServer::instance();
0088     se->send_message(this, MSG_SOURCE_ZDC, MSG_SEV_FATAL, msg.str(), 2);
0089     exit(1);
0090   }
0091 
0092   for (float &i : gain)
0093   {
0094     gain_infile >> col1 >> col2 >> col3;
0095     i = col1;
0096   }
0097 
0098   for (int i = 0; i < 16; i++)  // relative gains of SMD north channels
0099   {
0100     smd_south_rgain[i] = gain[i];  // 0-7: y channels, 8-14: x channels, 15: analog sum
0101   }
0102 
0103   for (int i = 0; i < 16; i++)  // relative gains of SMD north channels
0104   {
0105     smd_north_rgain[i] = gain[i + 16];  // 0-7: y channels, 8-14: x channels, 15: analog sum
0106   }
0107 
0108   gain_infile.close();
0109 
0110   // use printf for stuff which should go the screen but not into the message
0111   // system (all couts are redirected)
0112   printf("doing the Init\n");
0113 
0114   // Create hitograms
0115   zdc_adc_north = new TH1F("zdc_adc_north", "ZDC ADC north", BIN_NUMBER2, MIN_ENERGY2, MAX_ENERGY2);
0116   zdc_adc_south = new TH1F("zdc_adc_south", "ZDC ADC south", BIN_NUMBER2, MIN_ENERGY2, MAX_ENERGY2);
0117 
0118   zdc_N1 = new TH1F("zdc_N1", "ZDC1 ADC north", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0119   zdc_N2 = new TH1F("zdc_N2", "ZDC2 ADC north", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0120   zdc_N3 = new TH1F("zdc_N3", "ZDC3 ADC north", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0121   zdc_S1 = new TH1F("zdc_S1", "ZDC1 ADC south", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0122   zdc_S2 = new TH1F("zdc_S2", "ZDC2 ADC south", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0123   zdc_S3 = new TH1F("zdc_S3", "ZDC3 ADC south", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0124 
0125   veto_NF = new TH1F("veto_NF", "veto north front", SMD_ADC_BIN, MIN_ENERGY2, MAX_SMD_ADC);
0126   veto_NB = new TH1F("veto_NB", "veto north back", SMD_ADC_BIN, MIN_ENERGY2, MAX_SMD_ADC);
0127   veto_SF = new TH1F("veto_SF", "veto south front", SMD_ADC_BIN, MIN_ENERGY2, MAX_SMD_ADC);
0128   veto_SB = new TH1F("veto_SB", "veto south back", SMD_ADC_BIN, MIN_ENERGY2, MAX_SMD_ADC);
0129 
0130   //waveform
0131     
0132    h_waveform_timez = new TH1F("h_waveform_timez", "", 16, 0.5, 16 + 0.5);
0133    h_waveform_timess = new TH1F("h_waveform_timess", "", 16, 0.5, 16 + 0.5);
0134    h_waveform_timesn = new TH1F("h_waveform_timesn", "", 16, 0.5, 16 + 0.5);
0135    h_waveform_timevs = new TH1F("h_waveform_timevs", "", 16, 0.5, 16 + 0.5);
0136    h_waveform_timevn = new TH1F("h_waveform_timevn", "", 16, 0.5, 16 + 0.5);
0137 
0138   h_waveformZDC = new TH2F("h_waveformZDC", "h_waveformZDC", 31, 0.5, 31 + 0.5, BIN_WF, 0, MAX_WFAMP);
0139   h_waveformSMD_North = new TH2F("h_waveformSMD_North", "h_waveformSMD_North", 31, 0.5, 31 + 0.5, BIN_WF, 0, MAX_WFAMP);
0140   h_waveformSMD_South = new TH2F("h_waveformSMD_South", "h_waveformSMD_South", 31, 0.5, 31 + 0.5, BIN_WF, 0, MAX_WFAMP);
0141   h_waveformVeto_North = new TH2F("h_waveformVeto_North", "h_waveformVeto_North", 31, 0.5, 31 + 0.5, BIN_WF, 0, MAX_WFAMP);
0142   h_waveformVeto_South = new TH2F("h_waveformVeto_South", "h_waveformVeto_South", 31, 0.5, 31 + 0.5, BIN_WF, 0, MAX_WFAMP);
0143       
0144   // SMD
0145   // Individual SMD_ADC Values
0146   // Horizontal (expert plot)
0147   for (int i = 0; i < 8; i++)
0148   {
0149     smd_adc_n_hor_ind[i] = new TH1I(Form("smd_adc_n_hor_ind%d", i), Form("smd_adc_n_hor_ind%d", i), SMD_ADC_BIN, 0, MAX_SMD_ADC);
0150     smd_adc_s_hor_ind[i] = new TH1I(Form("smd_adc_s_hor_ind%d", i), Form("smd_adc_s_hor_ind%d", i), SMD_ADC_BIN, 0, MAX_SMD_ADC);
0151   }
0152   // Vertical (expert plot)
0153   for (int i = 0; i < 7; i++)
0154   {
0155     smd_adc_n_ver_ind[i] = new TH1I(Form("smd_adc_n_ver_ind%d", i), Form("smd_adc_n_ver_ind%d", i), SMD_ADC_BIN, 0, MAX_SMD_ADC);
0156     smd_adc_s_ver_ind[i] = new TH1I(Form("smd_adc_s_ver_ind%d", i), Form("smd_adc_s_ver_ind%d", i), SMD_ADC_BIN, 0, MAX_SMD_ADC);
0157   }
0158 
0159   // SMD Hit Multiplicity
0160   smd_north_hor_hits = new TH1F("smd_north_hor_hits", "smd_north_hor_hits", 9, -0.5, 8.5);
0161   smd_north_ver_hits = new TH1F("smd_north_ver_hits", "smd_north_ver_hits", 8, -0.5, 7.5);
0162   smd_south_hor_hits = new TH1F("smd_south_hor_hits", "smd_south_hor_hits", 9, -0.5, 8.5);
0163   smd_south_ver_hits = new TH1F("smd_south_ver_hits", "smd_south_ver_hits", 8, -0.5, 7.5);
0164 
0165   // north smd
0166   smd_hor_north = new TH1F("smd_hor_north", "Beam centroid distribution, SMD North y", 296, -5.92, 5.92);
0167   smd_ver_north = new TH1F("smd_ver_north", "Beam centroid distribution, SMD North x", 220, -5.5, 5.5);
0168   
0169   smd_sum_hor_north = new TH1F("smd_sum_hor_north", "SMD North y", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0170   smd_sum_ver_north = new TH1F("smd_sum_ver_north", "SMD North x", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0171 
0172   smd_hor_north_small = new TH1F("smd_hor_north_small", "Beam centroid distribution, SMD North y, zdc <= 200", 296, -5.92, 5.92);
0173   smd_ver_north_small = new TH1F("smd_ver_north_small", "Beam centroid distribution, SMD North x, zdc <= 200", 220, -5.5, 5.5);
0174   smd_hor_north_good = new TH1F("smd_hor_north_good", "Beam centroid distribution, SMD North y, zdc > 200", 296, -5.92, 5.92);
0175   smd_ver_north_good = new TH1F("smd_ver_north_good", "Beam centroid distribution, SMD North x, zdc > 200", 220, -5.5, 5.5);
0176 
0177   // south smd
0178   smd_hor_south = new TH1F("smd_hor_south", "Beam centroid distribution, SMD South y", 296, -5.92, 5.92);
0179   smd_ver_south = new TH1F("smd_ver_south", "Beam centroid distribution, SMD South x", 220, -5.5, 5.5);
0180 
0181   smd_sum_hor_south = new TH1F("smd_sum_hor_south", "SMD South y", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0182   smd_sum_ver_south = new TH1F("smd_sum_ver_south", "SMD South x", BIN_NUMBER1, MIN_ENERGY1, MAX_ENERGY1);
0183   
0184   smd_hor_south_good = new TH1F("smd_hor_south_good", "Beam centroid distribution, SMD South y, zdc1 > 65 zdc2>20 and veto<200", 296, -5.92, 5.92);
0185   smd_ver_south_good = new TH1F("smd_ver_south_good", "Beam centroid distribution, SMD South x, zdc1 > 65 zdc2>20 and veto<200", 220, -5.5, 5.5);
0186 
0187 
0188   // smd values (expert plot)
0189   smd_value = new TH2F("smd_value", "SMD channel# vs value", 1024, 0, 4096, 33, -0.5, 32.5);
0190   smd_value_good = new TH2F("smd_value_good", "SMD channel# vs value, zdc > 200", 1024, 0, 4096, 33, -0.5, 32.5);
0191   smd_value_small = new TH2F("smd_value_small", "SMD channel# vs value, zdc <= 200", 1024, 0, 4096, 33, -0.5, 32.5);
0192   smd_xy_north = new TH2F("smd_xy_north", "SMD hit position north", 110, -5.5, 5.5, 119, -5.92, 5.92);
0193   smd_xy_south = new TH2F("smd_xy_south", "SMD hit position south", 110, -5.5, 5.5, 119, -5.92, 5.92);
0194 
0195   OnlMonServer *se = OnlMonServer::instance();
0196 
0197   //register histograms with server otherwise client won't get them
0198   //zdc
0199   se->registerHisto(this, zdc_adc_north);
0200   se->registerHisto(this, zdc_adc_south);
0201   se->registerHisto(this, zdc_N1);
0202   se->registerHisto(this, zdc_N2);
0203   se->registerHisto(this, zdc_N3);
0204   se->registerHisto(this, zdc_S1);
0205   se->registerHisto(this, zdc_S2);
0206   se->registerHisto(this, zdc_S3);
0207   se->registerHisto(this, h_waveformZDC);
0208   se->registerHisto(this, h_waveformSMD_North);
0209   se->registerHisto(this, h_waveformSMD_South);
0210   se->registerHisto(this, h_waveformVeto_North);
0211   se->registerHisto(this, h_waveformVeto_South);
0212     
0213   se->registerHisto(this, h_waveform_timez);
0214   se->registerHisto(this, h_waveform_timess);
0215   se->registerHisto(this, h_waveform_timesn);
0216   se->registerHisto(this, h_waveform_timevs);
0217   se->registerHisto(this, h_waveform_timevn);
0218  
0219     
0220   //veto
0221   se->registerHisto(this, veto_NF);
0222   se->registerHisto(this, veto_NB);
0223   se->registerHisto(this, veto_SF);
0224   se->registerHisto(this, veto_SB);
0225  
0226 
0227   // SMD
0228   // Individual smd_adc channel histos
0229 
0230   for (int i = 0; i < 8; i++)
0231   {
0232     se->registerHisto(this, smd_adc_n_hor_ind[i]);
0233     se->registerHisto(this, smd_adc_s_hor_ind[i]);
0234   }
0235   for (int i = 0; i < 7; i++)
0236   {
0237     se->registerHisto(this, smd_adc_n_ver_ind[i]);
0238     se->registerHisto(this, smd_adc_s_ver_ind[i]);
0239   }
0240 
0241   // SMD Hit Multiplicity
0242   se->registerHisto(this, smd_north_hor_hits);
0243   se->registerHisto(this, smd_north_ver_hits);
0244   se->registerHisto(this, smd_south_hor_hits);
0245   se->registerHisto(this, smd_south_ver_hits);
0246   
0247 
0248   // north SMD
0249   se->registerHisto(this, smd_hor_north);
0250   se->registerHisto(this, smd_ver_north);
0251   se->registerHisto(this, smd_sum_hor_north);
0252   se->registerHisto(this, smd_sum_ver_north);
0253   se->registerHisto(this, smd_hor_north_small);
0254   se->registerHisto(this, smd_ver_north_small);
0255   se->registerHisto(this, smd_hor_north_good);
0256   se->registerHisto(this, smd_ver_north_good);
0257   // south SMD
0258   se->registerHisto(this, smd_hor_south);
0259   se->registerHisto(this, smd_ver_south);
0260   se->registerHisto(this, smd_sum_hor_south);
0261   se->registerHisto(this, smd_sum_ver_south);
0262   se->registerHisto(this, smd_hor_south_good);
0263   se->registerHisto(this, smd_ver_south_good);
0264   // SMD values
0265   se->registerHisto(this, smd_value);
0266   se->registerHisto(this, smd_value_good);
0267   se->registerHisto(this, smd_value_small);
0268   se->registerHisto(this, smd_xy_north);
0269   se->registerHisto(this, smd_xy_south);
0270 
0271   WaveformProcessingFast = new CaloWaveformFitting();
0272 
0273   Reset();
0274 
0275   return 0;
0276 }
0277 
0278 int ZdcMon::BeginRun(const int /* runno */)
0279 {
0280   // if you need to read calibrations on a run by run basis
0281   // this is the place to do it
0282 
0283   return 0;
0284 }
0285 
0286 std::vector<float> ZdcMon::anaWaveformFast(Packet *p, const int channel)
0287 {
0288   std::vector<float> waveform;
0289   // Chris: preallocation = speed improvement
0290   waveform.reserve(p->iValue(0, "SAMPLES"));
0291   for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
0292   {
0293     waveform.push_back(p->iValue(s, channel));
0294   }
0295   std::vector<std::vector<float>> multiple_wfs;
0296   multiple_wfs.push_back(waveform);
0297 
0298   std::vector<std::vector<float>> fitresults_zdc;
0299   fitresults_zdc = WaveformProcessingFast->calo_processing_fast(multiple_wfs);
0300 
0301   std::vector<float> result;
0302   result = fitresults_zdc.at(0);
0303   return result;
0304 }
0305 
0306 int ZdcMon::process_event(Event *e /* evt */)
0307 {
0308   evtcnt++;
0309     
0310   const float waveform_hit_threshold = 100 * 5.;
0311 
0312   int packet = 12001;
0313 
0314   float totalzdcsouthsignal = 0.;
0315   float totalzdcnorthsignal = 0.;
0316   float smd_south_xsum = 0.;
0317   float smd_south_ysum = 0.;
0318   float smd_north_xsum = 0.;
0319   float smd_north_ysum = 0.;
0320 
0321   float veto_cut = 200.0;
0322   float ZDC1cut = 65.0;
0323   float ZDC2cut = 20.0;
0324 
0325   std::vector <float> z;
0326   z.clear();
0327     
0328   std::vector <float> sm;
0329   sm.clear();
0330     
0331   std::vector <float> tz;
0332   tz.clear();
0333     
0334   std::vector <float> tsmd;
0335   tsmd.clear();
0336     
0337   std::vector<float> resultFast;
0338   resultFast.clear();
0339 
0340   float zdctimelow  = 5.0;
0341   float zdctimehigh  = 9.0;
0342     
0343   float smdNtimelow  = 9.0;
0344   float smdNtimehigh  = 14.0;
0345 
0346   float smdStimelow  = 6.0;
0347   float smdStimehigh  = 12.0;
0348     
0349   float vetoStimelow  = 6.0;
0350   float vetoStimehigh  = 12.0;
0351     
0352   float vetoNtimelow  = 5.0;
0353   float vetoNtimehigh  = 9.0;
0354  
0355   Packet *p = e->getPacket(packet);
0356   if (p)
0357   {
0358         
0359     for (int c = 0; c < p->iValue(0, "CHANNELS"); c++)
0360     {
0361       resultFast = anaWaveformFast(p, c);  // fast waveform fitting
0362       float signalFast = resultFast.at(0);
0363       float time = resultFast.at(1);
0364       float pedestal = resultFast.at(2);
0365       float signal = signalFast;
0366         
0367         for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
0368         {
0369             if (c < 16)
0370             {
0371                 if (signal > waveform_hit_threshold) h_waveformZDC->Fill(s, p->iValue(s, c) - pedestal);
0372             }
0373             
0374             if (c > 15 && c < 18)
0375             {
0376                 if (signal > waveform_hit_threshold) h_waveformVeto_North->Fill(s, p->iValue(s, c) - pedestal);
0377             }
0378             
0379             if (c > 47 && c < 64)
0380             {
0381                 if (signal > waveform_hit_threshold) h_waveformSMD_North->Fill(s, p->iValue(s, c) - pedestal);
0382             }
0383             
0384             if (c > 79 && c < 82)
0385             {
0386                 if (signal > waveform_hit_threshold) h_waveformVeto_South->Fill(s, p->iValue(s, c) - pedestal);
0387             }
0388             
0389             if (c > 111)
0390             {
0391                 if (signal > waveform_hit_threshold) h_waveformSMD_South->Fill(s, p->iValue(s, c) - pedestal);
0392             }
0393         }
0394 
0395      // fill zdc raw signal first
0396      if(c < 16)
0397      {
0398          if(signal > waveform_hit_threshold)
0399          {
0400            h_waveform_timez->Fill(time);
0401          }
0402  
0403        z.push_back(signal);
0404        tz.push_back(time);
0405 
0406       if((c == 0) || (c == 2) || (c == 4))
0407       {
0408          totalzdcsouthsignal += signal;
0409           
0410          if(c == 0) zdc_S1->Fill(signal);
0411          if(c == 2) zdc_S2->Fill(signal);
0412          if(c == 4) zdc_S3->Fill(signal);
0413       }
0414 
0415       else if((c==8) || (c ==10) || (c == 12))
0416       {
0417          totalzdcnorthsignal += signal;
0418           
0419          if(c == 8) zdc_N1->Fill(signal);
0420          if(c == 10) zdc_N2->Fill(signal);
0421          if(c == 12) zdc_N3->Fill(signal);
0422       }
0423      }
0424 
0425     // veto N
0426     else if(c > 15 && c < 18)
0427     {
0428         if(signal > waveform_hit_threshold)
0429         {
0430            h_waveform_timevn->Fill(time);
0431         }
0432         
0433         if(((time >= vetoNtimelow) && (time <= vetoNtimehigh)))
0434         {
0435 
0436             if(c == 16)
0437             {
0438                 v[0] = signal; if(signal > 0.) veto_NF->Fill(signal);
0439             }
0440             
0441             if (c == 17)
0442             {
0443                 v[1] = signal; if(signal > 0.) veto_NB->Fill(signal);
0444             }
0445         }
0446         
0447     }
0448         
0449      //smd N
0450      else if(c > 47 && c < 64)
0451      {
0452         sm.push_back(signal);
0453         tsmd.push_back(time);
0454          
0455          if(signal > waveform_hit_threshold)
0456          {
0457             h_waveform_timesn->Fill(time);
0458          }
0459      }
0460         
0461     // veto S
0462     else if(c > 79 && c < 82)
0463     {
0464         if(((time >= vetoStimelow) && (time <= vetoStimehigh)))
0465         {
0466 
0467             if(c == 80)
0468             {
0469                 v[2] = signal; if(signal > 0.) veto_SF->Fill(signal);
0470             }
0471                 
0472             if (c == 81)
0473             {
0474                 v[3] = signal; if(signal > 0.) veto_SB->Fill(signal);
0475             }
0476         }
0477         
0478         if(signal > waveform_hit_threshold)
0479         {
0480             h_waveform_timevs->Fill(time);
0481         }
0482         
0483             
0484     }
0485         
0486           
0487     //smd S
0488      else if(c > 111)
0489      {
0490            sm.push_back(signal);
0491            tsmd.push_back(time);
0492          
0493          if(signal > waveform_hit_threshold)
0494          {
0495              h_waveform_timess->Fill(time);
0496          }
0497      }
0498 
0499 
0500   }// channel loop end
0501 
0502       
0503    zdc_adc_south->Fill(totalzdcsouthsignal);
0504    zdc_adc_north->Fill(totalzdcnorthsignal);
0505 
0506         
0507   int zsize = z.size();
0508   int ssize = sm.size();
0509       
0510    if(zsize != 16)
0511     {
0512       std::cout<< "zdc channel mapping error" << std::endl;
0513       if(tz.size() != 16)
0514       exit(1);
0515     }
0516 
0517    if(ssize != 32)
0518     {
0519       std::cout<< "smd channel mapping error" << std::endl;
0520       if(tsmd.size() != 32)
0521       exit(1);
0522     }
0523 
0524 
0525      for (int i = 0; i < zsize; i++) //zdc
0526      {
0527          if ((tz[i] >= zdctimelow) && (tz[i] <= zdctimehigh))
0528          {
0529              zdc_adc[i] = z[i];
0530          }
0531          else
0532          {
0533             zdc_adc[i] = 0.0;
0534          }
0535      }//zdc
0536 
0537      for (int j = 0; j < ssize; j++) //smd
0538       {
0539           if(j < 16) //smd north [0,15] --> [48,63]
0540           {
0541             if((tsmd[j] >= smdNtimelow) && (tsmd[j] <= smdNtimehigh))
0542               {
0543                   
0544                   smd_adc[j] = sm[j];
0545                   if(j<=7) smd_north_ysum += sm[j];
0546                   if(j >= 8 && j<=14) smd_north_xsum += sm[j]; //skip sum ch, 15->63
0547               }
0548               else
0549               {
0550                  smd_adc[j] = 0.0;
0551               }
0552            }
0553         
0554           if (j >= 16 && j <= 31) //smd south [16,31] --> [112,127]
0555           {
0556              if((tsmd[j] >= smdStimelow) && (tsmd[j] <= smdStimehigh ))
0557               {
0558                   smd_adc[j] = sm[j];
0559                   if(j >= 16 && j<=23) smd_south_ysum += sm[j];
0560                   if(j >= 24 && j<=30) smd_south_xsum += sm[j]; //skip sum ch, 31->127
0561               }
0562               else
0563               {
0564                   smd_adc[j] = 0.0;
0565               }
0566           }
0567       }//smd
0568 
0569 
0570 
0571   // call the functions
0572     CompSmdAdc();
0573     CompSmdPos();
0574 
0575     // BOOLEANS, INTs AND OTHER DEFINITIONS
0576 
0577     bool fill_hor_south = false;
0578     bool fill_ver_south = false;
0579 
0580     bool fill_hor_north = false;
0581     bool fill_ver_north = false;
0582 
0583     int s_ver = 0;
0584     int s_hor = 0;
0585 
0586     int n_ver = 0;
0587     int n_hor = 0;
0588 
0589     float zdc_adc_threshold = 200.;
0590     float smd_adc_threshold = 20.;
0591    
0592     // counters
0593     int smd_n_h_counter = 0;
0594     int smd_n_v_counter = 0;
0595     int smd_s_h_counter = 0;
0596     int smd_s_v_counter = 0;
0597     
0598       
0599     float hor_cut = 8.0;
0600     float ver_cut = 8.0;
0601     float ped_cut = 0.0; //suppress zeroes
0602 
0603     for (int i = 0; i < 8; i++)
0604     {
0605 
0606      if (smd_adc[i] > hor_cut)
0607       {
0608         n_hor++;
0609       }
0610       
0611 
0612      if (smd_adc[i] > ped_cut) smd_adc_n_hor_ind[i]->Fill(smd_adc[i]);
0613 
0614      smd_value->Fill(smd_adc[i], float(i));
0615    
0616      if (zdc_adc[8] > veto_cut)
0617       {
0618          smd_value_good->Fill(smd_adc[i], float(i));
0619       }
0620       else
0621       {
0622          smd_value_small->Fill(smd_adc[i], float(i));
0623       }
0624 
0625       if ((smd_adc[i] > smd_adc_threshold) && (zdc_adc[0] > zdc_adc_threshold))
0626       {
0627         smd_n_h_counter++;
0628       }
0629 
0630       if (smd_adc[i] > smd_adc_threshold)
0631       {
0632         smd_n_h_counter++;
0633       }
0634 
0635       if (smd_adc[i + 16] > hor_cut)
0636       {
0637         s_hor++;
0638       }
0639     
0640       if (smd_adc[i + 16] > ped_cut) smd_adc_s_hor_ind[i]->Fill(smd_adc[i + 16]);
0641       
0642       smd_value->Fill(smd_adc[i + 16], float(i) + 16);
0643      
0644       if (zdc_adc[0] > veto_cut)
0645       {
0646         smd_value_good->Fill(smd_adc[i + 16], float(i) + 16);
0647       }
0648       else
0649       {
0650         smd_value_small->Fill(smd_adc[i + 16], float(i) + 16);
0651       }
0652 
0653 
0654       if (smd_adc[i + 16] > smd_adc_threshold)
0655       {
0656         smd_s_h_counter++;
0657       }
0658         
0659     }
0660 
0661     for (int i = 0; i < 7; i++)
0662     {
0663       if (smd_adc[i + 8] > ver_cut)
0664       {
0665         n_ver++;
0666       }
0667      
0668   
0669       if(smd_adc[i + 8] > ped_cut) smd_adc_n_ver_ind[i]->Fill(smd_adc[i + 8]);
0670 
0671       smd_value->Fill(smd_adc[i + 8], float(i) + 8);
0672    
0673       if (zdc_adc[8] > veto_cut)
0674       {
0675         smd_value_good->Fill(smd_adc[i + 8], float(i) + 8);
0676       }
0677       else
0678       {
0679         smd_value_small->Fill(smd_adc[i + 8], float(i) + 8);
0680       }
0681 
0682       if (smd_adc[i + 8] > smd_adc_threshold)
0683       {
0684         smd_n_v_counter++;
0685       }
0686       //****************************
0687 
0688       //****smd south vertical individual channels****
0689       if (smd_adc[i + 24] > ver_cut)
0690       {
0691         s_ver++;
0692       }
0693       
0694       if (smd_adc[i + 24] > ped_cut)   smd_adc_s_ver_ind[i]->Fill(smd_adc[i + 24]);
0695 
0696       smd_value->Fill(smd_adc[i + 24], float(i) + 24);
0697     
0698       if (zdc_adc[0] > veto_cut)
0699       {
0700         smd_value_good->Fill(smd_adc[i + 24], float(i) + 24);
0701       }
0702       else
0703       {
0704         smd_value_small->Fill(smd_adc[i + 24], float(i) + 24);
0705       }
0706 
0707       if (smd_adc[i + 24] > smd_adc_threshold)
0708       {
0709         smd_s_v_counter++;
0710       }
0711       //****************************
0712 
0713       // Fill out the SMD counters with doubles instead of integers.
0714       double nh = smd_n_h_counter + 0.0;
0715       smd_north_hor_hits->Fill(nh);
0716       double nv = smd_n_v_counter + 0.0;
0717       smd_north_ver_hits->Fill(nv);
0718       double sh = smd_s_h_counter + 0.0;
0719       smd_south_hor_hits->Fill(sh);
0720       double sv = smd_s_v_counter + 0.0;
0721       smd_south_ver_hits->Fill(sv);
0722     }
0723 
0724     
0725     bool fired_smd_hor_n = (n_hor > 1);
0726     bool fired_smd_ver_n = (n_ver > 1);
0727 
0728     bool fired_smd_hor_s = (s_hor > 1);
0729     bool fired_smd_ver_s = (s_ver > 1);
0730 
0731    //compute, if smd is overloaded
0732     bool smd_ovld_north = false;
0733     bool smd_ovld_south = false;
0734 
0735     // FILLING OUT THE HISTOGRAMS
0736     
0737 
0738     if (fired_smd_hor_s && fired_smd_ver_s && !smd_ovld_south)
0739     {
0740       fill_hor_south = true;
0741       fill_ver_south = true;
0742       smd_hor_south->Fill(smd_pos[2]);
0743       smd_ver_south->Fill(smd_pos[3]);
0744       smd_sum_ver_south->Fill(smd_south_xsum);
0745       smd_sum_hor_south->Fill(smd_south_ysum);
0746     }
0747 
0748     if(fill_hor_south && fill_ver_south && (zdc_adc[0] > ZDC1cut) && (zdc_adc[2] > ZDC2cut) && (v[2] < veto_cut) && (v[3] < veto_cut))
0749     {
0750       smd_xy_south->Fill(smd_pos[3], smd_pos[2]);
0751       smd_hor_south_good->Fill(smd_pos[2]);
0752       smd_ver_south_good->Fill(smd_pos[3]);
0753     }
0754 
0755    
0756     if (fired_smd_hor_n && fired_smd_ver_n && !smd_ovld_north)
0757     {
0758       fill_hor_north = true;
0759       fill_ver_north = true;
0760       smd_hor_north->Fill(smd_pos[0]);
0761       smd_ver_north->Fill(smd_pos[1]);
0762       smd_sum_ver_north->Fill(smd_north_xsum);
0763       smd_sum_hor_north->Fill(smd_north_ysum);
0764       
0765     }
0766 
0767     if(fill_hor_north && fill_ver_north && (zdc_adc[8] > ZDC1cut) && (zdc_adc[10] > ZDC2cut) && (v[0] < veto_cut) && (v[1] < veto_cut))
0768     {
0769       smd_xy_north->Fill(smd_pos[1], smd_pos[0]);
0770       smd_hor_north_good->Fill(smd_pos[0]);
0771       smd_ver_north_good->Fill(smd_pos[1]);
0772     }
0773 
0774    
0775   }  // if packet good
0776 
0777   z.clear();
0778   sm.clear();
0779   tz.clear();
0780   tsmd.clear();
0781     
0782   delete p;
0783   return 0;
0784 }
0785 
0786 int ZdcMon::Reset()
0787 {
0788   // reset our internal counters
0789   evtcnt = 0;
0790   idummy = 0;
0791   return 0;
0792 }
0793 
0794 void ZdcMon::CompSmdAdc()  // mulitplying by relative gains
0795 {
0796   for (int i = 0; i < 15; i++)  // last one is reserved for analogue sum
0797   {
0798     // multiply SMD channels with their gain factors
0799     // to get the absolute ADC values in the same units
0800     //rgains come from CompSmdAdc()
0801     smd_adc[i] = smd_adc[i] * smd_north_rgain[i];            // sout -> north for PHENIX -> sPHENIX
0802     smd_adc[i + 16] = smd_adc[i + 16] * smd_south_rgain[i];  // north -> south for PHENIX-> sPHENIX
0803   }
0804 }
0805 
0806 void ZdcMon::CompSmdPos()  //computing position with weighted averages
0807 {
0808   float w_ave[4];  // 0 -> north hor; 1 -> noth vert; 2 -> south hor; 3 -> south vert.
0809   float weights[4] = {0};
0810   memset(weights, 0, sizeof(weights));  // memset float works only for 0
0811   float w_sum[4];
0812   memset(w_sum, 0, sizeof(w_sum));
0813 
0814   // these constants convert the SMD channel number into real dimensions (cm's)
0815   const float hor_scale = 2.0 * 11.0 / 10.5 * sin(PI / 4);  // from gsl_math.h
0816   const float ver_scale = 1.5 * 11.0 / 10.5;
0817   float hor_offset = (hor_scale * 8 / 2.0) * (7.0 / 8.0);
0818   float ver_offset = (ver_scale * 7 / 2.0) * (6.0 / 7.0);
0819 
0820   for (int i = 0; i < 8; i++)
0821   {
0822     weights[0] += smd_adc[i];  //summing weights
0823     weights[2] += smd_adc[i + 16];
0824     w_sum[0] += (float) i * smd_adc[i];  //summing for the average
0825     w_sum[2] += ((float) i + 16.) * smd_adc[i + 16];
0826   }
0827   for (int i = 0; i < 7; i++)
0828   {
0829     weights[1] += smd_adc[i + 8];
0830     weights[3] += smd_adc[i + 24];
0831     w_sum[1] += ((float) i + 8.) * smd_adc[i + 8];
0832     w_sum[3] += ((float) i + 24.) * smd_adc[i + 24];
0833   }
0834 
0835   if (weights[0] > 0.0)
0836   {
0837     w_ave[0] = w_sum[0] / weights[0];  //average = sum / sumn of weights...
0838     smd_pos[0] = hor_scale * w_ave[0] - hor_offset;
0839   }
0840   else
0841   {
0842     smd_pos[0] = 0;
0843   }
0844   if (weights[1] > 0.0)
0845   {
0846     w_ave[1] = w_sum[1] / weights[1];
0847     smd_pos[1] = ver_scale * (w_ave[1] - 8.0) - ver_offset;
0848   }
0849   else
0850   {
0851     smd_pos[1] = 0;
0852   }
0853 
0854   if (weights[2] > 0.0)
0855   {
0856     w_ave[2] = w_sum[2] / weights[2];
0857     smd_pos[2] = hor_scale * (w_ave[2] - 16.0) - hor_offset;
0858   }
0859   else
0860   {
0861     smd_pos[2] = 0;
0862   }
0863 
0864   if (weights[3] > 0.0)
0865   {
0866     w_ave[3] = w_sum[3] / weights[3];
0867     smd_pos[3] = ver_scale * (w_ave[3] - 24.0) - ver_offset;
0868   }
0869   else
0870   {
0871     smd_pos[3] = 0;
0872   }
0873 }
0874 
0875 
0876