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
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;
0029
0030
0031 long lastFitTime = 0;
0032 long lastModTime = 0;
0033 std::bitset<8> alive;
0034 int lsCount = 0;
0035 int currentLS = 0;
0036
0037
0038 DipFactory* dip;
0039 DipData* messageCMS;
0040 DipData* messageLHC;
0041 DipData* messagePV;
0042 DipPublication* publicationCMS;
0043 DipPublication* publicationLHC;
0044 DipPublication* publicationPV;
0045
0046
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);
0154
0155 return list;
0156 }
0157
0158
0159 void CMS2LHCRF_POS(float x, float y, float z) {
0160 if (x != 0) {
0161 double tmpx = x;
0162
0163 Centroid[0] = tmpx;
0164 Centroid[0] *= -1.0 * cm2um;
0165 } else
0166 Centroid[0] = x;
0167
0168 if (y != 0) {
0169 double tmpy = y;
0170
0171
0172
0173 Centroid[1] = tmpy;
0174 Centroid[1] *= cm2um;
0175 } else
0176 Centroid[1] = y;
0177
0178 if (z != 0) {
0179 double tmpz = z;
0180
0181
0182
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
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
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");
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
0232 messageLHC->insert(Size, 3, "Size");
0233 messageLHC->insert(Centroid, 3, "Centroid");
0234 messageLHC->insert(Tilt, 2, "Tilt");
0235
0236
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;
0299 zeit = DipTimestamp(epoch);
0300 } else
0301 zeit = DipTimestamp();
0302
0303
0304 if (updateCMS)
0305 publicationCMS->send(*messageCMS, zeit);
0306
0307 publicationLHC->send(*messageLHC, zeit);
0308 publicationPV->send(*messagePV, zeit);
0309
0310
0311
0312 if (qlty == qualities[0]) {
0313 if (updateCMS)
0314 publicationCMS->setQualityUncertain(err.c_str());
0315
0316 publicationLHC->setQualityUncertain(err.c_str());
0317 } else if (qlty == qualities[1]) {
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];
0371 else if (type >= 2)
0372 quality = qualities[2];
0373 else
0374 quality = qualities[1];
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
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))
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) {
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
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
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
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
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();
0636 publishRcd("UNINITIALIZED", "", true, false);
0637 } catch (exception& e) {
0638 cerr << "exception (start up): " << e.what() << endl;
0639 }
0640
0641 quality = qualities[0];
0642 }
0643
0644
0645 void endServer() {
0646
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
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
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 }