class HParamObj : public TNamed { protected: TString paramValue; char paramType; Int_t nParam; public: HParamObj() {nParam=0;} HParamObj(const Text_t*,const Text_t*,const char,const Int_t); ~HParamObj() {} void setParamValue(const Text_t* v) { paramValue=v; } void setParamType(const char t) { paramType=t; } void setNumParams(const char n) { nParam=n; } const char* getParamValue() { return paramValue.Data(); } const char getParamType() { return paramType; } Int_t getNumParams() { return nParam; } void print(); ClassDef(HParamObj,1) // Class for parameter object (name + string-value) }; class HParamList : public TObject { protected: TList* paramList; public: HParamList(); ~HParamList(); void add(HParamObj&); void add(const Text_t* name,const Text_t* value,const char type='s', const Int_t n=1); void add(const Text_t* name,const Int_t value); void add(const Text_t* name,const Long_t value); void add(const Text_t* name,const Float_t value,const Int_t precision=3); void add(const Text_t* name,const Double_t value,const Int_t precision=3); void add(const Text_t* name,TArrayI& value); void add(const Text_t* name,TArrayF& value,const Int_t precision=3); void add(const Text_t* name,TArrayD& value,const Int_t precision=3); Bool_t fill(const Text_t* name,Text_t* value,const Int_t length); Bool_t fill(const Text_t* name,Int_t* value); Bool_t fill(const Text_t* name,Long_t* value); Bool_t fill(const Text_t* name,Float_t* value); Bool_t fill(const Text_t* name,Double_t* value); Bool_t fill(const Text_t* name,TArrayI* value); Bool_t fill(const Text_t* name,TArrayF* value); Bool_t fill(const Text_t* name,TArrayD* value); void print(); HParamObj* find(const Text_t* name) { return (HParamObj*)paramList->FindObject(name); } TList* getList() { return paramList; } ClassDef(HParamList,1) // Class for list of parameters (of type HParamObj) };(See .../base/runtimedb/hparamlist.cc for implementation)
The add-functions accept a name and a value, convert the value to a string, create a new object of type HParamObj and add this object to the list.
The default precision for conversion of floats and doubles is 3. Arrays are stored as comma-separated list.
The maximum length of the string after conversion is 4000.
The fill-functions accept a name and a pointer to the data-element, find the object which this name in the list, convert the value-string to the corresponding type and and set the value(s). The functions return kFALSE, when an object with this name and type is not in the list.
For value-type Text_t* additionaly the length of the char-array must be provided to avoid storage override.
The function print() writes all parameters (name: value) to the screen.
The function putParams(HParamList*) fills all persistent data members into the list. The code must be provided by the parameter container itself.
class HParCond : public HParSet { public: HParCond(const char* name,const char* title,const char* context) : HParSet(name,title,context) {} virtual ~HParCond() {} virtual void putParams(HParamList*)=0; virtual Bool_t getParams(HParamList*)=0; virtual void printParams(); protected: HParCond() {}; ClassDef(HParCond,1) // Base class for condition containers };(See .../base/runtimedb/hparcond.cc for implementation)
The function getParams(HParamList*) fills all persistent data members from the list. If a data-element (name + type) is not found in the list, the functions return kFALSE.
Parameter containers derived from this class must implement both funtions.
The function printParams() uses internally the list and writes all parameters to the screen together with the paramContext, the author and the description.
The function readCond(HParSet* pPar, Int_t*) reads the parameters from Oracle (including version management) and can be called directly in the init-function in the detector Oracle-I/O without any addional implementation.
class HParOraCond : public TNamed { public: Int_t contextId; // Id of context Double_t versDate[2]; // Actual date range of parameters HParOraCond(const char* pName); ~HParOraCond() {} void clearVersDate(); ClassDef(HParOraCond,0) }; class HDetParOraIo : public HDetParIo { private: HOraConn* pConn; // pointer to Oracle connection class HRun* actContVers; // pointer to the actual list of container versions Int_t actRunId; // actual runId (can be -1 if there are no data in Ora cle) Double_t* geompar_date; // stores the actual date range of the geometry TList* condList; // list of conditions public: HDetParOraIo(HOraConn* p=0); virtual ~HDetParOraIo(void); void commit(void); void rollback(void); void showSqlError(const char*); Int_t getActRunId(void) { return actRunId; } Int_t getRunStart(); Int_t getPredefVersion(HParSet*); Bool_t readCond(HParCond* pPar, Int_t*); Int_t writeCond(HParCond* pPar); protected: Bool_t readGeometry(HDetGeomPar*,Int_t*); virtual Int_t readGeomVersion(Int_t); Int_t readGeomIndex(const Text_t*); Bool_t readGeomShape(HGeomVolume*, Int_t, Int_t); Int_t readGeomPoints(HGeomVolume*, Int_t, Int_t); Bool_t readGeomTransform(HGeomTransform*,Text_t*,Int_t, Int_t); HParOraCond* getCond(HParCond* pPar); Int_t getContextId(const char* className, const char* paramContext); Int_t createParamVers(HParCond* pPar); ClassDef(HDetParOraIo,0) // base class for the detector interface to Oracle };(See .../hdetparoraio.pc for implementation)
The function writeCond(HParSet* pPar) writes the parameters to the Load-tables in Oracle (further processing with the WebDb interface).
The class and its parameter context must exist already in Oracle. New classes/contexts can be added with the WebDb interface.
2. In the implementation of class HRichParOraIo the following lines were added:
... class HParamList; class HRichAnalysisPar: public HParCond { ... public: HRichAnalysisPar(const char* name="RichAnalysisParameters", const char* title="Rich Analysis Parameters", const char* context="RichAnaNormalBias"); ... void putParams(HParamList*); Bool_t getParams(HParamList*); Bool_t readAscii(HDetParAsciiFileIo*); Int_t writeAscii(HDetParAsciiFileIo*); ... }(See .../rich/hrichanalysispar.h for complete class definition.) The corresponding implementation of the functions putParams(HParamList*) and getParams(HParamList*) contains one line for each persistent data-element. ... #include "hparamlist.h" ... HRichAnalysisPar::HRichAnalysisPar(const char* name,const char* title, const char* context) : HParCond(name,title,context) { strcpy(detName,"Rich"); clear(); } ... void HRichAnalysisPar::putParams(HParamList* l) { if (!l) return; l->add("iCutOffThresheold",iCutOffThresheold); l->add("iRingRadius",iRingRadius); ... l->add("iHowManyHoughTransfRings",iHowManyHoughTransfRings); } Bool_t HRichAnalysisPar::getParams(HParamList* l) { if (!l) return kFALSE; if (!l->fill("iCutOffThresheold",&iCutOffThresheold)) return kFALSE; if (!l->fill("iRingRadius",&iRingRadius)) return kFALSE; ... if (!l->fill("iHowManyHoughTransfRings",&iHowManyHoughTransfRings)) return kFALSE; return kTRUE; } Bool_t HRichAnalysisPar::readAscii(HDetParAsciiFileIo* io) { return io->readCond(this); } Int_t HRichAnalysisPar::writeAscii(HDetParAsciiFileIo* io) { return io->writeCond(this); }(See .../rich/hrichanalysispar.cc for complete code.) Remark: The RICH does normally not support the HParAsciiFileIo, but uses HParHadAsciiFileIo. The code for containers derived from HParCond can be fully implemented in the base class and I have (only) done this for the HParAsciiFileIo. For testing I added the functions also in HRichAnalysisPar, but maybe they will not be part of the final CVS version.
... #include "hparcond.h" #include "hparamlist.h" ... Bool_t HRichParOraIo::init(HParSet* pPar,Int_t* set) { ... if (strncmp(name,"RichAnalysisParameters",strlen("RichAnalysisParameters")==0) return readCond((HParCond*)pPar,set); ... } Int_t HRichParOraIo::write(HParSet* pPar) { ... if (strncmp(name,"RichAnalysisParameters",strlen("RichAnalysisParameters"))==0) return writeCond((HParCond*)pPar); ... }
{ // ROOT-macro to read Rich Analysis parameters from Oracle // Reads two different Contexts for the same runs and writes them to a ROOT // file Hades* myHades=new Hades; HRuntimeDb* rtdb=gHades->getRuntimeDb(); HSpectrometer* spec=gHades->getSetup(); HRichDetector* rich=new HRichDetector; spec->addDetector(rich); HParOraIo* inp1=new HParOraIo; inp1->open(); rtdb->setFirstInput(inp1); HParRootFileIo* output=new HParRootFileIo; output->open("tmp.root","RECREATE"); rtdb->setOutput(output); //////////////////////////////// RICH //////////////////////////////////////// rtdb->addParamContext("RichAnaHighBias"); HRichAnalysisPar* p=(HRichAnalysisPar*)(rtdb->getContainer("RichAnalysisParameters")); // Second version with defaults: context = RichNormalBias HRichAnalysisPar* pm=new HRichAnalysisPar; rtdb->addContainer(pm); if (!rtdb->initContainers(1007785790)) return; p->print(); p->printParams(); pm->print(); pm->printParams(); if (!rtdb->initContainers(1007786191)) return; //////////////////////////////////////////////////////////////////////////////// rtdb->saveOutput(); rtdb->print(); delete myHades; }
{ // ROOT-macro to write Rich Correlator parameters to Oracle Hades* myHades=new Hades; HRuntimeDb* rtdb=gHades->getRuntimeDb(); HSpectrometer* spec=gHades->getSetup(); HRichDetector* rich=new HRichDetector; spec->addDetector(rich); HParHadAsciiFileIo input; // ASCII input input.open("/u/fabietti/hydra542/params/corrSharpPhiWideTheta.txt","READ"); rtdb->setFirstInput(&input); HParOraIo* output=new HParOraIo; output->open("rich_ana"); rtdb->setOutput(output); //////////////////////////////// RICH //////////////////////////////////////// // The old ROOT file does not support a context, therefore the container // factory cannot be used. It would set the name to // RichCorrelatorParameters_RichCorrSharpPhiWideThe rtdb->addParamContext("RichCorrSharpPhiWideThe"); HRichCorrelatorPar* p=(HRichCorrelatorPar*)(rtdb->getContainer("RichCorrelatorParameters")); if (!rtdb->initContainers(1)) return; p->print(); p->printParam(); p->setAuthor("Laura Fabbietti"); p->setDescription("Correlator parameters with wide Theta and sharp Phi cuts (experimental data)"); p->write(); //////////////////////////////////////////////////////////////////////////////// delete myHades; }