BOSS 7.1.2
BESIII Offline Software System
Loading...
Searching...
No Matches
MdcHvDropSvc.cxx
Go to the documentation of this file.
1/**
2 * @file MdcHvDropSvc.cxx
3 * @author zhangzeheng ([email protected])
4 * @brief main functions of this svc
5 * @version 0.1
6 * @date 2022-01-19
7 *
8 * @copyright Copyright (c) 2022
9 *
10 */
11
12#include <cstdio>
13#include <cstdlib>
14#include <cstring>
15#include <iostream>
16#include <sstream>
17
18#include "GaudiKernel/IDataProviderSvc.h"
19#include "GaudiKernel/IInterface.h"
20#include "GaudiKernel/ISvcLocator.h"
21#include "GaudiKernel/Kernel.h"
22#include "GaudiKernel/MsgStream.h"
23#include "GaudiKernel/PropertyMgr.h"
24#include "GaudiKernel/SmartDataPtr.h"
25#include "GaudiKernel/StatusCode.h"
26#include "GaudiKernel/SvcFactory.h"
28
29#include "GaudiKernel/IIncidentListener.h"
30#include "GaudiKernel/IIncidentSvc.h"
31#include "GaudiKernel/Incident.h"
32
33#include "EventModel/Event.h"
36#include "GaudiKernel/Bootstrap.h"
37#include "GaudiKernel/ISvcLocator.h"
38
39#include <TMath.h>
40
41//using namespace std;
42using std::cout;
43using std::endl;
44using std::string;
45
46DECLARE_COMPONENT(MdcHvDropSvc)
47
48
49MdcHvDropSvc::MdcHvDropSvc(const string &name, ISvcLocator *svcloc) : Service(name, svcloc) {
50 // declare properties
51 declareProperty("Host", m_host = std::string("202.122.33.123"));
52 declareProperty("DbName", m_dbName = std::string("tof40t_linux"));
53 declareProperty("TableName", m_table = std::string("MDCLayerVmon"));
54 declareProperty("UserName", m_userName = std::string("guest"));
55 declareProperty("Password", m_password = std::string("guestpass"));
56 declareProperty("Port", m_port=6175);
57 declareProperty("IgnoreLayer_21_24",m_ignoreLayer_21_24=true);
58 declareProperty("RelativeHvDropThreshold",m_relativeHvDropThreshold=0.007);
59 declareProperty("FetchHvDataLengthInSeconds",m_fetchLength=5*3600);
60 declareProperty("UseEtsT1",m_useEtsT1=0); // whether to use EtsT1, if not, use time().
61 declareProperty("EtsT1OffSet",m_etsT1Offset=0);// if is 0, and UseEtsT1, will be treated as using database time from database..
62 // else, acts as calculating time_override=etsT1+etsT1Offset;
63
64 declareProperty("Host2", m_host2 = std::string("bes3db2.ihep.ac.cn"));
65 declareProperty("DbName2", m_dbName2 = std::string("run"));
66 declareProperty("TableName2", m_table2 = std::string("RunParams"));
67 declareProperty("UserName2", m_userName2 = std::string("guest"));
68 declareProperty("Password2", m_password2 = std::string("guestpass"));
69 declareProperty("Port2", m_port2=3306);//3306 is default port for mysql
70}
71
74
75StatusCode MdcHvDropSvc::queryInterface(const InterfaceID &riid, void **ppvInterface) {
76 if (IID_IMdcHvDropSvc.versionMatch(riid)) {
77 *ppvInterface = static_cast<IMdcHvDropSvc *>(this);
78 } else {
79 return Service::queryInterface(riid, ppvInterface);
80 }
81 return StatusCode::SUCCESS;
82}
83
85 MsgStream log(messageService(), name());
86 log << MSG::INFO << "MdcHvDropSvc::initialize()" << endreq;
87
88 StatusCode sc = Service::initialize();
89 if (sc.isFailure()) return sc;
90
91 IIncidentSvc *incsvc;
92 sc = service("IncidentSvc", incsvc);
93 int priority = 100;
94 if (sc.isSuccess()) {
95 incsvc->addListener(this, "NewRun", priority);
96 }
97
98 //sc = serviceLocator()->service("DatabaseSvc", m_dbsvc, true);
99 //if (sc.isFailure()) {
100 // log << MSG::ERROR << "Unable to find DatabaseSvc " << endreq;
101 // return sc;
102 //}
103//
104 sc = serviceLocator()->service("EventDataSvc", m_eventSvc, true);
105 if (sc.isFailure()) {
106 log << MSG::ERROR << "Unable to find EventDataSvc " << endreq;
107 return sc;
108 }
109
110 sc = initMySql();
111 if (sc.isFailure()){
112 log << MSG::ERROR << "Unable to initialize mysql " << endreq;
113 return sc;
114 }
115
116 return StatusCode::SUCCESS;
117}
118
120 MsgStream log(messageService(), name());
121 log << MSG::INFO << "MdcHvDropSvc::finalize()" << endreq;
122 // if(m_connect_offline) delete m_connect_offline;
123 return StatusCode::SUCCESS;
124}
125// TODO: multi-run.
126void MdcHvDropSvc::handle(const Incident &inc) {
127 MsgStream log(messageService(), name());
128 log << MSG::DEBUG << "handle: " << inc.type() << endreq;
129 // so currently we do nothing.
130 //if (inc.type() == "NewRun") {
131 // log << MSG::DEBUG << "NewRun" << endreq;
132 //
133 // SmartDataPtr<Event::EventHeader> eventHeader(m_eventSvc, "/Event/EventHeader");
134 // int run = eventHeader->runNumber();
135 // //cout<<"&&&&&&&&&&&&&&:&&&&&&&&&&&&&&&&&&&& MdcHvDropSvc handle,run="<<run<<endl;
136 // if (run < 0) run = -run;
137 // log << MSG::DEBUG << "handle: "
138 // << "Run in handle is: " << run << endreq;
139 // cout << "-------------in MdcHvDropSvc in the following-----------" << endl;
140 // cout << "handle: "
141 // << "Run in handle is: " << run << endl;
142
143 //if (run >= m_RunFrom && run <= m_RunTo && m_ReadPar == true) {
144 // cout << "do not read the database repeatly in EmcShEnCalibConst" << endl;
145 // cout << "run,RunFrom,runTo=" << run << "," << m_RunFrom << "," << m_RunTo << endl;
146 //} else {
147 //
148 // //cout<<"read the database in EmcShEnCalibConst"<<endl;
149 // if (!getMdcHvDropSvcInfo()) {
150 // log << MSG::ERROR << "can not initilize Shower energy Calib Constants" << endreq;
151 // } else {
152 // m_ReadPar = true;
153 // std::cout << "in handle of MdcHvDropSvc getPi0CalibFile()= " << getPi0CalibFile() << std::endl;
154 // std::cout << "getSingleGammaCalibFile()= " << getSingleGammaCalibFile() << std::endl;
155 // }
156 //}
157 //}
158}
159
160
161/**
162 * @brief connects to mysql using pre-defined parameters.
163 *
164 * @return StatusCode
165 */
166StatusCode MdcHvDropSvc::initMySql(){
167 //char host [] = "202.122.33.123";
168 //char username[] = "guest";
169 //char password[] = "guestpass";
170 //int m_port = 6175;
171 //char database[] = "tof40t_linux";
172 //char querystring[] = "select * from MDCLayerVmon where id >=1000000 and id <= 1000010";
173
174 mysql_init(&m_mysql);
175
176 if(!mysql_real_connect(&m_mysql,m_host.c_str(),m_userName.c_str(),m_password.c_str(),m_dbName.c_str(),m_port,NULL,0)){
177 std::cerr<<"Connect to database" <<m_host<<":"<<m_port<<" failed\n"<<
178 "due to "<<mysql_error(&m_mysql)<<std::endl;
179 return StatusCode::FAILURE;
180 }
181 return StatusCode::SUCCESS;
182}
183
184/**
185 * @brief timestamp to a string of the time in UTC+8
186 *
187 * from timestamp get sql formatted datetime string with TZ=UTC+8, or Asia/Shanghai
188 * our Slow Control Database stores datetime with TZ=UTC+8,
189 *
190 * @param utctime timestamp
191 * @param str the string to store
192 * @param length length of string
193 * @return size_t how many charactors are written to str (including trailing "\0"). basically 0==fail, !0 == succeed.
194 */
195size_t MdcHvDropSvc::Time_t2str(Time_t utctime, char* str, int length){
196 const int tzOffset=60*60*8;
197 std::time_t timeShanghai=utctime+tzOffset;
198 std::tm *tm=std::gmtime(&timeShanghai); // this is not thread safe
199 return std::strftime(str,length,"%Y-%m-%d %H:%M:%S", tm);//as-is
200}
201
202/**
203 * @brief Get Time_t from a date_time string.
204 * require str be like "%Y-%m-%d %H:%M:%S"
205 * note that our date_time is fixed TZ=UTC+8, or Asia/Shanghai
206 *
207 * @param str date_time string
208 * @return Time_t
209 */
210Time_t MdcHvDropSvc::datetimeStr2Time_t(const char* str){
211 const int tzOffset=60*60*8;
212 std::tm tm;
213 int year, month, day, hour, min, sec;
214 std::sscanf(str,"%d-%d-%d %d:%d:%d",
215 & year, & month, & day, & hour, & min, & sec);
216 tm.tm_year = year-1900;
217 tm.tm_mon = month-1;
218 tm.tm_mday = day;
219 tm.tm_hour = hour;
220 tm.tm_min = min;
221 tm.tm_sec = sec;
222 tm.tm_isdst=0;
223 tm.tm_gmtoff=tzOffset;
224 Time_t time=std::mktime(&tm);
225 return time;
226}
227
228
229/**
230 * @brief fetch hv info from database between timeBegin and timeEnd. in DB time.
231 *
232 * @param timeBegin
233 * @param timeEnd
234 * @return StatusCode
235 */
236StatusCode MdcHvDropSvc::FetchHvInfo(Time_t timeBegin, Time_t timeEnd) {
237 //MsgStream log(msgSvc(), "MdcHvDropSvc");
238 MsgStream log(messageService(), name());
239 log << MSG::INFO << "MdcHvDropSvc::FetchHvInfo()" << endreq;
240 char querystring[300];
241 char sTimeBegin[100], sTimeEnd[100];
242 Time_t2str(timeBegin,sTimeBegin,100);
243 Time_t2str(timeEnd,sTimeEnd,100);
244 //MYSQL_RES *res_set;
245
246 sprintf(querystring, "select * \
247 from %s \
248 where date_time >= '%s' \
249 and date_time <= '%s' ",
250 m_table.c_str(),sTimeBegin, sTimeEnd);
251 log << MSG::INFO << "sql_request=" << querystring << endreq;
252 // yield:
253
254 //unsigned int nColomn;
255
256 if (mysql_query(&m_mysql,querystring)){
257 log << MSG::ERROR << "Error! mysql_query failed"<<endreq;
258 return StatusCode::FAILURE;
259 }
260 else{
261 m_result=mysql_store_result(&m_mysql);
262 //nColomn = mysql_num_fields(m_result);
263 while ((m_row = mysql_fetch_row(m_result))) {
264 //unsigned long *lengths;
265 //lengths = mysql_fetch_lengths(m_result);
266
267 VDataItem item;
268 Time_t time;
269 sqlRow2Item(m_row,m_result,item,time);
270 m_vData.push_back_sorted(time,item);
271
272 //for (int i = 0; i < nColomn; i++) {
273 // printf("[%.*s] \t", (int)lengths[i], m_row[i] ? //m_row[i] : "NULL");
274 // item[]
275//
276 //}
277 //printf("\n");
278 }
279 log <<MSG::INFO << "successfully fetched HV data from database." << endreq;
280 }
281
282
283
284 //int row_no = m_dbsvc->query(dbName.c_str(), stmt, res);
285 //if (row_no < 1) {
286 // std::cerr << "ERROR: query" << stmt << "returns empty //result"<<std::endl;
287 //}
288 //else {
289 // for (int i = 0; i < row_no; i++) {
290 // DatabaseRecord *records1 = res[i];
291 // VDataItem item;
292 // runfrm = records1->GetInt("RunFrom");
293 // runto = records1->GetInt("RunTo");
294//
295//
296 // SftVer = records1->GetString("SftVer");
297 // CalParVer = records1->GetString("ParVer");
298//
299 // }
300//
301 //}
302
303 return StatusCode::SUCCESS;
304}
305/**
306 * @brief returns average HV for a slice in a row, row[begin:end]
307 *
308 * contain row[sliceBegin];
309 * contains no row[sliceEnd];
310 */
311inline static double average(MYSQL_ROW row, int sliceBegin, int sliceEnd) {
312
313 double sum = 0.0;
314 for (int i=sliceBegin;i<sliceEnd;i++ ){
315 sum+=atof(row[i]);
316 }
317 return sum/(sliceEnd-sliceBegin);
318
319}
320
321/**
322 * @brief grab info stored in a row of mysql result, and build a VDataItem from it. also time.
323 *
324 * @param row
325 * @param result
326 * @param item the item
327 * @param time
328 * @return StatusCode
329 */
330StatusCode MdcHvDropSvc::sqlRow2Item(MYSQL_ROW row, MYSQL_RES *result,VDataItem &item, Time_t &time){
331 //VDataItem& item=out;
332 MsgStream log(messageService(), name());
333 log << MSG::DEBUG << "MdcHvDropSvc::sqlRow2Item()" << endreq;
334 int nColomn = mysql_num_fields(result);
335 if (nColomn !=102){
336 log << MSG::ERROR << "ERROR: SQL output does not meet expectation"<<endreq;
337 return StatusCode::FAILURE;
338 }
339 //unsigned long *lengths;
340 //lengths = mysql_fetch_lengths(result);
341 time=datetimeStr2Time_t(row[1]);
342 item[0]=average(row,39,44);// S1
343 item[1]=average(row,44,50);// S2
344 item[2]=average(row,50,56);// S3
345 item[3]=average(row,56,62);// S4
346 item[4]=atof(row[80]);// S5
347 item[5]=atof(row[81]);// S6
348 for (int i =2; i<39;i++){
349 int layer=i+4;
350 item[layer]=atof(row[i]);// S7~43
351 }
352 return StatusCode::SUCCESS;
353
354 //from
355 //ia[:,2:39].astype(float)#S7-43
356
357}
358
359//bool MdcHvDropSvc::getMdcHvDropSvcInfo() {
360// MsgStream log(messageService(), name());
361// SmartDataPtr<Event::EventHeader> eventHeader(m_eventSvc, "/Event/EventHeader");
362// int run = eventHeader->runNumber();
363// cout << "Run in getMdcHvDropSvcInfo() is: " << run << endl;
364//
365// char stmt1[400];
366// StatusCode st1;
367// //runfrm,runto are the value from the table ***CalConst;runfrm1,runto1 are the value from the table CalVtxLumVer
368// int runfrm, runfrm1;
369// int runto, runto1;
370// std::string cType;
371//
372// if (run < 0) {
373// cout << "This data is the MC sample with the Run Number: " << run << endl;
374// run = -run;
375// }
376//
377// if (m_bossRelease == "default") m_bossRelease = getenv("BES_RELEASE");
378//
379// cType = "EmcShEnCalib";
380//
381// st1 = getSftParVer(m_bossVer, m_calPar, runfrm1, runto1, run, m_bossRelease, cType);
382//
383// sprintf(stmt1, "select RunFrom,RunTo,singleGammaCalib,pi0Calib from EmcShEnCalibConst where SftVer = '%s' and //RunFrom <= %d and RunTo >= %d ", m_bossVer.c_str(), run, run);
384//
385// DatabaseRecordVector res;
386// int row_no = m_dbsvc->query("offlinedb", stmt1, res);
387//
388// if (row_no > 0) {
389// DatabaseRecord &dbrec = *res[row_no - 1];
390// m_SingleGammaCalibFile = dbrec.GetString("singleGammaCalib");
391// m_Pi0CalibFile = dbrec.GetString("pi0Calib");
392// m_RunFrom = dbrec.GetInt("RunFrom");
393// m_RunTo = dbrec.GetInt("RunTo");
394//
395// cout << "BossReleaseVer=" << m_bossRelease.c_str() << "\t"
396// << "EmcShEnCalibBossVer=" << m_bossVer.c_str() << endl;
397// cout << "m_Pi0CalibFile is:" << m_Pi0CalibFile << endl;
398// cout << "m_SingleGammaCalibFile is:" << m_SingleGammaCalibFile << endl;
399// cout << "m_RunFrom is:" << m_RunFrom << endl;
400// cout << "m_RunTo is:" << m_RunTo << endl;
401// cout << "Successfully fetch MdcHvDropSvc information for run: " << run << endl;
402// cout << "////////// read parameters from EmcShEnCalibConst database/////////////" << endl;
403// return true;
404// } else if (row_no <= 0) {
405// cout << " MdcHvDropSvc:: can not found MdcHvDropSvc information of run:"
406// << run << ", boss version " << m_bossRelease << endl;
407// exit(1);
408// return false;
409// }
410// return true;
411//}
412
414 MsgStream log(messageService(), name());
415 //log << MSG::DEBUG << "MdcHvDropSvc::sqlRow2Item()" << endreq;
416 SmartDataPtr<Event::EventHeader> eventHeader(m_eventSvc, "/Event/EventHeader");
417 Time_t time = eventHeader->time();
418 Time_t fetchBeginTime = time;
419 int run = eventHeader->runNumber();
420 unsigned long time_etsT1=eventHeader->etsT1();
421 long time_etsT1_timelike32=((time_etsT1/2000000)&0x00000000ffffffffLU);
422
423 // handle etsT1 logic
424 // declareProperty("UseEtsT1",m_useEtsT1=0); // whether to use EtsT1, if not, use time().
425 //declareProperty("EtsT1OffSet",m_etsT1Offset=0);// if is 0, and UseEtsT1, will be treated as using database time from database..
426 //else, acts as calculating time_override=etsT1+etsT1Offset;
427
428 if(m_useEtsT1){
429
430 if(m_etsT1Offset==0){
431
432 time=time_etsT1_timelike32+getRunBeginTime(run);
433 }
434 else{
435 time=time_etsT1_timelike32+m_etsT1Offset;
436 }
437 }
438
439
440
441 if (run < 0) return 0; // a MC event.
442
443 log << MSG::INFO << "query time " << time << endreq;
444 log << MSG::INFO << "current boundary " << m_vData.getLowerBoundaryEventTime() << " : " << m_vData.getUpperBoundaryEventTime() << endreq;
445
446 if (m_vData.getUpperBoundaryEventTime() < time || time < m_vData.getLowerBoundaryEventTime()) { // not in cache
447 // 1st time.
448 if (m_vData.size() == 0) {
449 char time1str[100];
450 Time_t2str(time, time1str, 100);
451 log << MSG::INFO << "INFO: MdcHvDropSvc time " << time << " aka " << time1str << " is not in cache yet.\n"
452 << "\tfetching HV info for 1h ago" << time - 3600 << " til fetch Length" << time + m_fetchLength - 3600 << endreq;
453 fetchBeginTime = time - 3600;
454 }
455 // 2nd time
456 else {
457 Time_t upTimeCachedDBTime = m_vData.getUpperBoundaryEventTime() + m_vData.getOffsetEvt2Db();
458 char time1str[100];
459 Time_t2str(time, time1str, 100);
460 // time in another fetch interval, thus we choose to fetch new data and append to cache
461 if (m_vData.getLowerBoundaryEventTime() < time && time < m_vData.getUpperBoundaryEventTime() + m_fetchLength) {
462
463 log << MSG::INFO << "INFO:MdcHvDropSvc time " << time << " aka " << time1str << " is not in cache yet.\n"
464 << "\tcurrent upperBoundary is " << m_vData.getUpperBoundaryEventTime() << "\n"
465 << "\tfetching HV info for dbTime " << upTimeCachedDBTime << " to fetch Length later" << upTimeCachedDBTime + m_fetchLength << endreq;
466 fetchBeginTime = upTimeCachedDBTime;
467 }
468 //time not in another fetch interval, and we cannot find a interval to append to cache.
469 else {
470 log << MSG::INFO << "INFO:MdcHvDropSvc time " << time << " aka " << time1str << " is not in cache or canbe fetched in a interval.\n"
471 << "\tcurrent cache boundary is " << m_vData.getLowerBoundaryEventTime() << ":" << m_vData.getUpperBoundaryEventTime() << ".\n"
472 << "\tcurrent fetch interval is " << m_vData.getUpperBoundaryEventTime() << ":" << m_vData.getUpperBoundaryEventTime() + m_fetchLength << endreq;
473 log << MSG::INFO << "aborted cache and fetching new data.\n"
474 << "\tfetching HV info for 1h ago" << time - 3600 << " til fetch Length" << time + m_fetchLength - 3600 << endreq;
475 m_vData.clear();
476 fetchBeginTime = time - 3600;
477 }
478 }
479
480 fetchBeginTime += m_vData.getOffsetEvt2Db(); // now db time
481 Time_t time2 = fetchBeginTime + m_fetchLength;
482 if (!FetchHvInfo(fetchBeginTime - 600, time2) == StatusCode::SUCCESS) {
483 cout << "ERROR: MdcHvDropSvc failed to fetch HV info\n";
484 return -10000;
485 }
486 }
487 if (!m_vData.isValid(time))
488 return -9999;
489 if (m_ignoreLayer_21_24)
490 return m_vData.getAvgDropButVeryDrop(time);
491 else
492 return m_vData.getAvgDrop(time);
493}
494
495
496Time_t MdcHvDropSvc::getRunBeginTime(int runid){
497
498 if (m_run_begin.find(runid)!=m_run_begin.end()){
499 return m_run_begin[runid];
500 }
501 //connect to offline database
502 MYSQL mysql;
503 MYSQL_ROW row;
504 MYSQL_RES *result;
505 mysql_init(&mysql);
506 const Time_t ret_err=0;
507
508 if(!mysql_real_connect(&mysql,m_host2.c_str(),m_userName2.c_str(),m_password2.c_str(),m_dbName2.c_str(),m_port2,NULL,0)){
509 std::cerr<<"Connect to database" <<m_host<<":"<<m_port<<" failed\n"<<
510 "due to "<<mysql_error(&mysql)<<std::endl;
511 return m_run_begin[runid]=ret_err;
512 }
513 char querystring[300];
514 //query is SELECT run_number, startTime, endTime FROM RunParams WHERE run_number >= %s AND run_number <= %s
515 sprintf(querystring, "SELECT run_number, startTime, endTime FROM RunParams WHERE run_number = %d",runid);
516 if (mysql_query(&mysql,querystring)){
517 std::cerr<<"Error! mysql_query failed"<<std::endl;
518 return m_run_begin[runid]=ret_err;
519 }
520 else{
521 result=mysql_store_result(&mysql);
522 if (mysql_num_rows(result) < 1){
523 std::cerr<<"Error! mysql_query returns "<<mysql_num_rows(result)<<" rows"<<std::endl;
524 return m_run_begin[runid]=ret_err;
525 }
526 row = mysql_fetch_row(result);
527 Time_t time=datetimeStr2Time_t(row[1]);
528 mysql_free_result(result);
529 mysql_close(&mysql);
530 std::cout<<"got run begin time for run "<<runid<<" is "<<time<<std::endl;
531 return m_run_begin[runid]=time;
532 }
533
534}
sprintf(cut,"kal_costheta0_em>-0.93&&kal_costheta0_em<0.93&&kal_pxy0_em>=0.05+%d*0.1&&kal_pxy0_em<0.15+%d*0.1&&NGch>=2", j, j)
Double_t time
header for main part.
struct st_mysql_res MYSQL_RES
struct st_mysql MYSQL
long Time_t
Definition VData.h:31
#define NULL
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvUnknown)
void handle(const Incident &)
virtual StatusCode initialize()
virtual double queryRelativeHvDrop()
virtual StatusCode finalize()
bool isValid(Time_t time) const
Definition VData.cxx:17
double getAvgDrop(Time_t time)
Definition VData.cxx:89
Time_t getUpperBoundaryEventTime()
Definition VData.h:55
void push_back_sorted(Time_t time_HV_SLOWCTRL, const VDataItem &data)
add a entry to our cache. the entry has to be pushed back in ascending order, with no gap....
Definition VData.cxx:110
double getAvgDropButVeryDrop(Time_t time)
Definition VData.cxx:95
Time_t getLowerBoundaryEventTime()
Definition VData.h:56
void clear()
throw all cached data. next time you might have to prepare cache again..
Definition VData.cxx:73
double getOffsetEvt2Db()
Definition VData.h:64
size_t size()
Definition VData.h:54