Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-02 02:22:50

0001 /*
0002  * =====================================================================================
0003  *
0004  *       Filename:  Summary.cc
0005  *
0006  *    Description:  Class Summary implementation
0007  *
0008  *        Version:  1.0
0009  *        Created:  05/19/2008 10:59:34 AM
0010  *       Revision:  none
0011  *       Compiler:  gcc
0012  *
0013  *         Author:  Valdas Rapsevicius (VR), Valdas.Rapsevicius@cern.ch
0014  *        Company:  CERN, CH
0015  *
0016  * =====================================================================================
0017  */
0018 
0019 #include "CSCDQM_Summary.h"
0020 
0021 namespace cscdqm {
0022 
0023   /**
0024    * @brief  Constructor
0025    */
0026   Summary::Summary() : detector(NTICS, NTICS) { Reset(); }
0027 
0028   /**
0029    * @brief  Destructor
0030    */
0031   Summary::~Summary() {}
0032 
0033   /**
0034    * @brief  Resets all detector map
0035    */
0036   void Summary::Reset() {
0037     Address adr;
0038     bzero(&adr, sizeof(Address));
0039 
0040     /**  Setting Zeros (no data) for each HW element (and beyond) */
0041     adr.mask.side = adr.mask.station = adr.mask.layer = false;
0042     adr.mask.ring = adr.mask.chamber = adr.mask.cfeb = adr.mask.hv = true;
0043     for (adr.ring = 1; adr.ring <= N_RINGS; adr.ring++) {
0044       for (adr.chamber = 1; adr.chamber <= N_CHAMBERS; adr.chamber++) {
0045         for (adr.cfeb = 1; adr.cfeb <= N_CFEBS; adr.cfeb++) {
0046           for (adr.hv = 1; adr.hv <= N_HVS; adr.hv++) {
0047             for (unsigned int bit = 0; bit < HWSTATUSBITSETSIZE; bit++) {
0048               ReSetValue(adr, (HWStatusBit)bit);
0049             }
0050           }
0051         }
0052       }
0053     }
0054   }
0055 
0056   /**
0057    * @brief  Read Reporting Chamber histogram and fill in detector map.
0058    * @param  h2 Histogram to read
0059    * @param  threshold Min bin value to set HW element as reporting 
0060    */
0061   void Summary::ReadReportingChambers(const TH2*& h2, const double threshold) {
0062     if (h2->GetXaxis()->GetXmin() <= 1 && h2->GetXaxis()->GetXmax() >= 36 && h2->GetYaxis()->GetXmin() <= 1 &&
0063         h2->GetYaxis()->GetXmax() >= 18) {
0064       Address adr;
0065       bzero(&adr, sizeof(Address));
0066       double z = 0.0;
0067 
0068       for (unsigned int x = 1; x <= 36; x++) {
0069         for (unsigned int y = 1; y <= 18; y++) {
0070           z = h2->GetBinContent(x, y);
0071           if (ChamberCoordsToAddress(x, y, adr)) {
0072             if (z >= threshold) {
0073               SetValue(adr, DATA);
0074             } else {
0075               ReSetValue(adr, DATA);
0076             }
0077           }
0078         }
0079       }
0080     } else {
0081       LOG_WARN << "cscdqm::Summary.ReadReportingChambers routine. Wrong histogram dimensions!";
0082     }
0083   }
0084 
0085   /**
0086    * @brief  Read Reporting Chamber histogram and fill in detector map based on
0087    * reference histogram.
0088    * @param  h2 Histogram to read
0089    * @param  refh2 Reference histogram of hit occupancies
0090    * @param  cold_coef Minimum tolerance of difference (rate) to set COLD (not reporting) HW element
0091    * @param  cold_Sfail Significance threshold for COLD HW element
0092    * @param  hot_coef Minimum tolerance of difference (rate) to set HOT HW element
0093    * @param  hot_Sfail Significance threshold for HOT HW element
0094    */
0095   void Summary::ReadReportingChambersRef(const TH2*& h2,
0096                                          const TH2*& refh2,
0097                                          const double cold_coef,
0098                                          const double cold_Sfail,
0099                                          const double hot_coef,
0100                                          const double hot_Sfail) {
0101     if (h2->GetXaxis()->GetXmin() <= 1 && h2->GetXaxis()->GetXmax() >= 36 && h2->GetYaxis()->GetXmin() <= 1 &&
0102         h2->GetYaxis()->GetXmax() >= 18 && refh2->GetXaxis()->GetXmin() <= 1 && refh2->GetXaxis()->GetXmax() >= 36 &&
0103         refh2->GetYaxis()->GetXmin() <= 1 && refh2->GetYaxis()->GetXmax() >= 18) {
0104       /**  Rate Factor calculation */
0105       double num = 1.0, denum = 1.0;
0106       for (unsigned int x = 1; x <= 36; x++) {
0107         for (unsigned int y = 1; y <= 18; y++) {
0108           double Nij = h2->GetBinContent(x, y);
0109           double Nrefij = refh2->GetBinContent(x, y);
0110           if (Nij > 0) {
0111             num += Nrefij;
0112             denum += pow(Nrefij, 2.0) / Nij;
0113           }
0114         }
0115       }
0116       double factor = num / denum;
0117 
0118       Address adr;
0119       bzero(&adr, sizeof(Address));
0120       unsigned int N = 0, n = 0;
0121 
0122       for (unsigned int x = 1; x <= 36; x++) {
0123         for (unsigned int y = 1; y <= 18; y++) {
0124           N = int(refh2->GetBinContent(x, y) * factor);
0125           n = int(h2->GetBinContent(x, y));
0126 
0127           if (ChamberCoordsToAddress(x, y, adr)) {
0128             /**  Reset some bits */
0129             ReSetValue(adr, HOT);
0130             ReSetValue(adr, COLD);
0131 
0132             if (n == 0) {
0133               ReSetValue(adr, DATA);
0134             } else {
0135               SetValue(adr, DATA);
0136             }
0137 
0138             switch (Utility::checkOccupancy(N, n, cold_coef, hot_coef, cold_Sfail, hot_Sfail)) {
0139               case -1:
0140                 SetValue(adr, COLD);
0141 
0142                 /*
0143             std::cout << "adr = " << detector.AddressName(adr);
0144             std::cout << ", x = " << x << ", y = " << y;
0145             std::cout << ", value = " << GetValue(adr);
0146             std::cout << ", refh2 = " << refh2->GetBinContent(x, y);
0147             std::cout << ", factor = " << factor;
0148             std::cout << ", N = " << N;
0149             std::cout << ", n = " << n;
0150             std::cout << ", num = " << num;
0151             std::cout << ", denum = " << denum;
0152             std::cout << ", rate = " << (N > 0 ? n / N : 0);
0153             std::cout << ", cold_coef = " << cold_coef;
0154             std::cout << ", = COLD";
0155             std::cout << "\n";
0156               */
0157 
0158                 break;
0159               case 1:
0160                 SetValue(adr, HOT);
0161 
0162                 /*
0163             std::cout << "adr = " << detector.AddressName(adr);
0164             std::cout << ", x = " << x << ", y = " << y;
0165             std::cout << ", value = " << GetValue(adr);
0166             std::cout << ", refh2 = " << refh2->GetBinContent(x, y);
0167             std::cout << ", factor = " << factor;
0168             std::cout << ", N = " << N;
0169             std::cout << ", n = " << n;
0170             std::cout << ", num = " << num;
0171             std::cout << ", denum = " << denum;
0172             std::cout << ", rate = " << (N > 0 ? n / N : 0);
0173             std::cout << ", hot_coef = " << hot_coef;
0174             std::cout << ", = HOT";
0175             std::cout << "\n";
0176               */
0177 
0178                 break;
0179             };
0180           }
0181         }
0182       }
0183 
0184     } else {
0185       LOG_WARN << "cscdqm::Summary.ReadReportingChambersRef routine. Wrong histogram dimensions!";
0186     }
0187   }
0188 
0189   /**
0190    * @brief  Read Error data for Chambers
0191    * @param  evs Histogram for number of events (total)
0192    * @param  err Histogram for number of errors
0193    * @param  bit Error bit to set
0194    * @param  eps_max Maximum tolerance of errors (rate)
0195    * @param  Sfail Significance threshold for failure report
0196    */
0197   void Summary::ReadErrorChambers(
0198       const TH2*& evs, const TH2*& err, const HWStatusBit bit, const double eps_max, const double Sfail) {
0199     if (evs->GetXaxis()->GetXmin() <= 1 && evs->GetXaxis()->GetXmax() >= 36 && evs->GetYaxis()->GetXmin() <= 1 &&
0200         evs->GetYaxis()->GetXmax() >= 18 && err->GetXaxis()->GetXmin() <= 1 && err->GetXaxis()->GetXmax() >= 36 &&
0201         err->GetYaxis()->GetXmin() <= 1 && err->GetYaxis()->GetXmax() >= 18) {
0202       Address adr;
0203       bzero(&adr, sizeof(Address));
0204       unsigned int N = 0, n = 0;
0205 
0206       for (unsigned int x = 1; x <= 36; x++) {
0207         for (unsigned int y = 1; y <= 18; y++) {
0208           N = int(evs->GetBinContent(x, y));
0209           n = int(err->GetBinContent(x, y));
0210           if (ChamberCoordsToAddress(x, y, adr)) {
0211             if (Utility::checkError(N, n, eps_max, Sfail)) {
0212               SetValue(adr, bit);
0213             } else {
0214               ReSetValue(adr, bit);
0215             }
0216           }
0217         }
0218       }
0219     } else {
0220       LOG_WARN << "cscdqm::Summary.ReadErrorChambers routine. Wrong histogram dimensions!";
0221     }
0222   }
0223 
0224   /**
0225    * @brief  Write detector map to H1 histogram (linear data) for the selected adr.station
0226    * @param  h2 Histogram to write data to
0227    * @param  station station number (1-4) to write data for
0228    */
0229   void Summary::Write(TH2*& h2, const unsigned int station) const {
0230     const AddressBox* box;
0231     Address adr, tadr;
0232     bzero(&adr, sizeof(Address));
0233     bzero(&tadr, sizeof(Address));
0234     float area_all = 0.0, area_rep = 0.0;
0235 
0236     if (station < 1 || station > N_STATIONS)
0237       return;
0238 
0239     adr.mask.side = adr.mask.ring = adr.mask.chamber = adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0240     adr.mask.station = true;
0241     adr.station = station;
0242 
0243     unsigned int i = 0;
0244 
0245     while (detector.NextAddressBox(i, box, adr)) {
0246       unsigned int x = 1 + (box->adr.side - 1) * 9 + (box->adr.ring - 1) * 3 + (box->adr.hv - 1);
0247       unsigned int y = 1 + (box->adr.chamber - 1) * 5 + (box->adr.cfeb - 1);
0248 
0249       tadr = box->adr;
0250       HWStatusBitSet status = GetValue(tadr);
0251 
0252       float area_box = fabs((box->xmax - box->xmin) * (box->ymax - box->ymin));
0253 
0254       if (status.test(MASKED)) {
0255         h2->SetBinContent(x, y, 2.0);
0256       } else {
0257         area_all += area_box;
0258         if (HWSTATUSANYERROR(status)) {
0259           h2->SetBinContent(x, y, -1.0);
0260         } else {
0261           area_rep += area_box;
0262           if (status.test(DATA)) {
0263             h2->SetBinContent(x, y, 1.0);
0264           } else {
0265             h2->SetBinContent(x, y, 0.0);
0266           }
0267         }
0268       }
0269     }
0270 
0271     TString title = Form("ME%d Status: Physics Efficiency %.2f%%", station, (area_rep / area_all) * 100.0);
0272     h2->SetTitle(title);
0273   }
0274 
0275   /**
0276    * @brief  Write PhysicsReady Map to H2 histogram
0277    * @param  h2 Histogram to write map to
0278    */
0279   void Summary::WriteMap(TH2*& h2) {
0280     unsigned int rep_el = 0, csc_el = 0;
0281 
0282     if (h2->GetXaxis()->GetXmin() <= 1 && h2->GetXaxis()->GetXmax() >= NTICS && h2->GetYaxis()->GetXmin() <= 1 &&
0283         h2->GetYaxis()->GetXmax() >= NTICS) {
0284       float xd = 5.0 / NTICS;
0285 
0286       float xmin, xmax;
0287 
0288       for (unsigned int x = 0; x < NTICS; x++) {
0289         xmin = -2.5 + xd * x;
0290         xmax = xmin + xd;
0291 
0292         for (unsigned int y = 0; y < NTICS; y++) {
0293           double value = 0.0;
0294 
0295           if (xmin == -2.5 || xmax == 2.5)
0296             continue;
0297           if (xmin >= -1 && xmax <= 1)
0298             continue;
0299 
0300           switch (IsPhysicsReady(x, y)) {
0301             case -1:
0302               value = -1.0;
0303               break;
0304             case 0:
0305               value = 0.0;
0306               rep_el++;
0307               break;
0308             case 1:
0309               value = 1.0;
0310               rep_el++;
0311               break;
0312             case 2:
0313               value = 2.0;
0314               rep_el++;
0315           }
0316 
0317           h2->SetBinContent(x + 1, y + 1, value);
0318           csc_el++;
0319         }
0320       }
0321 
0322     } else {
0323       LOG_WARN << "cscdqm::Summary.WriteMap routine. Wrong histogram dimensions!";
0324     }
0325 
0326     TString title =
0327         Form("EMU Status: Physics Efficiency %.2f%%", (csc_el == 0 ? 0.0 : (1.0 * rep_el) / csc_el) * 100.0);
0328     h2->SetTitle(title);
0329   }
0330 
0331   /**
0332    * @brief  Write State information to chamber histogram
0333    * @param  h2 histogram to write to
0334    * @param  mask mask of errors to check while writing
0335    * @param  value to write to if state fits mask
0336    * @param  reset should all chamber states be reseted to 0 prior writing?
0337    * @param  op_any Should chamber be marked as errorous on any bit in mask? false - for all.
0338    */
0339   void Summary::WriteChamberState(TH2*& h2, const int mask, const int value, const bool reset, const bool op_any) const {
0340     if (h2->GetXaxis()->GetXmin() <= 1 && h2->GetXaxis()->GetXmax() >= 36 && h2->GetYaxis()->GetXmin() <= 1 &&
0341         h2->GetYaxis()->GetXmax() >= 18) {
0342       unsigned int x, y;
0343       Address adr;
0344       bzero(&adr, sizeof(Address));
0345 
0346       adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = true;
0347       adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0348 
0349       for (adr.side = 1; adr.side <= N_SIDES; adr.side++) {
0350         for (adr.station = 1; adr.station <= N_STATIONS; adr.station++) {
0351           for (adr.ring = 1; adr.ring <= detector.NumberOfRings(adr.station); adr.ring++) {
0352             for (adr.chamber = 1; adr.chamber <= detector.NumberOfChambers(adr.station, adr.ring); adr.chamber++) {
0353               if (ChamberAddressToCoords(adr, x, y)) {
0354                 HWStatusBitSet hwValue = GetValue(adr);
0355                 bool hit = (op_any ? HWSTATUSANY(hwValue, mask) : HWSTATUSEQUALS(hwValue, mask));
0356 
0357                 // std::cout << "x = " << x << ", y = " << y << ", value = " << GetValue(adr) << std::endl;
0358                 // std::cout << "adr = " << detector.AddressName(adr) << ", x = " << x << ", y = " << y << ", value = " << GetValue(adr) << std::endl;
0359                 if (hit) {
0360                   h2->SetBinContent(x, y, 1.0 * value);
0361                 } else if (reset) {
0362                   h2->SetBinContent(x, y, 0.0);
0363                 }
0364               }
0365             }
0366           }
0367         }
0368       }
0369 
0370     } else {
0371       LOG_WARN << "cscdqm::Summary.WriteChamberState routine. Wrong histogram dimensions!";
0372     }
0373   }
0374 
0375   /**
0376    * @brief  ReSetValue for the whole of detector
0377    * @param  bit Status bit to set
0378    */
0379   void Summary::ReSetValue(const HWStatusBit bit) { SetValue(bit, 0); }
0380 
0381   /**
0382    * @brief  ReSet value recursivelly by following the supplied address
0383    * @param  adr Address to be updated
0384    * @param  bit Status bit to set
0385    */
0386   void Summary::ReSetValue(const Address& adr, const HWStatusBit bit) { SetValue(adr, bit, 0); }
0387 
0388   /**
0389    * @brief  SetValue for the whole of detector
0390    * @param  bit Status bit to set
0391    * @param  value Value to set
0392    */
0393   void Summary::SetValue(const HWStatusBit bit, const int value) {
0394     Address adr;
0395     bzero(&adr, sizeof(Address));
0396     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = adr.mask.layer = adr.mask.cfeb = adr.mask.hv =
0397         false;
0398     SetValue(adr, bit, value);
0399   }
0400 
0401   /**
0402    * @brief  Set value recursivelly by following the supplied address
0403    * @param  adr Address to be updated
0404    * @param  bit Status bit to set
0405    * @param  value Value to be set
0406    */
0407   void Summary::SetValue(Address adr, const HWStatusBit bit, const int value) {
0408     if (!adr.mask.side) {
0409       adr.mask.side = true;
0410       for (adr.side = 1; adr.side <= N_SIDES; adr.side++)
0411         SetValue(adr, bit, value);
0412       return;
0413     }
0414 
0415     if (!adr.mask.station) {
0416       adr.mask.station = true;
0417       for (adr.station = 1; adr.station <= N_STATIONS; adr.station++)
0418         SetValue(adr, bit, value);
0419       return;
0420     }
0421 
0422     if (!adr.mask.ring) {
0423       adr.mask.ring = true;
0424       for (adr.ring = 1; adr.ring <= detector.NumberOfRings(adr.station); adr.ring++)
0425         SetValue(adr, bit, value);
0426       return;
0427     }
0428 
0429     if (!adr.mask.chamber) {
0430       adr.mask.chamber = true;
0431       for (adr.chamber = 1; adr.chamber <= detector.NumberOfChambers(adr.station, adr.ring); adr.chamber++)
0432         SetValue(adr, bit, value);
0433       return;
0434     }
0435 
0436     if (!adr.mask.layer) {
0437       adr.mask.layer = true;
0438       for (adr.layer = 1; adr.layer <= N_LAYERS; adr.layer++)
0439         SetValue(adr, bit, value);
0440       return;
0441     }
0442 
0443     if (!adr.mask.cfeb) {
0444       adr.mask.cfeb = true;
0445       for (adr.cfeb = 1; adr.cfeb <= detector.NumberOfChamberCFEBs(adr.station, adr.ring); adr.cfeb++)
0446         SetValue(adr, bit, value);
0447       return;
0448     }
0449 
0450     if (!adr.mask.hv) {
0451       adr.mask.hv = true;
0452       for (adr.hv = 1; adr.hv <= detector.NumberOfChamberHVs(adr.station, adr.ring); adr.hv++)
0453         SetValue(adr, bit, value);
0454       return;
0455     }
0456 
0457     if (adr.side > 0 && adr.side <= N_SIDES && adr.station > 0 && adr.station <= N_STATIONS && adr.ring > 0 &&
0458         adr.ring <= N_RINGS && adr.chamber > 0 && adr.chamber <= N_CHAMBERS && adr.layer > 0 && adr.layer <= N_LAYERS &&
0459         adr.cfeb > 0 && adr.cfeb <= N_CFEBS && adr.hv > 0 && adr.hv <= N_HVS) {
0460       map[adr.side - 1][adr.station - 1][adr.ring - 1][adr.chamber - 1][adr.layer - 1][adr.cfeb - 1][adr.hv - 1].set(
0461           bit, value);
0462     }
0463   }
0464 
0465   /**
0466    * @brief  Check if the current partition element (aka eta/phi polygon) has at least 2 active HW
0467    * elements in the area
0468    * @param  px partition element index in x axis
0469    * @param  py partition element index in y axis
0470    * @return 1 if this polygon is ok for physics and reporting, 0 - if it is ok
0471    * but does not report, -1 - otherwise
0472    */
0473   const int Summary::IsPhysicsReady(const unsigned int px, const unsigned int py) {
0474     AddressBox* box;
0475 
0476     HWStatusBitSet status[N_STATIONS];
0477 
0478     unsigned int i = 0;
0479     while (detector.NextAddressBoxByPartition(i, px, py, box)) {
0480       status[box->adr.station - 1] |= GetValue(box->adr);
0481     }
0482 
0483     unsigned int cdata = 0, cerror = 0, cmask = 0;
0484     for (unsigned int i = 0; i < N_STATIONS; i++) {
0485       if (HWSTATUSANYERROR(status[i])) {
0486         cerror++;
0487       } else {
0488         if (status[i].test(MASKED))
0489           cmask++;
0490         if (status[i].test(DATA))
0491           cdata++;
0492       }
0493     }
0494 
0495     /**  If at least 2 stations with data and without errors = OK */
0496     if (cdata > 1)
0497       return 1;
0498     /**  Else, if at least one station errorous = ERROR */
0499     if (cerror > 0)
0500       return -1;
0501     /**  Else, if at least one station masked = MASKED */
0502     if (cmask > 0)
0503       return 2;
0504     /**  Else, not sufficient data = OK */
0505     return 0;
0506   }
0507 
0508   /**
0509    * @brief  Get efficiency of the whole detector
0510    * @return Detector efficiency rate (0..1)
0511    */
0512   const double Summary::GetEfficiencyHW() const {
0513     Address adr;
0514     bzero(&adr, sizeof(Address));
0515     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = adr.mask.layer = adr.mask.cfeb = adr.mask.hv =
0516         false;
0517     return GetEfficiencyHW(adr);
0518   }
0519 
0520   /**
0521    * @brief  Get efficiency of the station
0522    * @param  station Station number
0523    * @return Detector efficiency rate (0..1)
0524    */
0525   const double Summary::GetEfficiencyHW(const unsigned int station) const {
0526     Address adr;
0527     bzero(&adr, sizeof(Address));
0528     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = adr.mask.layer = adr.mask.cfeb = adr.mask.hv =
0529         false;
0530 
0531     if (station > 0 && station <= N_STATIONS) {
0532       adr.mask.station = true;
0533       adr.station = station;
0534     } else {
0535       return 0.0;
0536     }
0537 
0538     return GetEfficiencyHW(adr);
0539   }
0540 
0541   /**
0542    * @brief  Get efficiency of the detector part supplied by the address
0543    * @param  adr Address to watch efficiency for
0544    * @return Subdetector efficiency rate (0..1)
0545    */
0546   const double Summary::GetEfficiencyHW(Address adr) const {
0547     double sum = 0.0;
0548     if (!adr.mask.side) {
0549       adr.mask.side = true;
0550       for (adr.side = 1; adr.side <= N_SIDES; adr.side++)
0551         sum += GetEfficiencyHW(adr);
0552       return sum / N_SIDES;
0553     }
0554 
0555     if (!adr.mask.station) {
0556       adr.mask.station = true;
0557       for (adr.station = 1; adr.station <= N_STATIONS; adr.station++)
0558         sum += GetEfficiencyHW(adr);
0559       return sum / N_STATIONS;
0560     }
0561 
0562     if (!adr.mask.ring) {
0563       adr.mask.ring = true;
0564       for (adr.ring = 1; adr.ring <= detector.NumberOfRings(adr.station); adr.ring++)
0565         sum += GetEfficiencyHW(adr);
0566       return sum / detector.NumberOfRings(adr.station);
0567     }
0568 
0569     if (!adr.mask.chamber) {
0570       adr.mask.chamber = true;
0571       for (adr.chamber = 1; adr.chamber <= detector.NumberOfChambers(adr.station, adr.ring); adr.chamber++)
0572         sum += GetEfficiencyHW(adr);
0573       return sum / detector.NumberOfChambers(adr.station, adr.ring);
0574     }
0575 
0576     if (!adr.mask.layer) {
0577       adr.mask.layer = true;
0578       for (adr.layer = 1; adr.layer <= N_LAYERS; adr.layer++)
0579         sum += GetEfficiencyHW(adr);
0580       return sum / N_LAYERS;
0581     }
0582 
0583     if (!adr.mask.cfeb) {
0584       adr.mask.cfeb = true;
0585       for (adr.cfeb = 1; adr.cfeb <= detector.NumberOfChamberCFEBs(adr.station, adr.ring); adr.cfeb++)
0586         sum += GetEfficiencyHW(adr);
0587       return sum / detector.NumberOfChamberCFEBs(adr.station, adr.ring);
0588     }
0589 
0590     if (!adr.mask.hv) {
0591       adr.mask.hv = true;
0592       for (adr.hv = 1; adr.hv <= detector.NumberOfChamberHVs(adr.station, adr.ring); adr.hv++)
0593         sum += GetEfficiencyHW(adr);
0594       return sum / detector.NumberOfChamberHVs(adr.station, adr.ring);
0595     }
0596 
0597     /**  if not error - then OK! */
0598     HWStatusBitSet status = GetValue(adr);
0599     if (HWSTATUSANYERROR(status))
0600       return 0.0;
0601     return 1.0;
0602   }
0603 
0604   /**
0605    * @brief  Get Efficiency area for the station
0606    * @param  station Station number 1..4
0607    * @return Reporting Area for the Station
0608    */
0609   const double Summary::GetEfficiencyArea(const unsigned int station) const {
0610     if (station <= 0 || station > N_STATIONS)
0611       return 0.0;
0612 
0613     Address adr;
0614     bzero(&adr, sizeof(Address));
0615     adr.mask.side = adr.mask.ring = adr.mask.chamber = adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0616     adr.mask.station = true;
0617     adr.station = station;
0618 
0619     return GetEfficiencyArea(adr);
0620   }
0621 
0622   /**
0623    * @brief  Get Efficiency area for the address
0624    * @param  adr Address
0625    * @return Area in eta/phi space
0626    */
0627   const double Summary::GetEfficiencyArea(const Address& adr) const {
0628     double all_area = 1;
0629 
0630     if ((adr.mask.side == false) && (adr.mask.ring == false) && (adr.mask.chamber == false) &&
0631         (adr.mask.layer == false) && (adr.mask.cfeb == false) && (adr.mask.hv == false) && (adr.mask.station == true))
0632       all_area = detector.Area(adr.station);
0633     else
0634       all_area = detector.Area(adr);
0635 
0636     double rep_area = GetReportingArea(adr);
0637     return rep_area / all_area;
0638   }
0639 
0640   /**
0641    * @brief  Calculate the reporting area for the address
0642    * @param  adr Address to calculate
0643    * @return Area in eta/phi space
0644    */
0645   const double Summary::GetReportingArea(Address adr) const {
0646     double sum = 0.0;
0647     if (!adr.mask.side) {
0648       adr.mask.side = true;
0649       for (adr.side = 1; adr.side <= N_SIDES; adr.side++)
0650         sum += GetReportingArea(adr);
0651       return sum;
0652     }
0653 
0654     if (!adr.mask.station) {
0655       adr.mask.station = true;
0656       for (adr.station = 1; adr.station <= N_STATIONS; adr.station++)
0657         sum += GetReportingArea(adr);
0658       return sum;
0659     }
0660 
0661     if (!adr.mask.ring) {
0662       adr.mask.ring = true;
0663       for (adr.ring = 1; adr.ring <= detector.NumberOfRings(adr.station); adr.ring++)
0664         sum += GetReportingArea(adr);
0665       return sum;
0666     }
0667 
0668     if (!adr.mask.chamber) {
0669       adr.mask.chamber = true;
0670       for (adr.chamber = 1; adr.chamber <= detector.NumberOfChambers(adr.station, adr.ring); adr.chamber++)
0671         sum += GetReportingArea(adr);
0672       return sum;
0673     }
0674 
0675     if (!adr.mask.cfeb) {
0676       adr.mask.cfeb = true;
0677       for (adr.cfeb = 1; adr.cfeb <= detector.NumberOfChamberCFEBs(adr.station, adr.ring); adr.cfeb++)
0678         sum += GetReportingArea(adr);
0679       return sum;
0680     }
0681 
0682     if (!adr.mask.hv) {
0683       adr.mask.hv = true;
0684       for (adr.hv = 1; adr.hv <= detector.NumberOfChamberHVs(adr.station, adr.ring); adr.hv++)
0685         sum += GetReportingArea(adr);
0686       return sum;
0687     }
0688 
0689     adr.mask.layer = false;
0690 
0691     /**  NOT errorous!  */
0692     HWStatusBitSet status = GetValue(adr);
0693     if (!HWSTATUSANYERROR(status)) {
0694       return detector.Area(adr);
0695     }
0696     return 0.0;
0697   }
0698 
0699   /**
0700    * @brief  Check if chamber is in standby?
0701    * @param  side Side
0702    * @param  station Station
0703    * @param  ring Ring
0704    * @param  chamber Chamber
0705    * @return true if chamber is in standby, false - otherwise
0706    */
0707   bool Summary::isChamberStandby(unsigned int side,
0708                                  unsigned int station,
0709                                  unsigned int ring,
0710                                  unsigned int chamber) const {
0711     Address adr;
0712     bzero(&adr, sizeof(Address));
0713     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = true;
0714     adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0715     adr.side = side;
0716     adr.station = station;
0717     adr.ring = ring;
0718     adr.chamber = chamber;
0719 
0720     //std::cout << adr << " = " << HWSTATUSANY(GetValue(adr), 0x1000) << "\n";
0721 
0722     return HWSTATUSANY(GetValue(adr), 0x1000);
0723   }
0724 
0725   /**
0726    * @brief  Check if chamber is in standby?
0727    * @param  cid Chamber identifier
0728    * @return true if chamber is in standby, false - otherwise
0729    */
0730   bool Summary::isChamberStandby(CSCDetId cid) const {
0731     return isChamberStandby(cid.endcap(), cid.station(), cid.ring(), cid.chamber());
0732   }
0733 
0734   /**
0735    * @brief  Get value of some address 
0736    * @param  adr Address of atomic element to return value from
0737    * @return Value of the requested element
0738    */
0739   const HWStatusBitSet Summary::GetValue(Address adr) const {
0740     HWStatusBitSet state;
0741     state.reset();
0742 
0743     if (!adr.mask.side) {
0744       adr.mask.side = true;
0745       for (adr.side = 1; adr.side <= N_SIDES; adr.side++)
0746         state |= GetValue(adr);
0747       return state;
0748     }
0749 
0750     if (!adr.mask.station) {
0751       adr.mask.station = true;
0752       for (adr.station = 1; adr.station <= N_STATIONS; adr.station++)
0753         state |= GetValue(adr);
0754       return state;
0755     }
0756 
0757     if (!adr.mask.ring) {
0758       adr.mask.ring = true;
0759       for (adr.ring = 1; adr.ring <= detector.NumberOfRings(adr.station); adr.ring++)
0760         state |= GetValue(adr);
0761       return state;
0762     }
0763 
0764     if (!adr.mask.chamber) {
0765       adr.mask.chamber = true;
0766       for (adr.chamber = 1; adr.chamber <= detector.NumberOfChambers(adr.station, adr.ring); adr.chamber++)
0767         state |= GetValue(adr);
0768       return state;
0769     }
0770 
0771     if (!adr.mask.layer) {
0772       adr.mask.layer = true;
0773       for (adr.layer = 1; adr.layer <= N_LAYERS; adr.layer++)
0774         state |= GetValue(adr);
0775       return state;
0776     }
0777 
0778     if (!adr.mask.cfeb) {
0779       adr.mask.cfeb = true;
0780       for (adr.cfeb = 1; adr.cfeb <= detector.NumberOfChamberCFEBs(adr.station, adr.ring); adr.cfeb++)
0781         state |= GetValue(adr);
0782       return state;
0783     }
0784 
0785     if (!adr.mask.hv) {
0786       adr.mask.hv = true;
0787       for (adr.hv = 1; adr.hv <= detector.NumberOfChamberHVs(adr.station, adr.ring); adr.hv++)
0788         state |= GetValue(adr);
0789       return state;
0790     }
0791 
0792     return map[adr.side - 1][adr.station - 1][adr.ring - 1][adr.chamber - 1][adr.layer - 1][adr.cfeb - 1][adr.hv - 1];
0793   }
0794 
0795   /**
0796    * @brief  Read HW element masks (strings), create Address and apply to detector map
0797    * @param  tokens Vector of mask strings
0798    * @return number of read and applied masks
0799    */
0800   const unsigned int Summary::setMaskedHWElements(std::vector<std::string>& tokens) {
0801     unsigned int applied = 0;
0802 
0803     for (unsigned int r = 0; r < tokens.size(); r++) {
0804       std::string token = (std::string)tokens.at(r);
0805       Address adr;
0806       if (detector.AddressFromString(token, adr)) {
0807         SetValue(adr, MASKED);
0808         applied++;
0809       }
0810     }
0811     return applied;
0812   }
0813 
0814   /**
0815    * @brief  Calculate Address from CSCChamberMap histogram coordinates 
0816    * @param  x X coordinate of histogram
0817    * @param  y Y coordinate of histogram
0818    * @param  adr Address to be filled in and returned
0819    * @return true if address was found and filled, false - otherwise
0820    */
0821   const bool Summary::ChamberCoordsToAddress(const unsigned int x, const unsigned int y, Address& adr) const {
0822     if (x < 1 || x > 36 || y < 1 || y > 18)
0823       return false;
0824 
0825     adr.mask.side = adr.mask.station = adr.mask.ring = adr.mask.chamber = true;
0826     adr.mask.layer = adr.mask.cfeb = adr.mask.hv = false;
0827 
0828     if (y < 10)
0829       adr.side = 2;
0830     else
0831       adr.side = 1;
0832 
0833     adr.chamber = x;
0834 
0835     if (y == 1 || y == 18) {
0836       adr.station = 4;
0837       adr.ring = 2;
0838     } else if (y == 2 || y == 17) {
0839       adr.station = 4;
0840       adr.ring = 1;
0841     } else if (y == 3 || y == 16) {
0842       adr.station = 3;
0843       adr.ring = 2;
0844     } else if (y == 4 || y == 15) {
0845       adr.station = 3;
0846       adr.ring = 1;
0847     } else if (y == 5 || y == 14) {
0848       adr.station = 2;
0849       adr.ring = 2;
0850     } else if (y == 6 || y == 13) {
0851       adr.station = 2;
0852       adr.ring = 1;
0853     } else if (y == 7 || y == 12) {
0854       adr.station = 1;
0855       adr.ring = 3;
0856     } else if (y == 8 || y == 11) {
0857       adr.station = 1;
0858       adr.ring = 2;
0859     } else if (y == 9 || y == 10) {
0860       adr.station = 1;
0861       adr.ring = 1;
0862     }
0863 
0864     return true;
0865   }
0866 
0867   /**
0868    * @brief  Calculate CSCChamberMap histogram coordinates from Address
0869    * @param  adr Address
0870    * @param  x X coordinate of histogram to be returned
0871    * @param  y Y coordinate of histogram to be returned
0872    * @return true if coords filled, false - otherwise
0873    */
0874   const bool Summary::ChamberAddressToCoords(const Address& adr, unsigned int& x, unsigned int& y) const {
0875     if (!adr.mask.side || !adr.mask.station || !adr.mask.ring || !adr.mask.chamber)
0876       return false;
0877 
0878     x = adr.chamber;
0879     y = 0;
0880 
0881     if (adr.side == 1) {
0882       switch (adr.station) {
0883         case 1:
0884           y = 10;
0885           if (adr.ring == 2)
0886             y = 11;
0887           if (adr.ring == 3)
0888             y = 12;
0889           break;
0890         case 2:
0891           y = 13;
0892           if (adr.ring == 2)
0893             y = 14;
0894           break;
0895         case 3:
0896           y = 15;
0897           if (adr.ring == 2)
0898             y = 16;
0899           break;
0900         case 4:
0901           y = 17;
0902           if (adr.ring == 2)
0903             y = 18;
0904           break;
0905       }
0906     } else if (adr.side == 2) {
0907       switch (adr.station) {
0908         case 1:
0909           y = 7;
0910           if (adr.ring == 2)
0911             y = 8;
0912           if (adr.ring == 1)
0913             y = 9;
0914           break;
0915         case 2:
0916           y = 5;
0917           if (adr.ring == 1)
0918             y = 6;
0919           break;
0920         case 3:
0921           y = 3;
0922           if (adr.ring == 1)
0923             y = 4;
0924           break;
0925         case 4:
0926           y = 1;
0927           if (adr.ring == 1)
0928             y = 2;
0929           break;
0930       }
0931     }
0932 
0933     return true;
0934   }
0935 
0936 }  // namespace cscdqm