Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:06:49

0001 #include <iostream>
0002 #include <fstream>
0003 #include <sstream>
0004 #include <vector>
0005 #include <cmath>
0006 #include <cstring>
0007 #include <ctime>
0008 #include <sys/stat.h>
0009 #include <bitset>
0010 #include <unistd.h>
0011 
0012 //
0013 #include "Dip.h"
0014 #include "DipFactory.h"
0015 #include "DipPublication.h"
0016 #include "DipTimestamp.h"
0017 
0018 using namespace std;
0019 
0020 // constants
0021 const char* qualities[3] = {"Uncertain", "Bad", "Good"};
0022 const bool publishStatErrors = true;
0023 
0024 const int secPerLS = 23;
0025 const int rad2urad = 1000000;
0026 const int cm2um = 10000;
0027 const int cm2mm = 10;
0028 const int intLS = 1;  // for CMS scaler
0029 
0030 // variables
0031 long lastFitTime = 0;
0032 long lastModTime = 0;
0033 std::bitset<8> alive;
0034 int lsCount = 0;
0035 int currentLS = 0;
0036 
0037 // DIP objects
0038 DipFactory* dip;
0039 DipData* messageCMS;
0040 DipData* messageLHC;
0041 DipData* messagePV;
0042 DipPublication* publicationCMS;
0043 DipPublication* publicationLHC;
0044 DipPublication* publicationPV;
0045 
0046 // initial values of beamspot object
0047 int runnum;
0048 string startTime;
0049 string endTime;
0050 time_t startTimeStamp = 0;
0051 time_t endTimeStamp = 0;
0052 string lumiRange = "0 - 0";
0053 string quality = "Uncertain";
0054 int type = -1;
0055 float x = 0;
0056 float y = 0;
0057 float z = 0;
0058 float dxdz = 0;
0059 float dydz = 0;
0060 float err_x = 0;
0061 float err_y = 0;
0062 float err_z = 0;
0063 float err_dxdz = 0;
0064 float err_dydz = 0;
0065 float width_x = 0;
0066 float width_y = 0;
0067 float sigma_z = 0;
0068 float err_width_x = 0;
0069 float err_width_y = 0;
0070 float err_sigma_z = 0;
0071 
0072 //
0073 int events = 0;
0074 float meanPV = 0;
0075 float err_meanPV = 0;
0076 float rmsPV = 0;
0077 float err_rmsPV = 0;
0078 int maxPV = 0;
0079 int nPV = 0;
0080 
0081 //
0082 float Size[3];
0083 float Centroid[3];
0084 float Tilt[2];
0085 
0086 //
0087 bool verbose = false;
0088 bool testing = false;
0089 
0090 const string subjectCMS = "dip/CMS/Tracker/BeamSpot";
0091 const string subjectLHC = "dip/CMS/LHC/LuminousRegion";
0092 const string subjectPV = "dip/CMS/Tracker/PrimaryVertices";
0093 
0094 string sourceFile = "/nfshome0/dqmpro/BeamMonitorDQM/BeamFitResultsForDIP.txt";
0095 string sourceFile1 = "/nfshome0/dqmpro/BeamMonitorDQM/BeamFitResultsOld_TkStatus.txt";
0096 
0097 const int timeoutLS[2] = {1, 2};
0098 
0099 //
0100 
0101 /*****************************************************************************/
0102 string getDateTime(time_t t) {
0103   char mbstr[100];
0104   strftime(mbstr, sizeof(mbstr), "%Y.%m.%d %H:%M:%S %z", std::localtime(&t));
0105 
0106   return mbstr;
0107 }
0108 
0109 string getDateTime() {
0110   time_t t = time(nullptr);
0111 
0112   return getDateTime(t);
0113 }
0114 
0115 /*****************************************************************************/
0116 class ErrHandler : public DipPublicationErrorHandler {
0117 public:
0118   virtual ~ErrHandler() = default;
0119 
0120 private:
0121   void handleException(DipPublication* publication, DipException& e) override {
0122     cerr << "exception (create): " << e.what() << endl;
0123   }
0124 };
0125 
0126 /*****************************************************************************/
0127 long getFileSize(string filename) {
0128   struct stat stat_buf;
0129   int rc = stat(filename.c_str(), &stat_buf);
0130   return (rc == 0 ? stat_buf.st_size : -1);
0131 }
0132 
0133 /*****************************************************************************/
0134 time_t getLastTime(string filename) {
0135   struct stat stat_buf;
0136   int rc = stat(filename.c_str(), &stat_buf);
0137   return (rc == 0 ? stat_buf.st_mtime : -1);
0138 }
0139 
0140 /*****************************************************************************/
0141 vector<string> parse(string line, const string& delimiter) {
0142   vector<string> list;
0143 
0144   size_t pos = 0;
0145   while ((pos = line.find(delimiter)) != string::npos) {
0146     string token = line.substr(0, pos);
0147 
0148     list.push_back(token);
0149 
0150     line.erase(0, pos + delimiter.length());
0151   }
0152 
0153   list.push_back(line);  // remainder
0154 
0155   return list;
0156 }
0157 
0158 /*****************************************************************************/
0159 void CMS2LHCRF_POS(float x, float y, float z) {
0160   if (x != 0) {  // Rotation + Translation + Inversion + Scaling
0161     double tmpx = x;
0162     // x*rotY[0]*rotZ[0] + y*rotY[0]*rotZ[1] - z*rotY[1] + trans[0];
0163     Centroid[0] = tmpx;
0164     Centroid[0] *= -1.0 * cm2um;
0165   } else
0166     Centroid[0] = x;
0167 
0168   if (y != 0) {  // Rotation + Translation + Scaling
0169     double tmpy = y;
0170     // x*(rotX[1]*rotY[1]*rotZ[0] - rotX[0]*rotZ[1]) +
0171     // y*(rotX[0]*rotZ[0] + rotX[1]*rotY[1]*rotZ[1]) +
0172     // z*rotX[1]*rotY[0] + trans[1];
0173     Centroid[1] = tmpy;
0174     Centroid[1] *= cm2um;
0175   } else
0176     Centroid[1] = y;
0177 
0178   if (z != 0) {  // Rotation + Translation + Inversion + Scaling
0179     double tmpz = z;
0180     // x*(rotX[0]*rotY[1]*rotZ[0] + rotX[1]*rotZ[1]) +
0181     // y*(rotX[0]*rotY[1]*rotZ[1] - rotX[1]*rotZ[0]) +
0182     // z*rotX[0]*rotY[0] + trans[2];
0183     Centroid[2] = tmpz;
0184     Centroid[2] *= -1.0 * cm2mm;
0185   } else
0186     Centroid[2] = z;
0187 }
0188 
0189 /*****************************************************************************/
0190 void trueRcd() {
0191   try {
0192     // CMS to LHC RF
0193     CMS2LHCRF_POS(x, y, z);
0194 
0195     Tilt[0] = dxdz * rad2urad;
0196     Tilt[1] = (dydz != 0 ? (dydz * -1 * rad2urad) : 0);
0197 
0198     Size[0] = width_x * cm2um;
0199     Size[1] = width_y * cm2um;
0200     Size[2] = sigma_z * cm2mm;
0201 
0202     // CMS
0203     messageCMS->insert(runnum, "runnum");
0204     messageCMS->insert(startTime, "startTime");
0205     messageCMS->insert(endTime, "endTime");
0206     messageCMS->insert(startTimeStamp, "startTimeStamp");
0207     messageCMS->insert(endTimeStamp, "endTimeStamp");
0208     messageCMS->insert(lumiRange, "lumiRange");
0209     messageCMS->insert(quality, "quality");
0210     messageCMS->insert(type, "type");  // Unknown=-1, Fake=0, Tracker=2(Good)
0211     messageCMS->insert(x, "x");
0212     messageCMS->insert(y, "y");
0213     messageCMS->insert(z, "z");
0214     messageCMS->insert(dxdz, "dxdz");
0215     messageCMS->insert(dydz, "dydz");
0216     messageCMS->insert(width_x, "width_x");
0217     messageCMS->insert(width_y, "width_y");
0218     messageCMS->insert(sigma_z, "sigma_z");
0219 
0220     if (publishStatErrors) {
0221       messageCMS->insert(err_x, "err_x");
0222       messageCMS->insert(err_y, "err_y");
0223       messageCMS->insert(err_z, "err_z");
0224       messageCMS->insert(err_dxdz, "err_dxdz");
0225       messageCMS->insert(err_dydz, "err_dydz");
0226       messageCMS->insert(err_width_x, "err_width_x");
0227       messageCMS->insert(err_width_y, "err_width_y");
0228       messageCMS->insert(err_sigma_z, "err_sigma_z");
0229     }
0230 
0231     // LHC
0232     messageLHC->insert(Size, 3, "Size");
0233     messageLHC->insert(Centroid, 3, "Centroid");
0234     messageLHC->insert(Tilt, 2, "Tilt");
0235 
0236     // PV
0237     messagePV->insert(runnum, "runnum");
0238     messagePV->insert(startTime, "startTime");
0239     messagePV->insert(endTime, "endTime");
0240     messagePV->insert(startTimeStamp, "startTimeStamp");
0241     messagePV->insert(endTimeStamp, "endTimeStamp");
0242     messagePV->insert(lumiRange, "lumiRange");
0243     messagePV->insert(events, "events");
0244     messagePV->insert(meanPV, "meanPV");
0245     messagePV->insert(err_meanPV, "err_meanPV");
0246     messagePV->insert(rmsPV, "rmsPV");
0247     messagePV->insert(err_rmsPV, "err_rmsPV");
0248     messagePV->insert(maxPV, "maxPV");
0249     messagePV->insert(nPV, "nPV");
0250   } catch (exception& e) {
0251     cerr << "exception (trueRcd): " << e.what() << endl;
0252   }
0253 }
0254 
0255 /*****************************************************************************/
0256 void fakeRcd() {
0257   try {
0258     Centroid[0] = 0;
0259     Centroid[1] = 0;
0260     Centroid[2] = 0;
0261 
0262     Size[0] = 0;
0263     Size[1] = 0;
0264     Size[2] = 0;
0265 
0266     Tilt[0] = 0;
0267     Tilt[1] = 0;
0268 
0269     messageLHC->insert(Size, 3, "Size");
0270     messageLHC->insert(Centroid, 3, "Centroid");
0271     messageLHC->insert(Tilt, 2, "Tilt");
0272   } catch (exception& e) {
0273     cerr << "exception (fakeRcd): " << e.what() << endl;
0274   }
0275 }
0276 
0277 /*****************************************************************************/
0278 void publishRcd(string qlty, string err, bool pubCMS, bool fitTime) {
0279   try {
0280     bool updateCMS = pubCMS && (currentLS % intLS == 0);
0281 
0282     if (verbose) {
0283       cerr << "sending (" << qlty << " | " << err << ")";
0284 
0285       if (alive.test(7)) {
0286         if (updateCMS)
0287           cerr << " to CCC and CMS";
0288         else if (!alive.test(1) && !alive.test(2))
0289           cerr << " to CCC only";
0290       }
0291 
0292       cerr << endl;
0293     }
0294 
0295     DipTimestamp zeit;
0296     if (fitTime) {
0297       long epoch;
0298       epoch = endTimeStamp * 1000;  // convert to ms
0299       zeit = DipTimestamp(epoch);
0300     } else
0301       zeit = DipTimestamp();
0302 
0303     // send
0304     if (updateCMS)
0305       publicationCMS->send(*messageCMS, zeit);
0306 
0307     publicationLHC->send(*messageLHC, zeit);
0308     publicationPV->send(*messagePV, zeit);
0309 
0310     // set qualities
0311 
0312     if (qlty == qualities[0]) {  // Uncertain
0313       if (updateCMS)
0314         publicationCMS->setQualityUncertain(err.c_str());
0315 
0316       publicationLHC->setQualityUncertain(err.c_str());
0317     } else if (qlty == qualities[1]) {  // Bad
0318       if (updateCMS)
0319         publicationCMS->setQualityBad(err.c_str());
0320 
0321       publicationLHC->setQualityBad(err.c_str());
0322     } else if (qlty == "UNINITIALIZED") {
0323       if (updateCMS)
0324         publicationCMS->setQualityBad("UNINITIALIZED");
0325 
0326       publicationLHC->setQualityBad("UNINITIALIZED");
0327     }
0328   } catch (exception& e) {
0329     cerr << "exception (publishRcd): " << e.what() << endl;
0330   }
0331 }
0332 
0333 /*****************************************************************************/
0334 bool readRcd(ifstream& file) {
0335   int nthLnInRcd = 0;
0336   bool rcdQlty = false;
0337 
0338   try {
0339     string record;
0340     while (getline(file, record)) {
0341       nthLnInRcd++;
0342 
0343       vector<string> tmp = parse(record, " ");
0344 
0345       switch (nthLnInRcd) {
0346         case 1:
0347           if (record.rfind("Run", 0) != 0) {
0348             cerr << "Reading of results text file interrupted. " + getDateTime() << endl;
0349             return false;
0350           }
0351           runnum = stoi(tmp[1]);
0352           break;
0353         case 2:
0354           startTime = tmp[1] + " " + tmp[2] + " " + tmp[3];
0355           startTimeStamp = stol(tmp[4]);
0356           break;
0357         case 3:
0358           endTime = tmp[1] + " " + tmp[2] + " " + tmp[3];
0359           endTimeStamp = stol(tmp[4]);
0360           break;
0361         case 4:
0362           lumiRange = record.substr(10);
0363           if (verbose)
0364             cerr << "lumisection range: " + lumiRange << endl;
0365           currentLS = stoi(tmp[3]);
0366           break;
0367         case 5:
0368           type = stoi(tmp[1]);
0369           if (testing)
0370             quality = qualities[0];  // Uncertain
0371           else if (type >= 2)
0372             quality = qualities[2];  // Good
0373           else
0374             quality = qualities[1];  // Bad
0375           break;
0376 
0377         case 6:
0378           x = stof(tmp[1]);
0379           break;
0380         case 7:
0381           y = stof(tmp[1]);
0382           break;
0383         case 8:
0384           z = stof(tmp[1]);
0385           break;
0386 
0387         case 9:
0388           sigma_z = stof(tmp[1]);
0389           break;
0390         case 10:
0391           dxdz = stof(tmp[1]);
0392           break;
0393         case 11:
0394           dydz = stof(tmp[1]);
0395           break;
0396         case 12:
0397           width_x = stof(tmp[1]);
0398           break;
0399         case 13:
0400           width_y = stof(tmp[1]);
0401           break;
0402 
0403         case 14:
0404           err_x = sqrt(stof(tmp[1]));
0405           break;
0406         case 15:
0407           err_y = sqrt(stof(tmp[2]));
0408           break;
0409         case 16:
0410           err_z = sqrt(stof(tmp[3]));
0411           break;
0412         case 17:
0413           err_sigma_z = sqrt(stof(tmp[4]));
0414           break;
0415         case 18:
0416           err_dxdz = sqrt(stof(tmp[5]));
0417           break;
0418         case 19:
0419           err_dydz = sqrt(stof(tmp[6]));
0420           break;
0421         case 20:
0422           err_width_x = sqrt(stof(tmp[7]));
0423           err_width_y = err_width_x;
0424           break;
0425         case 21:
0426           break;
0427         case 22:
0428           break;
0429         case 23:
0430           break;
0431         case 24:
0432           events = stoi(tmp[1]);
0433           break;
0434 
0435         case 25:
0436           meanPV = stof(tmp[1]);
0437           break;
0438         case 26:
0439           err_meanPV = stof(tmp[1]);
0440           break;
0441         case 27:
0442           rmsPV = stof(tmp[1]);
0443           break;
0444         case 28:
0445           err_rmsPV = stof(tmp[1]);
0446           break;
0447         case 29:
0448           maxPV = stoi(tmp[1]);
0449           break;
0450         case 30:
0451           nPV = stoi(tmp[1]);
0452           rcdQlty = true;
0453           break;
0454 
0455         default:
0456           break;
0457       }
0458     }
0459 
0460     file.close();
0461   } catch (exception& e) {
0462     cerr << "io exception (readRcd): " << e.what() << endl;
0463   }
0464 
0465   return rcdQlty;
0466 }
0467 
0468 /*****************************************************************************/
0469 string tkStatus() {
0470   string outstr;
0471 
0472   ifstream logfile(sourceFile1);
0473 
0474   if (!logfile.good() || getFileSize(sourceFile1) == 0) {
0475     // file does not exist or has zero size
0476     outstr = "No CMS Tracker status available. No DAQ/DQM.";
0477   } else {
0478     int nthLnInRcd = 0;
0479     string record;
0480 
0481     try {
0482       string record;
0483 
0484       while (getline(logfile, record)) {
0485         nthLnInRcd++;
0486         vector<string> tmp = parse(record, " ");
0487 
0488         switch (nthLnInRcd) {
0489           case 7:
0490             if (tmp[1].find("Yes") == string::npos)
0491               outstr = "CMS Tracker OFF.";
0492             else
0493               outstr = "CMS not taking data or no beam.";
0494             break;
0495           case 8:
0496             runnum = stoi(tmp[1]);
0497             break;
0498           default:
0499             break;
0500         }
0501       }
0502     } catch (exception& e) {
0503       cerr << "exception (tkStatus): " << e.what() << endl;
0504     }
0505   }
0506 
0507   logfile.close();
0508 
0509   return outstr;
0510 }
0511 
0512 /*****************************************************************************/
0513 void problem() {
0514   if (verbose)
0515     cerr << "no update | alive = " << alive << endl;
0516 
0517   lsCount++;
0518 
0519   if ((lsCount % (timeoutLS[0] * secPerLS) == 0) && (lsCount % (timeoutLS[1] * secPerLS) != 0))  // first timeout
0520   {
0521     if (!alive.test(1))
0522       alive.flip(1);
0523     if (!alive.test(2)) {
0524       if (!alive.test(7))
0525         fakeRcd();
0526       else
0527         trueRcd();
0528 
0529       stringstream warnMsg;
0530       warnMsg << "No new data for " << lsCount << " LS";
0531       publishRcd("Uncertain", warnMsg.str(), false, false);
0532     } else {
0533       fakeRcd();
0534 
0535       stringstream warnMsg;
0536       warnMsg << "No new data for " << lsCount << " LS: " << tkStatus();
0537       publishRcd("Bad", warnMsg.str(), false, false);
0538     }
0539   } else if (lsCount % (timeoutLS[1] * secPerLS) == 0) {  // second timeout
0540     if (!alive.test(2))
0541       alive.flip(2);
0542     fakeRcd();
0543 
0544     stringstream warnMsg;
0545     warnMsg << "No new data for " << lsCount << " LS: " << tkStatus();
0546     publishRcd("Bad", warnMsg.str(), false, false);
0547   }
0548 }
0549 
0550 /*****************************************************************************/
0551 void polling() {
0552   try {
0553     ifstream logFile(sourceFile);
0554 
0555     if (!logFile.good()) {
0556       cerr << "Source File: " + sourceFile + " doesn't exist!" << endl;
0557       problem();
0558     } else {
0559       lastModTime = getLastTime(sourceFile);
0560 
0561       if (lastFitTime == 0)
0562         lastFitTime = lastModTime;
0563 
0564       if (getFileSize(sourceFile) == 0) {
0565         // source file has zero length
0566         if (lastModTime > lastFitTime) {
0567           string tmp = tkStatus();
0568           cerr << "New run starts. Run number: " << runnum << endl;
0569           if (verbose)
0570             cerr << "Initial lastModTime = " + getDateTime(lastModTime) << endl;
0571         }
0572         lastFitTime = lastModTime;
0573       }
0574 
0575       if (lastModTime > lastFitTime) {
0576         // source file modified
0577         if (verbose) {
0578           cerr << "time of last fit    = " + getDateTime(lastFitTime) << endl;
0579           cerr << "time of current fit = " + getDateTime(lastModTime) << endl;
0580         }
0581         lastFitTime = lastModTime;
0582 
0583         // source file length > 0
0584         if (getFileSize(sourceFile) > 0) {
0585           if (verbose)
0586             cerr << "reading record from " + sourceFile << endl;
0587 
0588           if (readRcd(logFile)) {
0589             if (verbose)
0590               cerr << "got new record from file" << endl;
0591 
0592             trueRcd();
0593             alive.reset();
0594             alive.flip(7);
0595           } else {
0596             if (verbose)
0597               cerr << "problem with new record" << endl;
0598             fakeRcd();
0599           }
0600 
0601           lsCount = 0;
0602         }
0603       } else {
0604         // source file not touched
0605         problem();
0606       }
0607     }
0608 
0609     logFile.close();
0610 
0611   } catch (exception& e) {
0612     cerr << "io exception (end of lumi): " << e.what() << endl;
0613   };
0614 }
0615 
0616 /*****************************************************************************/
0617 void beginServer() {
0618   try {
0619     ErrHandler errHandler;
0620 
0621     cerr << "server started at " + getDateTime() << endl;
0622 
0623     cerr << "creating publication " + subjectCMS << endl;
0624     publicationCMS = dip->createDipPublication(subjectCMS.c_str(), &errHandler);
0625     messageCMS = dip->createDipData();
0626 
0627     cerr << "creating publication " + subjectLHC << endl;
0628     publicationLHC = dip->createDipPublication(subjectLHC.c_str(), &errHandler);
0629     messageLHC = dip->createDipData();
0630 
0631     cerr << "creating publication " + subjectPV << endl;
0632     publicationPV = dip->createDipPublication(subjectPV.c_str(), &errHandler);
0633     messagePV = dip->createDipData();
0634 
0635     trueRcd();  // starts with all 0
0636     publishRcd("UNINITIALIZED", "", true, false);
0637   } catch (exception& e) {
0638     cerr << "exception (start up): " << e.what() << endl;
0639   }
0640 
0641   quality = qualities[0];  // start with Uncertain
0642 }
0643 
0644 /*****************************************************************************/
0645 void endServer() {
0646   // destroy publications and data
0647   cerr << "destroying publication " + subjectCMS << endl;
0648   dip->destroyDipPublication(publicationCMS);
0649   delete messageCMS;
0650 
0651   cerr << "destroying publication " + subjectLHC << endl;
0652   dip->destroyDipPublication(publicationLHC);
0653   delete messageLHC;
0654 
0655   cerr << "destroying publication " + subjectPV << endl;
0656   dip->destroyDipPublication(publicationPV);
0657   delete messagePV;
0658 }
0659 
0660 /*****************************************************************************/
0661 int main(int narg, char* args[]) {
0662   // options
0663   verbose = strcmp(args[1], "true");
0664   testing = strcmp(args[2], "true");
0665 
0666   sourceFile = args[3];
0667   sourceFile1 = args[4];
0668 
0669   //
0670   startTime = getDateTime();
0671   endTime = getDateTime();
0672 
0673   dip = Dip::create("CmsBeamSpotServer");
0674   // Use both CMS-based DIM DNS server (https://its.cern.ch/jira/browse/CMSOMS-280)
0675   dip->setDNSNode("cmsdimns1.cern.ch,cmsdimns2.cern.ch");
0676 
0677   cerr << "reading from file (NFS)" << endl;
0678 
0679   //
0680   beginServer();
0681 
0682   cerr << "entering polling loop" << endl;
0683 
0684   while (true) {
0685     polling();
0686     sleep(1);
0687   }
0688 
0689   cerr << "[done]" << endl;
0690 
0691   //
0692   endServer();
0693 
0694   return 0;
0695 }