//*-- AUTHOR : Ilse Koenig //*-- Created : 16/08/2004 by Ilse Koenig //*-- Modified : 09/02/2011 by Ilse Koenig //_HADES_CLASS_DESCRIPTION ////////////////////////////////////////////////////////////////////////////// // // HOraSlowReaderOnline // // Class to read slowcontrol data from Oracle // ////////////////////////////////////////////////////////////////////////////// #include "horaslowreaderonline.h" #include "hdbconn.h" #include "horaslowpartition.h" #include "horaslowperiod.h" #include "horaslowchannel.h" #include "horaslowchanrunsum.h" #include "horaslowchanmeta.h" #include "horaslowchanraw.h" #include #include #define SQLCA_STORAGE_CLASS extern #define ORACA_STORAGE_CLASS extern // Oracle communication area #include // SQL Communications Area #include ClassImp(HOraSlowReaderOnline) Bool_t HOraSlowReaderOnline::readRunPeriods() { // Reads the run periods in the partition range if (!pConn->isOpen()||!pPartition) return kFALSE; TString start=pPartition->getStartTime(); TString end=pPartition->getEndTime(); if (start.IsNull()) { start = "2016-01-01 00:00:00"; } if (end.IsNull()) { end = "4000-01-01 00:00:00"; } pPartition->setTimeRange(start.Data(),end.Data()); EXEC SQL BEGIN DECLARE SECTION; char* pstart; char* pend; int nruns; int minid; int maxid; EXEC SQL END DECLARE SECTION; pstart=(Char_t*)start.Data(); pend=(Char_t*)end.Data(); EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; EXEC SQL SELECT NVL(count(1),0), NVL(min(id),-1), NVL(max(id),-1) INTO :nruns, :minid, :maxid FROM hades_scs.hscs_run_period WHERE starttime BETWEEN TO_DATE(:pstart,'yyyy-mm-dd hh24:mi:ss') AND TO_DATE(:pend,'yyyy-mm-dd hh24:mi:ss'); if (nruns>0) { TObjArray* data=pPartition->setNumPeriods(nruns); return readPeriods(data,nruns,minid,maxid); } notfound: Error("readRunPeriods","No run periods for partition %s in specified time range", pPartition->GetName()); return kFALSE; errorfound: pConn->showSqlError("readRunPeriods"); return kFALSE; } Bool_t HOraSlowReaderOnline::readPeriods(TObjArray* data,Int_t nData, Int_t minPeriodId,Int_t maxPeriodId) { // Private function to read the run periods in the partition range if (!data) return kFALSE; EXEC SQL BEGIN DECLARE SECTION; int minid; int maxid; struct { int id[NMAX_SCS]; char ts[NMAX_SCS][20]; char te[NMAX_SCS][20]; int rid[NMAX_SCS]; varchar rname[NMAX_SCS][81]; } periods; struct { short id_Ind[NMAX_SCS]; short ts_Ind[NMAX_SCS]; short te_Ind[NMAX_SCS]; short rid_Ind[NMAX_SCS]; short rname_Ind[NMAX_SCS]; } periods_Ind; EXEC SQL END DECLARE SECTION; minid=minPeriodId; maxid=maxPeriodId; Int_t nTot=0; Int_t nLast=0; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND continue; EXEC SQL DECLARE run_cursor CURSOR FOR SELECT period_id, TO_CHAR(period_begin,'yyyy-mm-dd hh24:mi:ss'), TO_CHAR(period_end,'yyyy-mm-dd hh24:mi:ss'), run_id, filename FROM hades_scs.hscs_periods WHERE period_id BETWEEN :minid AND :maxid ORDER BY period_id; EXEC SQL OPEN run_cursor; do { EXEC SQL FETCH run_cursor INTO :periods INDICATOR :periods_Ind; nLast=sqlca.sqlerrd[2]-nTot; for (Int_t i=0;isetPeriodId(periods.id[i]); p->setStartTime((Char_t*)(periods.ts[i])); p->setEndTime((Char_t*)(periods.te[i])); if (periods_Ind.rid_Ind[i]!=-1) p->setRunId(periods.rid[i]); if (periods_Ind.rname_Ind[i]!=-1) { periods.rname[i].arr[periods.rname[i].len]='\0'; p->setFilename((Char_t*)(periods.rname[i].arr)); } data->AddAt(p,nTot); nTot++; } } while (nLast==NMAX_SCS&&nTotshowSqlError("readPeriods"); return kFALSE; } Int_t HOraSlowReaderOnline::readChannelId(HOraSlowChannel* pChannel) { // Reads the channel id and data type of a channel if (!pConn->isOpen()||!pChannel) return kFALSE; EXEC SQL BEGIN DECLARE SECTION; char* chname; int chid; EXEC SQL END DECLARE SECTION; chname=(Char_t*)pChannel->GetName(); EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; EXEC SQL SELECT channel_id INTO :chid FROM hades_scs.hcss_channel WHERE channel_name = :chname; pChannel->setChannelId(chid); return chid; notfound: Warning("readChannelId","Channel %s not found",chname); return -1; errorfound: pConn->showSqlError("readChannelId"); return -1; } Bool_t HOraSlowReaderOnline::readChannelRunSum(HOraSlowChannel* pChannel) { // Reads the summary information of a channel for the given partition if (!pConn->isOpen()||!pPartition||!pChannel) return kFALSE; TObjArray* periods=pPartition->getRunPeriods(); if (!periods) return kFALSE; Int_t lastIndex=periods->GetLast(); if (lastIndex<0) return kFALSE; Int_t channelId=pChannel->getChannelId(); if (channelId<0) { channelId=readChannelId(pChannel); } if (channelId<=0) return kFALSE; EXEC SQL BEGIN DECLARE SECTION; int chid; int pmin; int pmax; struct { int pid[NMAX_SCS]; double vmean[NMAX_SCS]; double vsigma[NMAX_SCS]; double vmin[NMAX_SCS]; double vmax[NMAX_SCS]; int nd[NMAX_SCS]; int vstat[NMAX_SCS]; int ndmon[NMAX_SCS]; int spmon[NMAX_SCS]; } runsum; EXEC SQL END DECLARE SECTION; chid=channelId; pmin=((HOraSlowPeriod*)(periods->At(0)))->getPeriodId(); pmax=((HOraSlowPeriod*)(periods->At(lastIndex)))->getPeriodId(); Int_t nData=lastIndex+1; TObjArray* data=new TObjArray(nData); Int_t nTot=0; Int_t nLast=0; Int_t periodId=0; HOraSlowPeriod* period=0; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND continue; EXEC SQL DECLARE chansum_cursor CURSOR FOR SELECT period_id, mean_value, sigma_value, min_value, max_value, num_data_rows, stat, mon_num_data_rows, mon_smpl_per FROM hades_scs.hcss_chan_run_sum_view_ana WHERE channel_id = :chid AND period_id BETWEEN :pmin AND :pmax ORDER BY period_id; EXEC SQL OPEN chansum_cursor; do { EXEC SQL FETCH chansum_cursor INTO :runsum; nLast=sqlca.sqlerrd[2]-nTot; for (Int_t i=0;iAt(nTot)); periodId=period->getPeriodId(); if (periodId==runsum.pid[i]) { p->setPeriod(period); p->fill(runsum.pid[i],runsum.vmean[i],runsum.vsigma[i], runsum.vmin[i],runsum.vmax[i],runsum.nd[i], runsum.vstat[i],runsum.ndmon[i],runsum.spmon[i]); } else { p->fill(periodId,-999.,0.,-999.,-999.,0,1,-1,0); } data->AddAt(p,nTot); nTot++; } } while (nLast==NMAX_SCS&&nTot<(lastIndex+1)); EXEC SQL CLOSE chansum_cursor; pChannel->setRunSumData(data); if (nTot==nData) { cout<<"Run summary data for channel "<GetName()<<" read from Oracle\n"; return kTRUE; } else { Error("readChannelRunSum","Too few data read"); return kFALSE; } errorfound: pConn->showSqlError("readChannelRunSum"); return kFALSE; } Bool_t HOraSlowReaderOnline::readChannelMetaData(HOraSlowChannel* pChannel) { // Reads the meta information of a channel for the given partition if (!pConn->isOpen()||!pPartition||!pChannel) return kFALSE; Int_t channelId=pChannel->getChannelId(); if (channelId<0) { channelId=readChannelId(pChannel); } if (channelId<=0) return kFALSE; TObjArray* data=NULL; HOraSlowChanMeta* meta=NULL; EXEC SQL BEGIN DECLARE SECTION; int chid; int prec; varchar un[21]; char ts[20]; short un_Ind; short ts_Ind; EXEC SQL END DECLARE SECTION; chid=channelId; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND GOTO notfound; EXEC SQL SELECT NVL(precision,0), unit, TO_CHAR(data_starttime,'yyyy-mm-dd hh24:mi:ss') INTO :prec, :un:un_Ind, :ts:ts_Ind FROM hades_scs.hcss_meta_view_ana WHERE channel_id = :chid; data=new TObjArray(1); // no history stored since 2016 meta=new HOraSlowChanMeta(); meta->setPrecision(prec); if (un_Ind!=-1) { un.arr[un.len]='\0'; meta->setUnits((Char_t*)un.arr); } if (ts_Ind!=-1) { ts[19]='\0'; meta->setStartTime((Char_t*)ts); } data->AddAt(meta,0); pChannel->setMetaData(data); pChannel->setMaxPrecision(prec); cout<<"Meta data for channel "<GetName()<<" read from Oracle\n"; return kTRUE; notfound: Error("readChannelMetaData","No meta data found for channel %s",pChannel->GetName()); return kFALSE; errorfound: pConn->showSqlError("readChannelMetaData"); return kFALSE; } Bool_t HOraSlowReaderOnline::readRawData(HOraSlowChannel* channel, const Char_t* start, const Char_t* end) { // Reads the raw data of a channel in the specified time range if (!pConn->isOpen()||channel==0||start==0||end==0) return kFALSE; Int_t channelId=channel->getChannelId(); if (channelId<0) { channelId=readChannelId(channel); } if (channelId<=0) return kFALSE; if (channel->getMetaData()==0) readChannelMetaData(channel); EXEC SQL BEGIN DECLARE SECTION; int chid; char* tstart; char* tend; struct { char ti[NMAX_SCS][20]; int na[NMAX_SCS]; double va[NMAX_SCS]; int st[NMAX_SCS]; } rawdata; EXEC SQL END DECLARE SECTION; chid=channelId; TString t1(start); t1.Append(".000000"); TString t2(end); t2.Append(".999999"); tstart=(Char_t*)t1.Data(); tend=(Char_t*)t2.Data(); TObjArray* data=0; Int_t nTot=0; Int_t nLast=0; TString lastTimestamp; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND continue; EXEC SQL DECLARE rawf_cursor CURSOR FOR SELECT smpl_date, smpl_nanosec, NVL(float_val,0.), status FROM hades_scs.hcss_sample_data_view_ana WHERE smpl_time BETWEEN TO_TIMESTAMP(:tstart,'yyyy-mm-dd hh24:mi:ss.ff6') AND TO_TIMESTAMP(:tend,'yyyy-mm-dd hh24:mi:ss.ff6') AND channel_id = :chid ORDER BY smpl_time; EXEC SQL OPEN rawf_cursor; do { EXEC SQL FETCH rawf_cursor INTO :rawdata; nLast=sqlca.sqlerrd[2]-nTot; if (nLast>0) { if (data==0) data=new TObjArray(nLast); else data->Expand(sqlca.sqlerrd[2]); for (Int_t i=0;ifill(rawdata.ti[i],rawdata.na[i],rawdata.va[i],rawdata.st[i]); data->AddAt(p,nTot); nTot++; } lastTimestamp=rawdata.ti[nLast-1]; } } while (nLast==NMAX_SCS&&nTot<=20000); EXEC SQL CLOSE rawf_cursor; if (nTot>0) { if (nTot>=20000) channel->setRawData(data,start,lastTimestamp.Data()); else channel->setRawData(data,start,end); cout<<"Number of raw data: "<showSqlError("readRawData"); return kFALSE; }