File indexing completed on 2025-12-18 09:17:54
0001 #include "XingShiftCal.h"
0002
0003 #include <cdbobjects/CDBTTree.h>
0004
0005 #include <fun4all/DBInterface.h>
0006
0007 #include <fun4all/Fun4AllReturnCodes.h>
0008
0009 #include <phool/getClass.h>
0010 #include <phool/phool.h>
0011 #include <phool/recoConsts.h>
0012
0013 #include <Event/Event.h>
0014 #include <Event/EventTypes.h>
0015 #include <Event/packet.h>
0016
0017 #include <TCanvas.h>
0018 #include <TH1.h>
0019
0020 #include <odbc++/resultset.h>
0021 #include <odbc++/statement.h>
0022
0023 #include <format>
0024 #include <iostream>
0025 #include <memory>
0026
0027 XingShiftCal::XingShiftCal(const std::string &name, const int poverwriteSpinEntry)
0028 : SubsysReco(name)
0029 , nevt(0)
0030 , overwriteSpinEntry(poverwriteSpinEntry)
0031 {
0032
0033
0034 for (auto &scalercount : scalercounts)
0035 {
0036 for (unsigned long &j : scalercount)
0037 {
0038 j = 0;
0039 }
0040 }
0041
0042 std::cout << "XingShiftCal::XingShiftCal(const std::string &name) Calling ctor" << std::endl;
0043 }
0044
0045 int XingShiftCal::Init(PHCompositeNode * )
0046 {
0047 std::cout << "XingShiftCal::Init(PHCompositeNode *topNode) Initializing" << std::endl;
0048 preset_pattern_blue["111x111_P1"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0049 preset_pattern_yellow["111x111_P1"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0050 preset_pattern_blue["111x111_P2"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0051 preset_pattern_yellow["111x111_P2"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0052 preset_pattern_blue["111x111_P3"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0053 preset_pattern_yellow["111x111_P3"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0054 preset_pattern_blue["111x111_P4"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0055 preset_pattern_yellow["111x111_P4"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0056 preset_pattern_blue["111x111_P5"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0057 preset_pattern_yellow["111x111_P5"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0058 preset_pattern_blue["111x111_P6"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0059 preset_pattern_yellow["111x111_P6"] = "+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+--+-++-+-+-+--+-+-+-++-+*********";
0060 preset_pattern_blue["111x111_P7"] = "++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++-*********";
0061 preset_pattern_yellow["111x111_P7"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0062 preset_pattern_blue["111x111_P8"] = "--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--+*********";
0063 preset_pattern_yellow["111x111_P8"] = "-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-++-+--+-+-+-++-+-+-+--+-*********";
0064
0065 return Fun4AllReturnCodes::EVENT_OK;
0066 }
0067
0068 int XingShiftCal::InitRun(PHCompositeNode * )
0069 {
0070
0071
0072 recoConsts *rc = recoConsts::instance();
0073 runnumber = rc->get_IntFlag("RUNNUMBER");
0074 return Fun4AllReturnCodes::EVENT_OK;
0075 }
0076
0077 int XingShiftCal::process_event(PHCompositeNode *topNode)
0078 {
0079 if (done == 1)
0080 {
0081 return Fun4AllReturnCodes::EVENT_OK;
0082 }
0083
0084 Event *evt = findNode::getClass<Event>(topNode, "PRDF");
0085
0086 if (evt->getEvtType() == BEGRUNEVENT)
0087 {
0088
0089 pBluePol = evt->getPacket(packet_BLUEPOL);
0090 pYellPol = evt->getPacket(packet_YELLPOL);
0091
0092 pBlueIntPattern = evt->getPacket(packet_BLUEINTPATTERN);
0093 pYellIntPattern = evt->getPacket(packet_YELLINTPATTERN);
0094 pBluePolPattern = evt->getPacket(packet_BLUEPOLPATTERN);
0095 pYellPolPattern = evt->getPacket(packet_YELLPOLPATTERN);
0096
0097 pBlueAsym = evt->getPacket(packet_BLUEASYM);
0098 pYellAsym = evt->getPacket(packet_YELLASYM);
0099
0100 pBlueFillNumber = evt->getPacket(packet_BLUEFILLNUMBER);
0101 pYellFillNumber = evt->getPacket(packet_YELLFILLNUMBER);
0102
0103
0104
0105 polBlue = -999;
0106 polBlueErr = -999;
0107 if (pBluePol)
0108 {
0109 polBlue = pBluePol->iValue(0) / 10000.0;
0110 polBlueErr = pBluePol->iValue(1) / 10000.0;
0111 delete pBluePol;
0112 }
0113
0114 polYellow = -999;
0115 polYellowErr = -999;
0116 if (pYellPol)
0117 {
0118 polYellow = pYellPol->iValue(0) / 10000.0;
0119 polYellowErr = pYellPol->iValue(1) / 10000.0;
0120 delete pYellPol;
0121 }
0122
0123
0124
0125
0126
0127 if (pBlueIntPattern && pBluePolPattern)
0128 {
0129 for (int i = 0; i < 360; i += 3)
0130 {
0131 blueFillPattern[i / 3] = pBlueIntPattern->iValue(i);
0132 if (pBlueIntPattern->iValue(i))
0133 {
0134 blueSpinPattern[i / 3] = pBluePolPattern->iValue(i);
0135 }
0136 else
0137 {
0138 blueSpinPattern[i / 3] = 10;
0139 }
0140 }
0141 delete pBlueIntPattern;
0142 delete pBluePolPattern;
0143 }
0144
0145 if (pYellIntPattern && pYellPolPattern)
0146 {
0147 for (int i = 0; i < 360; i += 3)
0148 {
0149 yellFillPattern[i / 3] = pYellIntPattern->iValue(i);
0150 if (pYellIntPattern->iValue(i))
0151 {
0152 yellSpinPattern[i / 3] = pYellPolPattern->iValue(i);
0153 }
0154 else
0155 {
0156 yellSpinPattern[i / 3] = 10;
0157 }
0158 }
0159 delete pYellIntPattern;
0160 delete pYellPolPattern;
0161 }
0162
0163
0164
0165
0166
0167
0168 if (pBlueAsym)
0169 {
0170 for (int i = 0; i < 360; i += 3)
0171 {
0172 float blueAsyms = pBlueAsym->iValue(i) / 10000.0;
0173 float blueAsymsErr = pBlueAsym->iValue(i + 360) / 10000.0;
0174
0175 float bluebot = blueAsyms - blueAsymsErr;
0176 float bluetop = blueAsyms + blueAsymsErr;
0177
0178 if (blueAsyms != 0 || bluebot != 0 || bluetop != 0)
0179 {
0180 if (bluebot > 0 && bluetop > 0)
0181 {
0182 bluePcSpinPattern[i / 3] = 1;
0183 }
0184 else if (bluebot < 0 && bluetop < 0)
0185 {
0186 bluePcSpinPattern[i / 3] = -1;
0187 }
0188 else if (bluebot <= 0 && bluetop >= 0)
0189 {
0190 bluePcSpinPattern[i / 3] = 0;
0191 }
0192 }
0193 else
0194 {
0195 bluePcSpinPattern[i / 3] = 10;
0196 }
0197 }
0198 delete pBlueAsym;
0199 }
0200
0201 if (pYellAsym)
0202 {
0203 for (int i = 0; i < 360; i += 3)
0204 {
0205 float yellAsyms = pYellAsym->iValue(i) / 10000.0;
0206 float yellAsymsErr = pYellAsym->iValue(i + 360) / 10000.0;
0207
0208 float yellbot = yellAsyms - yellAsymsErr;
0209 float yelltop = yellAsyms + yellAsymsErr;
0210
0211 if (yellAsyms != 0 || yellbot != 0 || yelltop != 0)
0212 {
0213 if (yellbot > 0 && yelltop > 0)
0214 {
0215 yellPcSpinPattern[i / 3] = 1;
0216 }
0217 else if (yellbot < 0 && yelltop < 0)
0218 {
0219 yellPcSpinPattern[i / 3] = -1;
0220 }
0221 else if (yellbot <= 0 && yelltop >= 0)
0222 {
0223 yellPcSpinPattern[i / 3] = 0;
0224 }
0225 }
0226 else
0227 {
0228 yellPcSpinPattern[i / 3] = 10;
0229 }
0230 }
0231 delete pYellAsym;
0232 }
0233
0234
0235
0236 fillnumberBlue = 0;
0237 fillnumberYellow = 0;
0238 if (pBlueFillNumber)
0239 {
0240 fillnumberBlue = pBlueFillNumber->iValue(0);
0241 delete pBlueFillNumber;
0242 }
0243 if (pYellFillNumber)
0244 {
0245 fillnumberYellow = pYellFillNumber->iValue(0);
0246 delete pYellFillNumber;
0247 }
0248
0249 }
0250 else if (evt->getEvtType() == DATAEVENT)
0251 {
0252 p = evt->getPacket(packet_GL1);
0253 int bunchnr = p->lValue(0, "BunchNumber");
0254
0255 for (int i = 0; i < NTRIG; i++)
0256 {
0257
0258 long gl1pscaler = p->lValue(i, "GL1PLIVE");
0259 scalercounts[i][bunchnr] = gl1pscaler;
0260 }
0261 delete p;
0262 }
0263
0264 if (nevt > threshold)
0265 {
0266 Calibrate();
0267 if (success)
0268 {
0269 done = 1;
0270 }
0271 else
0272 {
0273 threshold += threshold;
0274 }
0275 }
0276
0277 if (nevt > evtcap)
0278 {
0279 done = 1;
0280 }
0281
0282 nevt++;
0283
0284 return Fun4AllReturnCodes::EVENT_OK;
0285 }
0286
0287 int XingShiftCal::End(PHCompositeNode * )
0288 {
0289 std::cout << "XingShiftCal::End(PHCompositeNode *topNode) This is the End..." << std::endl;
0290
0291 if (done)
0292 {
0293
0294 Calibrate(1);
0295
0296
0297 }
0298 else
0299 {
0300 success = false;
0301 std::cout << "Not enough statistics. Did not calibrate." << std::endl;
0302 }
0303
0304 const std::string cdbfname = std::format("SPIN-{:08}_crossingshiftCDBTTree.root", runnumber);
0305 WriteToCDB(cdbfname);
0306 CommitToSpinDB();
0307
0308 if (commitSuccessCDB)
0309 {
0310 std::cout << "Commit to CDB : SUCCESS" << std::endl;
0311 }
0312 else
0313 {
0314 std::cout << "Commit to CDB : FAILURE" << std::endl;
0315 }
0316
0317 if (commitSuccessSpinDB)
0318 {
0319 std::cout << "Commit to SpinDB : SUCCESS" << std::endl;
0320 }
0321 else
0322 {
0323 std::cout << "Commit to SpinDB : FAILURE" << std::endl;
0324 }
0325
0326 return Fun4AllReturnCodes::EVENT_OK;
0327 }
0328
0329 int XingShiftCal::Calibrate(const int final)
0330 {
0331 CalculateCrossingShift(xingshift, scalercounts, success);
0332 if (!success)
0333 {
0334 std::cout << "CROSSING CALIBRATION FAILED." << std::endl;
0335 if (final)
0336 {
0337 std::cout << "DONE CALIBRATING." << std::endl;
0338 }
0339 return 0;
0340 }
0341
0342 if (final)
0343 {
0344
0345 std::cout << "CROSSING CALIBRATION SUCCESS. XINGSHIFT: " << xingshift << std::endl;
0346 std::cout << "DONE CALIBRATING." << std::endl;
0347
0348 }
0349
0350 return 0;
0351 }
0352
0353 int XingShiftCal::CalculateCrossingShift(int &xing, uint64_t counts[NTRIG][NBUNCHES], bool &succ)
0354 {
0355 succ = false;
0356 int shift_array[NTRIG] = {0};
0357
0358 int trig_inactive_array[NTRIG] = {0};
0359
0360 int last_active_index = 0;
0361
0362 int _temp;
0363 for (int itrig = 0; itrig < NTRIG; itrig++)
0364 {
0365 long long _counts = 0;
0366 for (int ii = 0; ii < NBUNCHES; ii++)
0367 {
0368 _counts += counts[itrig][ii];
0369 }
0370
0371 if (_counts < 10000)
0372 {
0373 trig_inactive_array[itrig] = 1;
0374 }
0375 else
0376 {
0377 last_active_index = itrig;
0378 }
0379
0380 long long abort_sum_prev = _counts;
0381
0382 _temp = 0;
0383 for (int ishift = 0; ishift < NBUNCHES; ishift++)
0384 {
0385 long long abort_sum = 0;
0386 for (int iunfillbunch = 0; iunfillbunch < NBUNCHES; iunfillbunch++)
0387 {
0388 if (blueFillPattern[iunfillbunch] && yellFillPattern[iunfillbunch])
0389 {
0390 continue;
0391 }
0392 int shiftbunch = iunfillbunch - ishift;
0393 if (shiftbunch < 0)
0394 {
0395 shiftbunch = 120 + shiftbunch;
0396 }
0397 abort_sum += counts[itrig][(shiftbunch) % NBUNCHES];
0398 }
0399 if (abort_sum < abort_sum_prev)
0400 {
0401 abort_sum_prev = abort_sum;
0402 _temp = ishift;
0403 }
0404 }
0405
0406 shift_array[itrig] = _temp;
0407 }
0408
0409 for (int itrig = 0; itrig < NTRIG; itrig++)
0410 {
0411
0412 if (!trig_inactive_array[itrig])
0413 {
0414 if (shift_array[itrig] == shift_array[last_active_index])
0415 {
0416 xing = shift_array[itrig];
0417 succ = true;
0418 }
0419 else
0420 {
0421 xing = -999;
0422 succ = false;
0423 return 0;
0424 }
0425 }
0426 }
0427
0428
0429 return 0;
0430 }
0431
0432 int XingShiftCal::WriteToCDB(const std::string &fname)
0433 {
0434 std::cout << "XingShiftCal::WriteToCDB()" << std::endl;
0435 int xing_correction_offset = 0;
0436 if (success)
0437 {
0438 xing_correction_offset = xingshift;
0439 CDBTTree *cdbttree = new CDBTTree(fname);
0440 cdbttree->SetSingleIntValue("crossingshift", xing_correction_offset);
0441 cdbttree->CommitSingle();
0442
0443 cdbttree->WriteCDBTTree();
0444 delete cdbttree;
0445
0446 commitSuccessCDB = 1;
0447 }
0448 else
0449 {
0450
0451 std::cout << "no successful calibration, do not commit crossing shift to CDB" << std::endl;
0452
0453 commitSuccessCDB = 0;
0454 }
0455
0456 return 0;
0457 }
0458
0459
0460 int XingShiftCal::CommitToSpinDB()
0461 {
0462 std::cout << "XingShiftCal::CommitPatternToSpinDB()" << std::endl;
0463
0464 if (runnumber == 0)
0465 {
0466 std::cout << "Run doesn't exist" << std::endl;
0467 commitSuccessSpinDB = 0;
0468 return 0;
0469 }
0470
0471 if (fillnumberBlue != fillnumberYellow)
0472 {
0473 std::cout << "fillnumber is wrong : fillnumberBlue = " << fillnumberBlue
0474 << "fillnumberYellow = " << fillnumberYellow << std::endl;
0475 commitSuccessSpinDB = 0;
0476 return 0;
0477 }
0478
0479 int xing_correction_offset = -999;
0480 if (success)
0481 {
0482 xing_correction_offset = xingshift;
0483 }
0484 else
0485 {
0486
0487 std::cout << "no successful calibration, commit crossing shift -999 to spinDB" << std::endl;
0488
0489
0490 commitSuccessSpinDB = 0;
0491
0492 }
0493
0494
0495 unsigned int qa_level = 0xffff;
0496
0497
0498 std::string daqdbname = "daq";
0499
0500 std::string sqlGL1PSelect = "SELECT index, bunch, scaled FROM gl1_pscalers WHERE runnumber = " + std::to_string(runnumber);
0501 odbc::Statement *stmtGL1PSelect = DBInterface::instance()->getStatement(daqdbname);
0502 std::unique_ptr<odbc::ResultSet> rsGL1P;
0503 try
0504 {
0505 rsGL1P = std::unique_ptr<odbc::ResultSet>(stmtGL1PSelect->executeQuery(sqlGL1PSelect));
0506 }
0507 catch (odbc::SQLException &eGL1P)
0508 {
0509 std::cout << PHWHERE
0510 << " Exception caught at XingShiftCal::CommitPatternToSpinDB when querying DAQ DB" << std::endl;
0511 std::cout << "Message: " << eGL1P.getMessage() << std::endl;
0512
0513 return 0;
0514 }
0515
0516 while (rsGL1P->next())
0517 {
0518 int index = rsGL1P->getInt("index");
0519 int bunch = rsGL1P->getInt("bunch");
0520
0521 if (index == 0)
0522 {
0523 mbdns[bunch] = rsGL1P->getInt("scaled");
0524 }
0525 else if (index == 1)
0526 {
0527 mbdvtx[bunch] = rsGL1P->getInt("scaled");
0528 }
0529 else if (index == 5)
0530 {
0531 zdcns[bunch] = rsGL1P->getInt("scaled");
0532 }
0533 }
0534
0535
0536
0537
0538 std::cout << "polb = " << polBlue << " +- " << polBlueErr
0539 << std::endl
0540 << "poly = " << polYellow << " +- " << polYellowErr
0541 << std::endl;
0542
0543
0544 if (true )
0545 {
0546 for (int ibeam = 0; ibeam < 2; ibeam++)
0547 {
0548 if (!ibeam)
0549 {
0550 std::cout << "spinpatternblue = {";
0551 }
0552 else
0553 {
0554 std::cout << "spinpatternyellow = {";
0555 }
0556 for (int icross = 0; icross < NBUNCHES; icross++)
0557 {
0558 if (!ibeam)
0559 {
0560 std::cout << blueSpinPattern[icross] << ",";
0561 }
0562 else
0563 {
0564 std::cout << yellSpinPattern[icross] << ",";
0565 }
0566 }
0567 std::cout << "\b}\n";
0568 }
0569 }
0570
0571 if (true)
0572 {
0573 for (int i = 0; i < 3; i++)
0574 {
0575 if (i == 0)
0576 {
0577 std::cout << "mbdns = {";
0578 }
0579 else if (i == 1)
0580 {
0581 std::cout << "mbdvtx = {";
0582 }
0583 else if (i == 2)
0584 {
0585 std::cout << "zdcns = {";
0586 }
0587 for (int icross = 0; icross < NBUNCHES; icross++)
0588 {
0589 if (i == 0)
0590 {
0591 std::cout << mbdns[icross] << ",";
0592 }
0593 else if (i == 1)
0594 {
0595 std::cout << mbdvtx[icross] << ",";
0596 }
0597 else if (i == 2)
0598 {
0599 std::cout << zdcns[icross] << ",";
0600 }
0601 }
0602 std::cout << "\b}\n";
0603 }
0604 }
0605
0606
0607 std::string dbname = "spinDB_write";
0608 std::string dbtable = "spin";
0609
0610
0611
0612 bool runExists = false;
0613 std::string sqlSpinSelect = "SELECT runnumber, qa_level FROM " + dbtable + " WHERE runnumber = " + std::to_string(runnumber) + " AND qa_level = " + std::to_string(qa_level);
0614
0615
0616 odbc::Statement *stmtSpinSelect = DBInterface::instance()->getStatement(dbname);
0617 std::unique_ptr<odbc::ResultSet> rsSpin;
0618 try
0619 {
0620 rsSpin = std::unique_ptr<odbc::ResultSet>(stmtSpinSelect->executeQuery(sqlSpinSelect));
0621 }
0622 catch (odbc::SQLException &e)
0623 {
0624 std::cout << PHWHERE
0625 << " Exception caught at XingShiftCal::CommitPatternToSpinDB when querying spin DB" << std::endl;
0626 std::cout << "Message: " << e.getMessage() << std::endl;
0627 commitSuccessSpinDB = 0;
0628 return 0;
0629 }
0630 if (rsSpin->next())
0631 {
0632 if (true )
0633 {
0634 std::cout << "run " << runnumber << " exists in " << dbtable
0635 << ", ready to UPDATE" << std::endl;
0636 }
0637 runExists = true;
0638 }
0639 else
0640 {
0641 if (true )
0642 {
0643 std::cout << "run " << runnumber << " NOT exists in " << dbtable
0644 << ", ready to INSERT" << std::endl;
0645 }
0646 }
0647
0648 if (runExists && !overwriteSpinEntry)
0649 {
0650 std::cout << "BUT overwriteSpinEntry = " << overwriteSpinEntry << std::endl;
0651 std::cout << "XingShiftCal is NOT going to UPDATE the entry" << std::endl;
0652 commitSuccessSpinDB = 0;
0653 return 0;
0654 }
0655
0656
0657 std::ostringstream sql;
0658 if (runExists)
0659 {
0660
0661 sql << "UPDATE " << dbtable
0662 << " SET fillnumber = " << fillnumberBlue << ", "
0663 << "polarblue = " << SQLArrayConstF(polBlue, NBUNCHES) << ", "
0664 << "polarblueerror = " << SQLArrayConstF(polBlueErr, NBUNCHES) << ", "
0665 << "polaryellow = " << SQLArrayConstF(polYellow, NBUNCHES) << ", "
0666 << "polaryellowerror = " << SQLArrayConstF(polYellowErr, NBUNCHES) << ", "
0667 << "crossingshift = " << xing_correction_offset << ", ";
0668 sql << "spinpatternblue = '{";
0669 for (int icross = 0; icross < NBUNCHES; icross++)
0670 {
0671 sql << blueSpinPattern[icross];
0672 if (icross < NBUNCHES - 1)
0673 {
0674 sql << ",";
0675 }
0676 }
0677 sql << "}'";
0678 sql << ", spinpatternyellow = '{";
0679 for (int icross = 0; icross < NBUNCHES; icross++)
0680 {
0681 sql << yellSpinPattern[icross];
0682 if (icross < NBUNCHES - 1)
0683 {
0684 sql << ",";
0685 }
0686 }
0687 sql << "}'";
0688
0689 sql << ", mbdns = '{";
0690 for (int icross = 0; icross < NBUNCHES; icross++)
0691 {
0692 sql << mbdns[icross];
0693 if (icross < NBUNCHES - 1)
0694 {
0695 sql << ",";
0696 }
0697 }
0698 sql << "}'";
0699
0700 sql << ", mbdvtx = '{";
0701 for (int icross = 0; icross < NBUNCHES; icross++)
0702 {
0703 sql << mbdvtx[icross];
0704 if (icross < NBUNCHES - 1)
0705 {
0706 sql << ",";
0707 }
0708 }
0709 sql << "}'";
0710
0711 sql << ", zdcns = '{";
0712 for (int icross = 0; icross < NBUNCHES; icross++)
0713 {
0714 sql << zdcns[icross];
0715 if (icross < NBUNCHES - 1)
0716 {
0717 sql << ",";
0718 }
0719 }
0720 sql << "}'";
0721
0722 sql << " WHERE runnumber = " << runnumber
0723 << " AND qa_level = " << qa_level
0724 << ";";
0725 }
0726 else
0727 {
0728 sql << "INSERT INTO " << dbtable;
0729 sql << " (runnumber, fillnumber, polarblue, polarblueerror, polaryellow, polaryellowerror, crossingshift, spinpatternblue, spinpatternyellow, mbdns, mbdvtx, zdcns, qa_level) VALUES (";
0730 sql << runnumber << ", "
0731 << fillnumberBlue << ", "
0732 << SQLArrayConstF(polBlue, NBUNCHES) << ", "
0733 << SQLArrayConstF(polBlueErr, NBUNCHES) << ", "
0734 << SQLArrayConstF(polYellow, NBUNCHES) << ", "
0735 << SQLArrayConstF(polYellowErr, NBUNCHES) << ", "
0736 << xing_correction_offset << ", ";
0737 sql << "'{";
0738 for (int icross = 0; icross < NBUNCHES; icross++)
0739 {
0740 sql << blueSpinPattern[icross];
0741 if (icross < NBUNCHES - 1)
0742 {
0743 sql << ",";
0744 }
0745 }
0746 sql << "}'";
0747 sql << ", '{";
0748 for (int icross = 0; icross < NBUNCHES; icross++)
0749 {
0750 sql << yellSpinPattern[icross];
0751 if (icross < NBUNCHES - 1)
0752 {
0753 sql << ",";
0754 }
0755 }
0756 sql << "}'";
0757 sql << ", '{";
0758 for (int icross = 0; icross < NBUNCHES; icross++)
0759 {
0760 sql << mbdns[icross];
0761 if (icross < NBUNCHES - 1)
0762 {
0763 sql << ",";
0764 }
0765 }
0766 sql << "}'";
0767 sql << ", '{";
0768 for (int icross = 0; icross < NBUNCHES; icross++)
0769 {
0770 sql << mbdvtx[icross];
0771 if (icross < NBUNCHES - 1)
0772 {
0773 sql << ",";
0774 }
0775 }
0776 sql << "}'";
0777 sql << ", '{";
0778 for (int icross = 0; icross < NBUNCHES; icross++)
0779 {
0780 sql << zdcns[icross];
0781 if (icross < NBUNCHES - 1)
0782 {
0783 sql << ",";
0784 }
0785 }
0786 sql << "}'";
0787
0788 sql << ", " << qa_level << ");";
0789 }
0790 if (true )
0791 {
0792 std::cout << sql.str() << std::endl;
0793 }
0794
0795
0796 rsSpin.reset();
0797 odbc::Statement *stmtSpin = DBInterface::instance()->getStatement(dbname);
0798 try
0799 {
0800 stmtSpin->executeUpdate(sql.str());
0801 }
0802 catch (odbc::SQLException &e)
0803 {
0804 std::cout << PHWHERE
0805 << " Exception caught at XingShiftCal::CommitPatternToSpinDB when insert into spin DB" << std::endl;
0806 std::cout << "Message: " << e.getMessage() << std::endl;
0807 commitSuccessSpinDB = 0;
0808 return 0;
0809 }
0810
0811
0812 commitSuccessSpinDB = 1;
0813
0814
0815 SpinDBQA();
0816
0817
0818 return 0;
0819 }
0820
0821 int XingShiftCal::SpinDBQA()
0822 {
0823
0824 unsigned int qa_level = 0xffff;
0825
0826
0827 std::string dbname = "spinDB";
0828 std::string dbtable = "spin";
0829
0830
0831 bool runExists = false;
0832 int prevbadrunval = 0;
0833 std::string sqlSpinSelect = "SELECT runnumber, qa_level, badrunqa FROM " + dbtable + " WHERE runnumber = " + std::to_string(runnumber) + " AND qa_level = " + std::to_string(qa_level);
0834
0835 std::cout << sqlSpinSelect << std::endl;
0836
0837 odbc::Statement *stmtSpinSelect = DBInterface::instance()->getStatement(dbname);
0838 std::unique_ptr<odbc::ResultSet> rsSpin;
0839 try
0840 {
0841 rsSpin = std::unique_ptr<odbc::ResultSet>(stmtSpinSelect->executeQuery(sqlSpinSelect));
0842 }
0843 catch (odbc::SQLException &e)
0844 {
0845 std::cout << PHWHERE
0846 << " Exception caught at XingShiftCal::SpinDBQA when querying spin DB" << std::endl;
0847 std::cout << "Message: " << e.getMessage() << std::endl;
0848 return 0;
0849 }
0850 if (rsSpin->next())
0851 {
0852 prevbadrunval = rsSpin->getInt("badrunqa");
0853 if (rsSpin->wasNull())
0854 {
0855 std::cout << "SPINDBQA: badrunqa is NULL. Setting to 0 for qa check. " << std::endl;
0856 prevbadrunval = 0;
0857 }
0858 if (true)
0859 {
0860 std::cout << "run " << runnumber << " exists in " << dbtable
0861 << ", ready to do QA" << std::endl;
0862 }
0863 runExists = true;
0864 }
0865 else
0866 {
0867 if (true)
0868 {
0869 std::cout << "run " << runnumber << " NOT exists in " << dbtable
0870 << ", no QA" << std::endl;
0871 }
0872 }
0873
0874 int badrunQA = 0;
0875
0876 if (prevbadrunval > 0)
0877 {
0878 std::cout << "SPINDBQA: badrunqa is already > 0. No additional qa is performed." << std::endl;
0879 return 0;
0880 }
0881
0882
0883
0884
0885
0886
0887
0888 std::string scdev_blue;
0889 std::string scdev_yell;
0890 for (int crossing = 0; crossing < 120; crossing++)
0891 {
0892 int ibluespin = blueSpinPattern[crossing];
0893 int iyellspin = yellSpinPattern[crossing];
0894 if (ibluespin == 1)
0895 {
0896 scdev_blue.push_back('+');
0897 }
0898 else if (ibluespin == -1)
0899 {
0900 scdev_blue.push_back('-');
0901 }
0902 else
0903 {
0904 scdev_blue.push_back('*');
0905 }
0906
0907 if (iyellspin == 1)
0908 {
0909 scdev_yell.push_back('+');
0910 }
0911 else if (iyellspin == -1)
0912 {
0913 scdev_yell.push_back('-');
0914 }
0915 else
0916 {
0917 scdev_yell.push_back('*');
0918 }
0919 }
0920
0921
0922 std::string pattern_name = "UNKNOWN";
0923
0924 for (std::map<std::string, std::string>::const_iterator ii = preset_pattern_blue.begin(); ii != preset_pattern_blue.end(); ++ii)
0925 {
0926 std::string key = (*ii).first;
0927 if (preset_pattern_blue[key] == scdev_blue && preset_pattern_yellow[key] == scdev_yell)
0928 {
0929 pattern_name = key;
0930 }
0931 }
0932
0933 if (pattern_name == "UNKNOWN")
0934 {
0935 badrunQA = 1;
0936 std::cout << "SPINDBQA: Pattern is unidentified from known CDEV pattern. Setting bad run." << std::endl;
0937 }
0938
0939
0940 int mismatches = 0;
0941
0942
0943 for (int crossing = 0; crossing < 120; crossing++)
0944 {
0945 int spin_cdev_blue = blueSpinPattern[crossing];
0946 int spin_cdev_yell = yellSpinPattern[crossing];
0947 int spin_pC_blue = bluePcSpinPattern[crossing];
0948 int spin_pC_yell = yellPcSpinPattern[crossing];
0949
0950 if (spin_pC_blue == -1 || spin_pC_blue == 1)
0951 {
0952 if (spin_cdev_blue != spin_pC_blue && !(spin_cdev_blue == 0 && spin_pC_blue == 10))
0953 {
0954 mismatches += 1;
0955 }
0956 }
0957
0958 if (spin_pC_yell == -1 || spin_pC_yell == 1)
0959 {
0960 if (spin_cdev_yell != spin_pC_yell && !(spin_cdev_blue == 0 && spin_pC_blue == 10))
0961 {
0962 mismatches += 1;
0963 }
0964 }
0965 }
0966
0967 if (mismatches > 10)
0968 {
0969 badrunQA = 1;
0970 std::cout << "SPINDBQA: CDEV pattern has > 10 mismatched bunches from pC polarimeter. Setting bad run." << std::endl;
0971 }
0972
0973
0974 int xing_correction_offset = -999;
0975 if (success)
0976 {
0977 xing_correction_offset = xingshift;
0978 }
0979
0980 if (xing_correction_offset != 0)
0981 {
0982 badrunQA = 1;
0983 std::cout << "SPINDBQA: Crossing shift does not equal 0. Setting bad run." << std::endl;
0984 }
0985
0986
0987 if (polBlue <= 0.0 || polBlue > 100.0)
0988 {
0989 badrunQA = 1;
0990 std::cout << "SPINDBQA: Blue beam polarization is unknown. Setting bad run." << std::endl;
0991 }
0992 if (polYellow <= 0.0 || polYellow > 100.0)
0993 {
0994 badrunQA = 1;
0995 std::cout << "SPINDBQA: Yellow beam polarization is unknown. Setting bad run." << std::endl;
0996 }
0997
0998
0999
1000
1001 rsSpin.reset();
1002 dbname = "spinDB_write";
1003 dbtable = "spin";
1004 if (runExists)
1005 {
1006
1007 std::string sql = "UPDATE " + dbtable + " SET badrunqa = " + std::to_string(badrunQA) + " WHERE runnumber = " + std::to_string(runnumber) + " AND qa_level = " + std::to_string(qa_level);
1008
1009 std::cout << sql << std::endl;
1010
1011
1012 odbc::Statement *stmtSpin = DBInterface::instance()->getStatement(dbname);
1013 try
1014 {
1015 stmtSpin->executeUpdate(sql);
1016 }
1017 catch (odbc::SQLException &e)
1018 {
1019 std::cout << PHWHERE
1020 << " Exception caught at XingShiftCal::SpinDBQA when insert badrunqa into spin DB" << std::endl;
1021 std::cout << "Message: " << e.getMessage() << std::endl;
1022 commitSuccessSpinDB = 0;
1023 return 0;
1024 }
1025 }
1026
1027 return 0;
1028 }
1029
1030 std::string XingShiftCal::SQLArrayConstF(float x, int n)
1031 {
1032 std::ostringstream s;
1033 s << "'{";
1034 for (int i = 0; i < n; i++)
1035 {
1036 s << x;
1037 if (i < n - 1)
1038 {
1039 s << ",";
1040 }
1041 }
1042 s << "}'";
1043 return s.str();
1044 }