//_HADES_CLASS_DESCRIPTION ////////////////////////////////////////////////////////////////////////////// // HEmcParOra2Io // // Interface class to database Oracle for input/output of parameters needed // by the EMC for runs since 2010 // (uses the Oracle C/C++ precompiler) // ////////////////////////////////////////////////////////////////////////////// using namespace std; #include "hemcparora2io.h" #include "hparora2set.h" #include "hemctrb3lookup.h" #include "hemccalpar.h" #include "hemcgeompar.h" #include "hgeomcompositevolume.h" #include "hora2geomdetversion.h" #include "hora2geomobj.h" #include "TClass.h" #include "TList.h" #include #include #include #define SQLCA_STORAGE_CLASS extern #define ORACA_STORAGE_CLASS extern // Oracle communication area #include // SQL Communications Area #include ClassImp(HEmcParOra2Io) #define EMC_MAXSEC 6 #define EMC_MAXSECCELLS 163 #define EMC_MAXCELLS 1956 //978 * 2 because we have 2 channels per cell #define EMC_MAXGEOMCELLS 164 HEmcParOra2Io::HEmcParOra2Io(HOra2Conn* pC) : HDetParOra2Io(pC) { // constructor // sets the name of the I/O class "HEmcParIo" // gets the pointer to the connection class fName="HEmcParIo"; initModules=new TArrayI(EMC_MAXSEC); geomVers=0; sensVolume=0; } HEmcParOra2Io::~HEmcParOra2Io(void) { // destructor if (initModules) delete initModules; if (geomVers) delete geomVers; if (sensVolume) delete sensVolume; } Bool_t HEmcParOra2Io::init(HParSet* pPar,Int_t* set) { // calls special read-function for each parameter container if (getRunStart(pPar)<0) { pPar->setInputVersion(-1,inputNumber); return kFALSE; } const Text_t* name=pPar->IsA()->GetName(); if (strcmp(name,"HEmcTrb3Lookup")==0) return read(((HEmcTrb3Lookup*)pPar)); if (strcmp(name,"HEmcCalPar")==0) return read(((HEmcCalPar*)pPar),set); if (strcmp(name,"HEmcGeomPar")==0) return read(((HEmcGeomPar*)pPar),set); cout<<"No read-interface to Oracle for parameter container " <GetName()<IsA()->GetName(); if (strcmp(name,"HEmcTrb3Lookup")==0) return writePar((HEmcTrb3Lookup*)pPar); if (strcmp(name,"HEmcCalPar")==0) return writePar((HEmcCalPar*)pPar); if (strcmp(name,"HEmcGeomPar")==0) return writeAlignment((HEmcGeomPar*)pPar); cout<<"No write-interface to Oracle for parameter container " <GetName()<contextId==-1 || runStart==-1) { pPar->setInputVersion(-1,inputNumber); version=-1; return kFALSE; } Int_t contVers=pPar->getInputVersion(inputNumber); if (contVers!=-1 && runStart>=oraSet->versDate[0] && runStart<=oraSet->versDate[1]) { version=contVers; return kFALSE; } const Char_t* containerClass=pPar->IsA()->GetName(); oraSet->clearVersDate(); EXEC SQL BEGIN DECLARE SECTION; int context; int vers; double since; double until; EXEC SQL END DECLARE SECTION; context=oraSet->contextId; EXEC SQL WHENEVER SQLERROR DO showSqlError("getVersion(HParSet*,Int_t&)"); EXEC SQL WHENEVER NOT FOUND GOTO notfound; if (strcmp(containerClass,"HEmcTrb3Lookup")==0) { EXEC SQL SELECT version, hanadate.date_to_number(valid_since), hanadate.date_to_number(valid_until) INTO :vers, :since, :until FROM emc_ana2.trb3lookup_vers_at_date WHERE context_id = :context; } else { if (strcmp(containerClass,"HEmcCalPar")==0) { EXEC SQL SELECT version, hanadate.date_to_number(valid_since), hanadate.date_to_number(valid_until) INTO :vers, :since, :until FROM emc_ana2.calpar_vers_at_date WHERE context_id = :context; } } version=vers; oraSet->versDate[0]=since; oraSet->versDate[1]=until; return kTRUE; notfound: pPar->setInputVersion(-1,inputNumber); version=-1; return kFALSE; }; Bool_t HEmcParOra2Io::read(HEmcTrb3Lookup* pPar) { // reads the lookup table for the Trb3 unpacker and fill the container EmcTrb3Lookup Int_t oraVersion=-1; Bool_t rc=getVersion(pPar,oraVersion); if (oraVersion<0) return kFALSE; if (oraVersion>=0&&rc==kFALSE) return kTRUE; pPar->clear(); EXEC SQL BEGIN DECLARE SECTION; int vers; struct { int address[EMC_MAXCELLS]; int channel[EMC_MAXCELLS]; int module[EMC_MAXCELLS]; int cell[EMC_MAXCELLS]; int flag[EMC_MAXCELLS]; } lookup; EXEC SQL END DECLARE SECTION; vers=oraVersion; EXEC SQL WHENEVER SQLERROR DO showSqlError("read(HEmcTrb3Lookup*)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT trbnet_address, channel, module, cell, flag INTO :lookup FROM emc_ana2.trb3lookup_data_view WHERE vers_id = :vers; Int_t nData=sqlca.sqlerrd[2]; for (Int_t i=0;ifill(lookup.address[i],lookup.channel[i], lookup.module[i]-1,lookup.cell[i], lookup.flag[i]); } rc=kTRUE; if (nData>0) { setChanged(pPar,oraVersion); cout<GetName()<<" initialized from Oracle"<setInputVersion(-1,inputNumber); rc=kFALSE; } return rc; } Bool_t HEmcParOra2Io::read(HEmcCalPar* pPar, Int_t* set) { // reads the calibration parameters and fill the EmcCalPar container Int_t oraVersion=-1; Bool_t rc=getVersion(pPar,oraVersion); if (oraVersion<0) return kFALSE; if (oraVersion>=0&&rc==kFALSE) return kTRUE; pPar->clear(); initModules->Reset(); EXEC SQL BEGIN DECLARE SECTION; int vers; struct { int module[EMC_MAXCELLS]; int cell[EMC_MAXCELLS]; float tdcSlope[EMC_MAXCELLS]; float tdcOffset[EMC_MAXCELLS]; float adcPar_0[EMC_MAXCELLS]; float adcPar_1[EMC_MAXCELLS]; float adcPar_2[EMC_MAXCELLS]; float timeWalkCorr_0[EMC_MAXCELLS]; float timeWalkCorr_1[EMC_MAXCELLS]; float timeWalkCorr_2[EMC_MAXCELLS]; } cal; EXEC SQL END DECLARE SECTION; vers=oraVersion; EXEC SQL WHENEVER SQLERROR DO showSqlError("read(HEmcCalPar*,Int_t*)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT module, cell, tdc_slope, tdc_offset, adc_par_0, adc_par_1, adc_par_2, time_walk_0, time_walk_1, time_walk_2 INTO :cal FROM emc_ana2.calpar_data_view WHERE vers_id = :vers; Int_t nData=sqlca.sqlerrd[2]; Int_t m=-1; for (Int_t i=0;iAddAt(1,m); } } rc=kTRUE; for(Int_t i=0;iAt(i)==0) rc=kFALSE; } if (rc) { setChanged(pPar,oraVersion); printInfo(pPar->GetName()); } else { pPar->setInputVersion(-1,inputNumber); } return rc; } Bool_t HEmcParOra2Io::read(HEmcGeomPar* pPar, Int_t* set) { // reads the geometry of the EMC and fills the EmcGeomPar container Bool_t allFound=kTRUE; Int_t detId=-1; if (!geomVers) { detId=getDetectorId(pPar->getDetectorName()); geomVers=new HOra2GeomDetVersion(pPar->getDetectorName(),detId); } else { detId=geomVers->getDetectorId(); } if (detId<=0) { allFound=kFALSE; delete geomVers; geomVers=0; } if (detId>0&&pPar->isFirstInitialization()) { if (!readModGeomNames(pPar,set) || !readCompGeomNames(pPar,set)) { allFound=kFALSE; pPar->clear(); } else addGeomOraSet(pPar); } if (allFound) allFound=readDetectorGeometry(pPar,set,geomVers); return allFound; } Bool_t HEmcParOra2Io::readModGeomNames(HEmcGeomPar* pPar,Int_t* set) { // reads the GEANT geometry names of all modules EXEC SQL BEGIN DECLARE SECTION; struct { int sec[EMC_MAXSEC]; varchar oname[EMC_MAXSEC][9]; } mods; struct { short sec[EMC_MAXSEC]; short oname[EMC_MAXSEC]; } mods_Ind; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("readModGeomNames()"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT sector, geom_obj_name INTO :mods INDICATOR :mods_Ind FROM emc_ana2.detector_setup_at_date; Int_t nMods=sqlca.sqlerrd[2]; Int_t s; Char_t ref[10]; initModules->Reset(); for(Int_t i=0;igetModule(s,0); if (pMod && set[s]) { if (mods_Ind.oname[i]!=-1) { mods.oname[i].arr[mods.oname[i].len]='\0'; pMod->SetName((Char_t*)(mods.oname[i].arr)); initModules->AddAt(s+1,s); strcpy(ref,(Char_t*)(mods.oname[i].arr)); ref[4]='1'; // reference module in sector 1 pMod->setRefName(ref); HGeomCompositeVolume* refMod=pPar->getRefVolume(0); if (refMod==0) { refMod=new HGeomCompositeVolume(pPar->getNumComponents()); refMod->SetName(ref); pPar->addRefVolume(refMod,0); } pMod->setVolume(refMod); } } } Bool_t allFound=kTRUE; for(Int_t i=0;i0 && initModules->At(i)==0) allFound=kFALSE; } return allFound; } Bool_t HEmcParOra2Io::readCompGeomNames(HEmcGeomPar* pPar,Int_t* set) { // reads the names of all cells in the geometry tables EXEC SQL BEGIN DECLARE SECTION; struct { int cell_index[EMC_MAXGEOMCELLS]; varchar oname[EMC_MAXGEOMCELLS][9]; } lrecG; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("readCompGeomNames(...)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT cell_index, geom_obj_name INTO :lrecG FROM emc_ana2.module_cell WHERE geom_obj_name IS NOT NULL; HGeomCompositeVolume* pRefMod=pPar->getRefVolume(0); Int_t nCells=sqlca.sqlerrd[2]; Int_t cell=-1; for(Int_t k=0;kgetCompNum(cName); HGeomVolume* volu=pRefMod->getComponent(cell); if (volu) volu->SetName(cName); else { Error("readCompGeomNames","Index for cell %s not found",cName.Data()); return kFALSE; } } else { if (!sensVolume) sensVolume=new HGeomVolume(); sensVolume->SetName(cName); } } return (nCells>0) ? kTRUE : kFALSE; } void HEmcParOra2Io::addGeomRefComponents(HDetGeomPar* pPar,TList* geomObjects) { // Adds the reference modules and inner components to list of geometry objets to be read HGeomCompositeVolume* refMod=pPar->getRefVolume(0); if (refMod && refMod->getNumPoints()==0) { geomObjects->Add(new HOra2GeomObj(refMod->GetName(),refMod,'R',0)); for(Int_t l=0;lgetNumComponents();l++) { HGeomVolume* comp=refMod->getComponent(l); TString compName=comp->GetName(); if (!compName.IsNull()) { geomObjects->Add(new HOra2GeomObj(compName,comp,'I',refMod)); } } } geomObjects->Add(new HOra2GeomObj(sensVolume->GetName(),sensVolume,'C',refMod)); } Bool_t HEmcParOra2Io::transformGeomCompositeComponents(HDetGeomPar* pPar) { // Replaces the name and the points of the components GTOWx by the name and points of the // sensitive volume GLEA // IMPORTANT: The actual interface expects that the coordinate systems of the "towers" GTOWx // and GLEA including all intermediate volumes (GTOF, GTOI, GREF) are identical. Otherwise the // chain of mother volumes of GLEA must be read from Oracle to find the transformation // relative to the reference "tower" volume. HGeomCompositeVolume* refMod=pPar->getRefVolume(0); Bool_t rc=kTRUE; if (refMod && sensVolume) { TString sensVoluName=sensVolume->GetName(); Int_t nPoints=sensVolume->getNumPoints(); HGeomVolume* refComp=refMod->getComponent(0); if (sensVoluName.Length()==4 && nPoints>0 && refComp) { for(Int_t l=0;lgetNumComponents();l++) { HGeomVolume* comp=refMod->getComponent(l); TString compName=comp->GetName(); if (compName.Length()>0) { comp->SetName(compName.Replace(0,4,sensVoluName)); comp->createPoints(nPoints); for (Int_t i=0;isetPoint(i,*(sensVolume->getPoint(i))); } } } else rc=kFALSE; } else rc=kFALSE; return rc; } Int_t HEmcParOra2Io::createVers(HParSet* pPar) { // creates a new version for parameters // returns the new version cout<<"--------------- "<GetName()<<" ---------------\n"; if (strlen(pPar->getAuthor())==0) { Error("createVers(HParSet*)", "author of parameters not defined"); return -1; } if (strlen(pPar->getDescription())==0) { Error("createVers(HParSet*)", "descriction of parameters not defined"); return -1; } const Char_t* contName=pPar->IsA()->GetName(); EXEC SQL BEGIN DECLARE SECTION; int vers=-1; int context; int run; char* creator; char* descript; EXEC SQL END DECLARE SECTION; context = getContextId(contName,pPar->getParamContext()); if (context==-1) return -1; run=getActRunId(); creator=(Char_t*)pPar->getAuthor(); descript=(Char_t*)pPar->getDescription(); EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; if (strcmp(contName,"HEmcTrb3Lookup")==0) { EXEC SQL EXECUTE BEGIN SELECT emc_ana2.emc_par_query.next_version INTO :vers FROM DUAL; INSERT INTO emc_ana2.trb3lookup_vers (vers_id, orig_context_id, run_id, author, description) VALUES (:vers, :context, :run, :creator, :descript); END; END-EXEC; } else { if (strcmp(contName,"HEmcCalPar")==0) { EXEC SQL EXECUTE BEGIN SELECT emc_ana2.emc_par_query.next_version INTO :vers FROM DUAL; INSERT INTO emc_ana2.calpar_vers (vers_id, orig_context_id, run_id, author, description) VALUES (:vers, :context, :run, :creator, :descript); END; END-EXEC; } } cout<<"Oracle version for "<GetName()<<" created: "<getArrayOffset(); for(Int_t b=0;bgetSize();b++) { HEmcTrb3LookupBoard* board=(*pPar)[b]; if (board) { for(Int_t t=0;tgetSize();t++) { HEmcTrb3LookupChan& rChan=(*board)[t]; if (rChan.getSector()!=-1&&rChan.getCell()!=-1) { vers[nChan]=version; address[nChan]=arrayOffset+b; channel[nChan]=t; module[nChan]=rChan.getSector()+1; cell[nChan]=rChan.getCell(); flag[nChan]=rChan.getFlag(); // printf("HEmcParOra2Io::writePar %d- address:0x%x c:%d mod:%d cell:%d flag:%d\n", // nChan, address[nChan], channel[nChan], module[nChan], cell[nChan], flag[nChan]); nChan++; } } } } rows_to_insert=nChan; EXEC SQL WHENEVER SQLERROR GOTO errorfound; EXEC SQL WHENEVER NOT FOUND GOTO errorfound; EXEC SQL FOR :rows_to_insert INSERT INTO emc_ana2.trb3lookup_data (vers_id, trbnet_address, channel_id, cell_id, channel_flag) VALUES (:vers, :address, :channel, emc_ana2.emc_par_query.get_cell_id(:module,:cell), :flag); cout<setChanged(kFALSE); return version; errorfound: showSqlError("writePar(HEmcTrb3Lookup*)"); rollback(); pPar->setChanged(kFALSE); return -1; } Int_t HEmcParOra2Io:: writePar(HEmcCalPar* pPar) { // creates a new version and writes the calibration parameters to Oracle Int_t version=createVers(pPar); if (version==-1) return -1; EXEC SQL BEGIN DECLARE SECTION; int module[EMC_MAXSECCELLS]; int cell[EMC_MAXSECCELLS]; int vers[EMC_MAXSECCELLS]; float tdcSlope[EMC_MAXSECCELLS]; float tdcOffset[EMC_MAXSECCELLS]; float adcPar_0[EMC_MAXSECCELLS]; float adcPar_1[EMC_MAXSECCELLS]; float adcPar_2[EMC_MAXSECCELLS]; float timeWalkCorr_0[EMC_MAXCELLS]; float timeWalkCorr_1[EMC_MAXCELLS]; float timeWalkCorr_2[EMC_MAXCELLS]; int rows_to_insert; EXEC SQL END DECLARE SECTION; Int_t nCell=0; for(Int_t s=0; sgetSize(); s++) { HEmcCalParSec& rSec= (*pPar)[s]; nCell=0; for(Int_t c=0; c= EMC_MAXSECCELLS) { Error("writePar(HEmcCalPar*)","Too many cells in sector %i",s); rollback(); pPar->setChanged(kFALSE); return -1; } module[nCell]=s+1; cell[nCell]=c; vers[nCell]=version; tdcSlope[nCell]=rCell.getTdcSlope(); tdcOffset[nCell]=rCell.getTdcOffset(); adcPar_0[nCell]=rCell.getAdcPar0(); adcPar_1[nCell]=rCell.getAdcPar1(); adcPar_2[nCell]=rCell.getAdcPar2(); timeWalkCorr_0[nCell]=rCell.getTwcPar0(); timeWalkCorr_1[nCell]=rCell.getTwcPar1(); timeWalkCorr_2[nCell]=rCell.getTwcPar2(); nCell++; } } if (nCell==0) continue; rows_to_insert=nCell; EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; EXEC SQL FOR :rows_to_insert INSERT INTO emc_ana2.calpar_data (vers_id, cell_id, tdc_slope, tdc_offset, adc_par_0, adc_par_1, adc_par_2, time_walk_0, time_walk_1, time_walk_2) VALUES (:vers, emc_ana2.emc_par_query.get_cell_id(:module,:cell), :tdcSlope, :tdcOffset, :adcPar_0, :adcPar_1, :adcPar_2, :timeWalkCorr_0, :timeWalkCorr_1, :timeWalkCorr_2); cout<<"Sector "<setChanged(kFALSE); return version; not_found: showSqlError("writePar(HEmcCalPar*)"); rollback(); pPar->setChanged(kFALSE); return -1; } void HEmcParOra2Io::printInfo(const Char_t* contName) { // prints the sectors initialized from Oracle Bool_t first=kTRUE; for(Int_t i=0;iAt(i)) { if (first) { cout<