diff --git a/.gitmodules b/.gitmodules index d73dcf1..3412076 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,12 @@ [submodule "lz4"] path = lz4 url = https://github.com/lz4/lz4.git +[submodule "ccdb"] + path = ccdb + url = https://github.com/JeffersonLab/ccdb.git +[submodule "rcdb"] + path = rcdb + url = https://github.com/JeffersonLab/rcdb +[submodule "clasqaDB"] + path = clasqaDB + url = https://github.com/JeffersonLab/clasqaDB diff --git a/CMakeLists.txt b/CMakeLists.txt index a40790f..4c78113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,15 +37,15 @@ add_definitions(-D__LZ4__) set(CMAKE_INSTALL_INCLUDEDIR ${CMAKE_CURRENT_SOURCE_DIR}/include) #include clasqaDB c++ library and rapidjson library -IF (DEFINED ENV{CLASQADB_HOME}) +IF (DEFINED ENV{QADB}) - include_directories($ENV{CLASQADB_HOME}/srcC/rapidjson/include) - include_directories($ENV{CLASQADB_HOME}/srcC/include) + include_directories($ENV{QADB}/srcC/rapidjson/include) + include_directories($ENV{QADB}/srcC/include) #clasqaDB header contains function definitions which are not inlined #including this header causes multiple definitions of these functions set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition") add_definitions(-DCLAS_QADB) -ENDIF (DEFINED ENV{CLASQADB_HOME}) +ENDIF (DEFINED ENV{QADB}) diff --git a/Clas12Banks/CMakeLists.txt b/Clas12Banks/CMakeLists.txt index 0292426..e600759 100644 --- a/Clas12Banks/CMakeLists.txt +++ b/Clas12Banks/CMakeLists.txt @@ -1,21 +1,21 @@ -set(CLASS_LIST_CPP helflip.cpp helonline.cpp runconfig.cpp event.cpp ftbevent.cpp particle.cpp ftbparticle.cpp mcparticle.cpp scaler.cpp vtp.cpp particle_detector.cpp scintillator.cpp tracker.cpp traj.cpp forwardtagger.cpp cherenkov.cpp calorimeter.cpp covmatrix.cpp region_particle.cpp region_ft.cpp region_fdet.cpp region_cdet.cpp region_band.cpp clas12writer.cpp clas12reader.cpp mesonex_trigger.cpp scaler_reader.cpp clas12databases.cpp qadb_reader.cpp ccdb_reader.cpp rcdb_reader.cpp) +set(CLASS_LIST_CPP helflip.cpp helonline.cpp runconfig.cpp event.cpp ftbevent.cpp particle.cpp ftbparticle.cpp mcparticle.cpp mcevent.cpp mcmatch.cpp scaler.cpp vtp.cpp particle_detector.cpp scintillator.cpp scintextras.cpp tracker.cpp traj.cpp forwardtagger.cpp cherenkov.cpp calorimeter.cpp covmatrix.cpp region_particle.cpp region_ft.cpp region_fdet.cpp region_cdet.cpp region_band.cpp clas12writer.cpp clas12reader.cpp mesonex_trigger.cpp scaler_reader.cpp clas12databases.cpp qadb_reader.cpp ccdb_reader.cpp rcdb_reader.cpp) -set(CLASS_LIST_H helflip.h helonline.h runconfig.h event.h ftbevent.h particle.h ftbparticle.h mcparticle.h scaler.h vtp.h particle_detector.h scintillator.h tracker.h traj.h forwardtagger.h cherenkov.h calorimeter.h covmatrix.h region_particle.h region_ft.h region_fdet.h region_cdet.h region_band.h clas12writer.h clas12reader.h mesonex_trigger.h scaler_reader.h clas12databases.h qadb_reader.h ccdb_reader.h rcdb_reader.h) +set(CLASS_LIST_H helflip.h helonline.h runconfig.h event.h ftbevent.h particle.h ftbparticle.h mcparticle.h mcevent.h mcmatch.h scaler.h vtp.h particle_detector.h scintillator.h scintextras.h tracker.h traj.h forwardtagger.h cherenkov.h calorimeter.h covmatrix.h region_particle.h region_ft.h region_fdet.h region_cdet.h region_band.h clas12writer.h clas12reader.h mesonex_trigger.h scaler_reader.h clas12databases.h qadb_reader.h ccdb_reader.h rcdb_reader.h) -IF (DEFINED ENV{CLASQADB_HOME}) +IF (DEFINED ENV{QADB}) set(CLASS_LIST_CPP ${CLASS_LIST_CPP} jsonFileMerger.cpp) set(CLASS_LIST_H ${CLASS_LIST_H} jsonFileMerger.h) add_definitions(-DCLAS_QADB) -ENDIF (DEFINED ENV{CLASQADB_HOME}) +ENDIF (DEFINED ENV{QADB}) #include rcdb c++ header library IF (DEFINED ENV{CCDB_HOME}) # CCDB related include_directories($ENV{CCDB_HOME}/include) - link_libraries($ENV{CCDB_HOME}/lib/libccdb.so) + link_libraries($ENV{CCDB_HOME}/lib/libccdb${CMAKE_SHARED_LIBRARY_SUFFIX}) add_definitions(-DCLAS_CCDB) ENDIF (DEFINED ENV{CCDB_HOME}) @@ -69,9 +69,11 @@ target_link_libraries(Clas12Banks ${ROOT_LIBRARIES} Hipo4) install(TARGETS Clas12Banks LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") -FILE(GLOB ROOT_CLAS12_PCM ${CMAKE_BINARY_DIR}/Clas12Banks/*pcm) +#FILE(GLOB ROOT_CLAS12_PCM ${CMAKE_BINARY_DIR}/Clas12Banks/*pcm) -install (FILES ${ROOT_CLAS12_PCM} - DESTINATION "${CMAKE_INSTALL_LIBDIR}") +#install (FILES ${ROOT_CLAS12_PCM} +# DESTINATION "${CMAKE_INSTALL_LIBDIR}") +install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libClas12Banks_rdict.pcm + DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/Clas12Banks/ccdb_reader.cpp b/Clas12Banks/ccdb_reader.cpp index 8cdbd92..167ca37 100644 --- a/Clas12Banks/ccdb_reader.cpp +++ b/Clas12Banks/ccdb_reader.cpp @@ -1,5 +1,7 @@ #include "ccdb_reader.h" #include +#include + namespace clas12 { @@ -16,6 +18,7 @@ namespace clas12 { ccdb::CalibrationGenerator gen; _calib.reset( gen.MakeCalibration(_path, 0, "default", 0 ) ); + #endif } @@ -46,6 +49,41 @@ namespace clas12 { #endif + double ccdb_reader::requestTableValueFor(int row,const std::string& item,const std::string& tableName){ + + const TableOfDoubles_t* table=nullptr; + + //Find the requested table + auto it = std::find_if(_localTable.begin(),_localTable.end(), + [&tableName](const TableRecord_t& element) + { return element.first == tableName;} ); + if(it==_localTable.end()){ + //need to create table + table = &requestTableDoubles(tableName); + } + + else table=&(it->second); + + //Find the column index for this item in this table + auto ipos=requestTableEntryFor(item,tableName); + if(ipos<0){ + std::cerr<<" ccdb_reader::requestTableValueFor no "<at(row)[ipos]; + + } + int ccdb_reader::requestTableEntryFor(const std::string& item,const std::string& tableName){ + + int entry=-1; +#ifdef CLAS_CCDB + const auto& columns = _calib->GetAssignment(tableName)->GetTypeTable()->GetColumnNames(); + entry= std::distance( + columns.begin(), + std::find(columns.begin(), columns.end(), item) ); +#endif + return entry; + } const TableOfDoubles_t& ccdb_reader::requestTableDoubles(std::string tableName){ /* Get a table from the database, will reconnect to database automatically diff --git a/Clas12Banks/ccdb_reader.h b/Clas12Banks/ccdb_reader.h index 9a0dc79..8ea0932 100644 --- a/Clas12Banks/ccdb_reader.h +++ b/Clas12Banks/ccdb_reader.h @@ -47,6 +47,8 @@ namespace clas12 { public: const TableOfDoubles_t& requestTableDoubles(std::string tableName); void updateTables(); + int requestTableEntryFor(const std::string& item,const std::string& tableName); + double requestTableValueFor(int row,const std::string& item,const std::string& tableName); private: @@ -55,8 +57,6 @@ namespace clas12 { #ifdef CLAS_CCDB std::unique_ptr _calib ={nullptr}; - - #endif diff --git a/Clas12Banks/clas12databases.cpp b/Clas12Banks/clas12databases.cpp index 095e7e6..916409e 100644 --- a/Clas12Banks/clas12databases.cpp +++ b/Clas12Banks/clas12databases.cpp @@ -7,9 +7,9 @@ namespace clas12 { string clas12databases::_RcdbPath=""; string clas12databases::_CcdbPath=""; - string clas12databases::_QadbPath=""; + //string clas12databases::_QadbPath=""; - void clas12databases::SetQADBConnection(const string& name){_QadbPath=FullPath(name);} + //void clas12databases::SetQADBConnection(const string& name){_QadbPath=FullPath(name);} void clas12databases::SetCCDBLocalConnection(const string& name){_CcdbPath="sqlite://"+FullPath(name);} void clas12databases::SetCCDBRemoteConnection(){_CcdbPath="mysql://clas12reader@clasdb.jlab.org/clas12";} void clas12databases::SetRCDBLocalConnection(const string& name){_RcdbPath="sqlite://"+FullPath(name);} @@ -24,13 +24,14 @@ namespace clas12 { clas12databases::clas12databases() { - std::cout<<"clas12databases() rcdb path "<<_RcdbPath<<" "<<_myRcdbPath<{TFile::Open(filename,"recreate")}; - - auto nfiles=chain.GetNFiles(); - //loop over files and get the rcdb data - for(auto i=0;i{new clas12root::TRcdbVals(_rcdb->readAll(runNb,runName))}; - vals->Write(); - } - - rcdbFile->ls(); - - } - */ - /* - //////////////////////////////////////////////////////////// - ///Get a copy of the rcdb values for run number runNb, - ///from file fname created previously by WriteRcdbData - clas12::rcdb_vals HipoChain::fetchRunRcdb(const TString& datafile){ - - //make file and list unique_ptr so deleted when we return - auto rcdbFile=std::unique_ptr{TFile::Open(_rcdbFileName)}; - if(rcdbFile.get()==nullptr){ - Warning("HipoChain::FetchRunRcdb ",Form("No rcdb root file provided to the chain : %s",_rcdbFileName.Data()),""); - return rcdb_vals(); - } - auto keys= rcdbFile->GetListOfKeys(); - for(const auto& key:*keys){ - //the rcdb_vals Title is mapped to the data file name - auto baseName = gSystem->BaseName(datafile);//use base name in case user copies data to temp directory - if(TString(key->GetTitle())==TString(baseName)){ - auto vals=std::unique_ptr{dynamic_cast(rcdbFile->Get(key->GetName()))}; - if(vals.get()) - return vals.get()->_data; - } - } - Warning("HipoChain::FetchRunRcdb ",Form("run file %s not found in list in file %s",datafile.Data(),_rcdbFileName.Data()),""); - - //no rcdb - return rcdb_vals(); - } - */ } diff --git a/Clas12Banks/clas12databases.h b/Clas12Banks/clas12databases.h index fd81cc7..4b56194 100644 --- a/Clas12Banks/clas12databases.h +++ b/Clas12Banks/clas12databases.h @@ -26,7 +26,7 @@ namespace clas12 { //where to make database connections static string _RcdbPath;//! static string _CcdbPath;//! - static string _QadbPath;//! + //static string _QadbPath;//! public: @@ -40,7 +40,7 @@ namespace clas12 { void notifyRun(int runNb); - static void SetQADBConnection(const string& name); + //static void SetQADBConnection(const string& name); static void SetCCDBLocalConnection(const string& name); static void SetCCDBRemoteConnection(); static void SetRCDBLocalConnection(const string& name); @@ -57,7 +57,7 @@ namespace clas12 { const string& ccdbPath() const {return _myCcdbPath;} const string& rcdbPath() const {return _myRcdbPath;} - const string& qadbPath() const {return _myQadbPath;} + //const string& qadbPath() const {return _myQadbPath;} @@ -65,18 +65,19 @@ namespace clas12 { //I would rather this was not needed here //but it is to make sure it gets passed to PROOF void qadb_addQARequirement(string req){ _qadb->addQARequirement(req);_qadbReqsQA.push_back(req);}; - void qadb_setQARequirements( std::vector reqs){_qadb->setQARequirements(reqs); _qadbReqsQA = reqs; }; + void qadb_setQARequirements( std::vector reqs){_qadb->setQARequirements(reqs); _qadbReqsQA = reqs;}; void qadb_requireOkForAsymmetry(bool ok){_qadb->requireOkForAsymmetry(ok);_qadbReqOKAsymmetry=ok;}; void qadb_requireGolden(bool ok){_qadb->requireGolden(ok);_qadbReqGolden=ok;}; - + void setVerbose(short level=1){_verbose=level;} + private: //names for copying to ROOT file for selector string _myRcdbPath; string _myCcdbPath; - string _myQadbPath; + //string _myQadbPath; int _runNb={0};//! @@ -92,6 +93,7 @@ namespace clas12 { bool _qadbReqOKAsymmetry{false}; bool _qadbReqGolden{false}; + short _verbose={0}; }; diff --git a/Clas12Banks/clas12reader.cpp b/Clas12Banks/clas12reader.cpp index 20b6e62..de6f97f 100644 --- a/Clas12Banks/clas12reader.cpp +++ b/Clas12Banks/clas12reader.cpp @@ -12,7 +12,7 @@ namespace clas12 { clas12reader::clas12reader(std::string filename,std::vector tags): _filename(filename){ - cout<<" clas12reader::clas12reader reading "<getExtras())_event.getStructure(*_bscint->getExtras()); if(_btrck.get())_event.getStructure(*_btrck.get()); if(_btraj.get())_event.getStructure(*_btraj.get()); if(_bcher.get())_event.getStructure(*_bcher.get()); if(_bft.get())_event.getStructure(*_bft.get()); if(_bvtp.get())_event.getStructure(*_bvtp.get()); if(_bhelonline.get())_event.getStructure(*_bhelonline.get()); - //if(_bscal.get())_event.getStructure(*_bscal.get()); - + + if(_bmcparts.get()){ + _event.getStructure(*_bmcparts.get()); + if(_bmcevent.get())_event.getStructure(*_bmcevent.get()); + if(_bmcparts->getMatch())_event.getStructure(*_bmcparts->getMatch()); + } + for(auto& ibank:_addBanks){//if any additional banks requested get those _event.getStructure(*ibank.get()); } @@ -452,7 +475,7 @@ namespace clas12 { // if(_runNo==0){ _runNo=readQuickRunConfig(_filename); //} - std::cout<<"Connecting databases to run "<<_runNo<notifyRun(_runNo); } ///////////////////////////////////////////////////////// @@ -465,6 +488,7 @@ namespace clas12 { if(_bparts.get())_allBanks.push_back(_bparts.get()); if(_bftbparts.get())_allBanks.push_back(_bftbparts.get()); if(_bmcparts.get())_allBanks.push_back(_bmcparts.get()); + if(_bmcevent.get())_allBanks.push_back(_bmcevent.get()); if(_bcovmat.get())_allBanks.push_back(_bcovmat.get()); if(_bevent.get())_allBanks.push_back(_bevent.get()); if(_bftbevent.get())_allBanks.push_back(_bftbevent.get()); diff --git a/Clas12Banks/clas12reader.h b/Clas12Banks/clas12reader.h index 1dc26e3..b1f172d 100644 --- a/Clas12Banks/clas12reader.h +++ b/Clas12Banks/clas12reader.h @@ -13,6 +13,7 @@ #include "particle.h" #include "ftbparticle.h" #include "mcparticle.h" +#include "mcevent.h" #include "calorimeter.h" #include "scintillator.h" #include "tracker.h" @@ -81,26 +82,26 @@ namespace clas12 { void addARegionFDet(){ //Forward detector needs particles, calorimeter, scintillator, //track, cherenkov - region_fdet_uptr reg{new region_fdet{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get()}}; + region_fdet_uptr reg{new region_fdet{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get(),_bmcparts.get()}}; if(_useFTBased)reg->useFTBPid(); _rfdets.push_back(std::move(reg)); } void addARegionCDet(){ //Forward detector needs particles, calorimeter, scintillator, //track, cherenkov - region_cdet_uptr reg{new region_cdet{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get()}}; + region_cdet_uptr reg{new region_cdet{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get(),_bmcparts.get()}}; if(_useFTBased)reg->useFTBPid(); _rcdets.push_back(std::move(reg)); } void addARegionFT(){ //Forward tagger needs particles and forward tagger - region_ft_uptr reg{new region_ft{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get()}}; + region_ft_uptr reg{new region_ft{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get(),_bmcparts.get()}}; if(_useFTBased)reg->useFTBPid(); _rfts.push_back(std::move(reg)); } void addARegionBAND(){ //Forward tagger needs particles and forward tagger - region_band_uptr reg{new region_band{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get()}}; + region_band_uptr reg{new region_band{_bparts.get(),_bftbparts.get(),_bcovmat.get(),_bcal.get(),_bscint.get(),_btrck.get(),_btraj.get(),_bcher.get(),_bft.get(),_bevent.get(),_bmcparts.get()}}; if(_useFTBased)reg->useFTBPid(); _rbands.push_back(std::move(reg)); } @@ -112,14 +113,17 @@ namespace clas12 { event_ptr event() const{return _bevent.get();}; ftbevent_ptr ftbevent() const{return _bftbevent.get();}; vtp_ptr vtp() const{return _bvtp.get();}; - //scaler_ptr scaler() const{return _bscal.get();}; + + mcpar_ptr mcparts() const{return _bmcparts.get();}; + mcevt_ptr mcevent() const{return _bmcevent.get();}; //support for generic non-DST banks - uint addBank(std::string name){ + uint addBank(const std::string& name){ std::unique_ptr bnk{new hipo::bank{_factory.getSchema(name.data())}}; _addBanks.push_back(std::move(bnk)); + _addBankNames.push_back(name); return _addBanks.size()-1; //return place in vector } @@ -170,11 +174,17 @@ namespace clas12 { _runBeamCharge = _scalReader->getBeamCharge(); return _scalReader.get(); } - double getRunBeamCharge() const noexcept{ return _runBeamCharge;} + double getRunBeamCharge() { + if(_db!=nullptr) + if(db()->qa()!=nullptr) return db()->qa()->getAccCharge(); + return _runBeamCharge; + } double getCurrApproxCharge(){return _runBeamCharge*_nevent/_reader.getEntries();} void summary(){ - std::cout<<"for file "<<_filename<<"\n read "<<_nevent<<" events from which "<<_nselected<< " passed filtering conditions."<<" The beam charge to this point in the file was "<qa())cout<<"Accumulated charge past QA: "<qa()->getAccCharge()<<" nC"< _ownbparts; ftbpar_uptr _bftbparts;//! - mcpar_uptr _bmcparts;//! covmat_uptr _bcovmat;//! cal_uptr _bcal;//! scint_uptr _bscint;//! @@ -229,6 +242,8 @@ namespace clas12 { ft_uptr _bft;//! vtp_uptr _bvtp;//! + mcpar_uptr _bmcparts;//! + mcevt_uptr _bmcevent;//! std::vector > _addBanks; //!owns additional banks @@ -256,6 +271,8 @@ namespace clas12 { ushort _n_rfts{0}; ushort _n_rbands{0}; + ushort _verbose{0}; + std::vector _pids; bool _isRead{false}; //bool _rcdbQueried=false; @@ -267,7 +284,7 @@ namespace clas12 { std::map _pidSelectExact; bool _zeroOfRestPid{false}; bool _useFTBased{false}; - + std::vector _addBankNames; ///////////////////////////////DB private: @@ -287,7 +304,7 @@ namespace clas12 { rcdb_reader* rcdb()const {return _db->rc();} qadb_reader* qadb()const {return _db->qa();} - clas12databases& db(){return *_db;}; + clas12databases* db(){return _db;}; //clasqaDB void applyQA() { @@ -299,11 +316,7 @@ namespace clas12 { std::cout<<"Warning, clas12reader applyQA() not valid"< +#include + +namespace clas12 { + + class mcevent : public hipo::bank { + + + public: + + mcevent() = default; + + mcevent(hipo::schema __schema); + + virtual ~mcevent() = default; + + + + int getNpart() const noexcept { return getShort(_npart_order,_entry);} + int getAtarget() const noexcept { return getShort(_atarget_order,_entry);} + int getZtarget() const noexcept { return getShort(_ztarget_order,_entry);} + float getPtarget() const noexcept { return getFloat(_ptarget_order,_entry);} + float getPbeam() const noexcept { return getFloat(_pbeam_order,_entry);} + float getEbeam() const noexcept { return getFloat(_ebeam_order,_entry);} + int getBtype() const noexcept { return getShort(_btype_order,_entry);} + int getTargetid() const noexcept { return getShort(_targetid_order,_entry);} + int getProcessid() const noexcept { return getShort(_processid_order,_entry);} + float getWeight() const noexcept { return getShort(_weight_order,_entry);} + + + //void setEntry(short i){ _entry=i;} + // void setBankEntry(short i){ _entry=i;} //faster for BankHist + short getEntry() const noexcept{return _entry;} + /** + * This is virtual method from hipo::bank it will be called + * every time a bank is read in the reader. Can be used to sort + * mcevents and or map mcevents by pid or type (i.e. charge) + */ + void notify() final { + bank::notify(); + } + + private: + + int _npart_order{-1}; + int _atarget_order{-1}; + int _ztarget_order{-1}; + int _ptarget_order{-1}; + int _pbeam_order{-1}; + int _btype_order{-1}; + int _ebeam_order{-1}; + int _targetid_order{-1}; + int _processid_order{-1}; + int _weight_order{-1}; + + + + short _entry={0}; + + }; + + using mcevt_ptr=clas12::mcevent*; + using mcevt_uptr=std::unique_ptr; + +} + +#endif /* UTILS_H */ diff --git a/Clas12Banks/mcmatch.cpp b/Clas12Banks/mcmatch.cpp new file mode 100644 index 0000000..e2d17b3 --- /dev/null +++ b/Clas12Banks/mcmatch.cpp @@ -0,0 +1,57 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +#include "mcmatch.h" + +#include + +namespace clas12 { + + mcmatch::mcmatch(hipo::schema __schema): hipo::bank(__schema) { + _mcTindex_order = __schema.getEntryOrder("mcTindex"); + _pindex_order = __schema.getEntryOrder("pindex"); + _mclayerstrk_order= __schema.getEntryOrder("MCLayersTrk"); + _mclayersneut_order= __schema.getEntryOrder("MCLayersNeut"); + _reclayerstrk_order= __schema.getEntryOrder("RecLayersTrk"); + _reclayersneut_order= __schema.getEntryOrder("RecLayersNeut"); + } + + + int mcmatch::getIndex(int pindex){ + std::vector::iterator it; + if((it=std::find(_rvec.begin(),_rvec.end(),pindex))!=_rvec.end()){ + _index = std::distance(_rvec.begin(), it); + return _index; + } + return _index=-1; + } + + + void mcmatch::scanIndex(){ + _rvec.clear(); + const int size = getRows(); + _rvec.reserve(size); + for(int i = 0; i < size; i++){ + int pindex = getPindex(i); + _rvec.emplace_back(pindex); + } + } + + bool mcmatch::checkFDSuperLayers(const short nMinSL, const short nMinLayerPerSL) const noexcept { + auto pattern=getMCLayersTrk(); + short isSuper = 0; + for(uint isu=0;isu<6;++isu){//6 superlayers + short isLay = 0; + for(uint ilay=0;ilay<6;++ilay){//6 layers + isLay+=static_cast(checkBit(pattern,isu*6+ilay)); + } + if(isLay>=nMinLayerPerSL) ++isSuper;//at least 4 layers + } + if(isSuper>=nMinSL) return true; //at least 5 superlayers + return false; + } + +} diff --git a/Clas12Banks/mcmatch.h b/Clas12Banks/mcmatch.h new file mode 100644 index 0000000..bc698e7 --- /dev/null +++ b/Clas12Banks/mcmatch.h @@ -0,0 +1,101 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: mcmatch.h + * Author: dglazier + * + */ + +#ifndef MCMATCH_H +#define MCMATCH_H + +#include "bank.h" +#include +#include + +namespace clas12 { + + class mcmatch : public hipo::bank { + + + public: + + mcmatch() = default; + + mcmatch(hipo::schema __schema); + + ~mcmatch() override = default; + + + /* + int getMCTindex(int index) const noexcept { return getShort(_mcTindex_order,index);} + int getRecTindex(int index) const noexcept { return getShort(_recTindex_order,index);} + int getPindex(int index) const noexcept { return getShort(_pindex_order,index);} + */ + + short getMCTindex() const noexcept { return getShort(_mcTindex_order,_index);} + short getPindex() const noexcept { return getShort(_pindex_order,_index);} + + //bit patterns + long getMCLayersTrk() const noexcept { return getLong(_mclayerstrk_order,_index);} + long getMCLayersNeut() const noexcept { return getLong(_mclayersneut_order,_index);} + long getRecLayersTrk() const noexcept { return getLong(_reclayerstrk_order,_index);} + long getRecLayersNeut() const noexcept { return getLong(_reclayersneut_order,_index);} + + + int getPindex(int index) const noexcept { return getShort(_pindex_order,index);} + + bool checkBitInPattern(uint k) const noexcept { + return checkBit(getMCLayersTrk(),k); + } + bool checkBit(long word, uint k) const noexcept { + return ( (word >> k) & 1 )!=0; + } + + bool checkFDSuperLayers(const short nMinSL, const short nMinLayerPerSL) const noexcept ; + + + void setEntry(short i){ _index=i;} + void setBankEntry(short i){ _index=i;} //faster for BankHist + short getEntry() const noexcept{return _index;} + + int getIndex() const noexcept{return _index;} + int getIndex(int pindex); + + /** + * This is virtual method from hipo::bank it will be called + * every time a bank is read in the reader. Can be used to sort + * mcmatchs and or map mcmatchs by pid or type (i.e. charge) + */ + void notify() final { + bank::notify(); + scanIndex(); + } + + void scanIndex(); + + private: + + int _mcTindex_order{-1}; + int _pindex_order{-1}; + int _mclayerstrk_order{-1}; + int _mclayersneut_order{-1}; + int _reclayerstrk_order{-1}; + int _reclayersneut_order{-1}; + + std::vector _rvec{}; + + short _index={0}; + + }; + + using mcmatch_ptr=clas12::mcmatch*; + using mcmatch_uptr=std::unique_ptr; + +} + +#endif /* UTILS_H */ diff --git a/Clas12Banks/mcparticle.cpp b/Clas12Banks/mcparticle.cpp index b385b48..e97a27a 100644 --- a/Clas12Banks/mcparticle.cpp +++ b/Clas12Banks/mcparticle.cpp @@ -9,15 +9,41 @@ namespace clas12 { - mcparticle::mcparticle(hipo::schema __schema): hipo::bank(__schema) { - pid_order = __schema.getEntryOrder("pid"); - px_order = __schema.getEntryOrder("px"); - py_order = __schema.getEntryOrder("py"); - pz_order = __schema.getEntryOrder("pz"); - vx_order = __schema.getEntryOrder("vx"); - vy_order = __schema.getEntryOrder("vy"); - vz_order = __schema.getEntryOrder("vz"); - mass_order = __schema.getEntryOrder("mass"); + mcparticle::mcparticle(hipo::schema aschema,hipo::schema schmatch): + hipo::bank(aschema), + _match{new mcmatch{schmatch}} + { + _pid_order = aschema.getEntryOrder("pid"); + _px_order = aschema.getEntryOrder("px"); + _py_order = aschema.getEntryOrder("py"); + _pz_order = aschema.getEntryOrder("pz"); + _vx_order = aschema.getEntryOrder("vx"); + _vy_order = aschema.getEntryOrder("vy"); + _vz_order = aschema.getEntryOrder("vz"); + _mass_order = aschema.getEntryOrder("mass"); + _type_order = aschema.getEntryOrder("type"); + _life_order = aschema.getEntryOrder("lifetime"); + _index_order = aschema.getEntryOrder("index"); + _parent_order = aschema.getEntryOrder("parent"); + _daughter_order = aschema.getEntryOrder("daughter"); + + + } + mcparticle::mcparticle(hipo::schema aschema): hipo::bank(aschema) { + _pid_order = aschema.getEntryOrder("pid"); + _px_order = aschema.getEntryOrder("px"); + _py_order = aschema.getEntryOrder("py"); + _pz_order = aschema.getEntryOrder("pz"); + _vx_order = aschema.getEntryOrder("vx"); + _vy_order = aschema.getEntryOrder("vy"); + _vz_order = aschema.getEntryOrder("vz"); + _mass_order = aschema.getEntryOrder("mass"); + _type_order = aschema.getEntryOrder("type"); + _life_order = aschema.getEntryOrder("life"); + _index_order = aschema.getEntryOrder("index"); + _parent_order = aschema.getEntryOrder("parent"); + _daughter_order = aschema.getEntryOrder("daughter"); + } diff --git a/Clas12Banks/mcparticle.h b/Clas12Banks/mcparticle.h index afc6f89..960d6fa 100644 --- a/Clas12Banks/mcparticle.h +++ b/Clas12Banks/mcparticle.h @@ -6,15 +6,15 @@ /* * File: mcparticle.h - * Author: gavalian + * Author: dglazier * - * Created on April 27, 2017, 10:01 AM */ #ifndef MCPARTICLE_H #define MCPARTICLE_H #include "bank.h" +#include "mcmatch.h" #include #include @@ -27,48 +27,68 @@ namespace clas12 { mcparticle() = default; - mcparticle(hipo::schema __schema); + mcparticle(hipo::schema aschema); + mcparticle(hipo::schema aschema,hipo::schema schmatch); virtual ~mcparticle() = default; - int getPid(int index) const noexcept { return getInt(pid_order,index);} - float getPx(int index) const noexcept { return getFloat(px_order,index);} - float getPy(int index) const noexcept { return getFloat(py_order,index);} - float getPz(int index) const noexcept { return getFloat(pz_order,index);} - float getVx(int index) const noexcept { return getFloat(vx_order,index);} - float getVy(int index) const noexcept { return getFloat(vy_order,index);} - float getVz(int index) const noexcept { return getFloat(vz_order,index);} - float getMass(int index) const noexcept { return getFloat(mass_order,index);} - - int getPid() const noexcept { return getInt(pid_order,_entry);} - float getPx() const noexcept { return getFloat(px_order,_entry);} - float getPy() const noexcept { return getFloat(py_order,_entry);} - float getPz() const noexcept { return getFloat(pz_order,_entry);} - float getVx() const noexcept { return getFloat(vx_order,_entry);} - float getVy() const noexcept { return getFloat(vy_order,_entry);} - float getVz() const noexcept { return getFloat(vz_order,_entry);} - float getMass() const noexcept { return getFloat(mass_order,_entry);} + int getPid(int index) const noexcept { return getInt(_pid_order,index);} + float getPx(int index) const noexcept { return getFloat(_px_order,index);} + float getPy(int index) const noexcept { return getFloat(_py_order,index);} + float getPz(int index) const noexcept { return getFloat(_pz_order,index);} + float getVx(int index) const noexcept { return getFloat(_vx_order,index);} + float getVy(int index) const noexcept { return getFloat(_vy_order,index);} + float getVz(int index) const noexcept { return getFloat(_vz_order,index);} + float getMass(int index) const noexcept { return getFloat(_mass_order,index);} + int getIndex(int index) const noexcept { return getByte(_index_order,index);} + int getType(int index) const noexcept { return getByte(_type_order,index);} + int getParent(int index) const noexcept { return getByte(_parent_order,index);} + int getDaughter(int index) const noexcept { return getByte(_daughter_order,index);} + float getLifetime(int index) const noexcept { return getFloat(_life_order,index);} + + int getPid() const noexcept { return _entry==-1 ? 0: getInt(_pid_order,_entry);} + float getPx() const noexcept { return _entry==-1 ? 0: getFloat(_px_order,_entry);} + float getPy() const noexcept { return _entry==-1 ? 0: getFloat(_py_order,_entry);} + float getPz() const noexcept { return _entry==-1 ? 0: getFloat(_pz_order,_entry);} + float getVx() const noexcept { return _entry==-1 ? 0: getFloat(_vx_order,_entry);} + float getVy() const noexcept { return _entry==-1 ? 0: getFloat(_vy_order,_entry);} + float getVz() const noexcept { return _entry==-1 ? 0: getFloat(_vz_order,_entry);} + float getMass() const noexcept { return _entry==-1 ? 0: getFloat(_mass_order,_entry);} + int getIndex() const noexcept { return _entry==-1 ? 0: getByte(_index_order,_entry);} + int getType() const noexcept { return _entry==-1 ? 0: getByte(_type_order,_entry);} + int getParent() const noexcept { return _entry==-1 ? 0: getByte(_parent_order,_entry);} + int getDaughter() const noexcept { return _entry==-1 ? 0: getByte(_daughter_order,_entry);} + float getLifetime() const noexcept { return _entry==-1 ? 0: getFloat(_life_order,_entry);} + - /* void getVector3(int index, vector3 &vect){ */ - /* vect.setXYZ(getFloat(px_order,index),getFloat(py_order,index), */ - /* getFloat(pz_order,index)); */ - /* } */ - - /* void getVector4(int index, vector4 &vect, double mass){ */ - /* vect.setXYZM(getFloat(px_order,index),getFloat(py_order,index), */ - /* getFloat(pz_order,index),getFloat(mass_order,index)); */ - /* } */ - float getP() const noexcept{ - auto x= getFloat(px_order,_entry); - auto y= getFloat(py_order,_entry); - auto z= getFloat(pz_order,_entry); + auto x= getFloat(_px_order,_entry); + auto y= getFloat(_py_order,_entry); + auto z= getFloat(_pz_order,_entry); return sqrt(x*x+y*y+z*z); } + float getTheta() const noexcept{ + auto x= getFloat(_px_order,_entry); + auto y= getFloat(_py_order,_entry); + auto z= getFloat(_pz_order,_entry); + return x == 0.0 && y == 0.0 && z == 0.0 ? 0.0 + : atan2(sqrt(x*x+y*y),z); + } + float getPhi() const noexcept{ + auto x= getFloat(_px_order,_entry); + auto y= getFloat(_py_order,_entry); + return atan2(y,x); + } - void setEntry(short i){ _entry=i;} - void setBankEntry(short i){ _entry=i;} //faster for BankHist + void setEntry(short i){ + _entry=i; + if(_match.get()!=nullptr)_match->setEntry(i); + } + void setBankEntry(short i){ + _entry=i; + if(_match.get()!=nullptr)_match->setEntry(i); + } //faster for BankHist short getEntry() const noexcept{return _entry;} /** * This is virtual method from hipo::bank it will be called @@ -77,22 +97,35 @@ namespace clas12 { */ void notify() final { bank::notify(); - //printf("mcparticle class is read again\n"); } - + int match(int pindex){//pindex is index of reconstructed particle + return _match.get()!=nullptr ? + _entry=_match->getIndex(pindex) : -1 ; + } + bool isMatched() const noexcept{return _entry!=-1;} + + mcmatch* getMatch()const {return _match.get();} + private: - int pid_order{-1}; - int px_order{-1}; - int py_order{-1}; - int pz_order{-1}; - int vx_order{-1}; - int vy_order{-1}; - int vz_order{-1}; - int mass_order{-1}; + int _pid_order{-1}; + int _px_order{-1}; + int _py_order{-1}; + int _pz_order{-1}; + int _vx_order{-1}; + int _vy_order{-1}; + int _vz_order{-1}; + int _mass_order{-1}; + + int _type_order{-1}; + int _life_order{-1}; + int _index_order{-1}; + int _parent_order{-1}; + int _daughter_order{-1}; - short _entry=0; + short _entry={0}; + mcmatch_uptr _match; }; using mcpar_ptr=clas12::mcparticle*; diff --git a/Clas12Banks/particle.h b/Clas12Banks/particle.h index 3d04441..a4b12fe 100644 --- a/Clas12Banks/particle.h +++ b/Clas12Banks/particle.h @@ -40,7 +40,7 @@ namespace clas12 { int _st_order{-1}; int _chi2pid_order{-1}; - short _entry=0; + short _entry={0}; public: diff --git a/Clas12Banks/qadb_reader.cpp b/Clas12Banks/qadb_reader.cpp index e860077..ad543a9 100644 --- a/Clas12Banks/qadb_reader.cpp +++ b/Clas12Banks/qadb_reader.cpp @@ -4,56 +4,70 @@ namespace clas12 { #ifdef CLAS_QADB - qadb_reader::qadb_reader(string jsonFilePath, int runNo):_qa{jsonFilePath.c_str()}{_runNo=runNo;}; + qadb_reader::qadb_reader(int runNb):_qa{}{_runNb=runNb;}; + /////////////////////////////////////////////////////// + /// Add masks for all QA requirements + void qadb_reader::addAllMasks(){ + for(string req:_reqsQA){ + addMask(req.c_str(),true); + } + _masksAdded=true; + }; /////////////////////////////////////////////////////// ///Checks if an event passes all the QA requirements - - bool qadb_reader::passQAReqs(int evNo){ + bool qadb_reader::passQAReqs(int evNb){ //First event always has index 0 which doesn't exist in qaDB - if(evNo!=0){ + if(evNb!=0){ //isOkForAsymmetry already queries _QA, want to avoid doing it twice bool passAsymReq=true; bool queried=false; if(_reqOKAsymmetry){ - passAsymReq = isOkForAsymmetry(_runNo,evNo); + passAsymReq = isOkForAsymmetry(_runNb,evNb); queried=true; } else { - queried = query(_runNo,evNo); + queried = query(_runNb,evNb); + } + if(!_masksAdded){ + addAllMasks(); } - //An event may be ok for asymmetry but have other defects if(passAsymReq && queried){ //If an event is Golden it won't have other defects if(_reqGolden){ - return isGolden(); + //If the event passes the requirements, add charge + if(isGolden(_runNb,evNb)){ + _qa.AccumulateCharge(); + } + return isGolden(_runNb,evNb); } else { - //loop over all requirements asked by user - for(string req: _reqsQA){ - if (hasDefect(req.c_str())){ - return false; - } + //If the event passes the requirements, add charge + if(_qa.Pass(_runNb,evNb)){ + _qa.AccumulateCharge(); } + return _qa.Pass(_runNb,evNb); } } else { return false; } + //event passes all reqs, just don't want to acc for event 0 + _qa.AccumulateCharge(); } //Event passes all requirements return true; } #else - qadb_reader::qadb_reader(string jsonFilePath, int runNo){ - _runNo=runNo; + qadb_reader::qadb_reader(int runNb){ + _runNb=runNb; } /////////////////////////////////////////////////////// ///Checks if an event passes all the QA requirements - bool qadb_reader::passQAReqs(int evNo){ + bool qadb_reader::passQAReqs(int evNb){ return true; } diff --git a/Clas12Banks/qadb_reader.h b/Clas12Banks/qadb_reader.h index 39886f5..fc7c49f 100644 --- a/Clas12Banks/qadb_reader.h +++ b/Clas12Banks/qadb_reader.h @@ -15,7 +15,7 @@ namespace clas12 { class qadb_reader { public: - qadb_reader(string jsonFilePath, int runNo=0); + qadb_reader(int runNb=0); //virtual ~qadb_reader()=default; @@ -23,17 +23,18 @@ namespace clas12 { public: bool isValid(); - void addQARequirement(string req){_reqsQA.push_back(req);}; - void setQARequirements( std::vector reqs){_reqsQA=reqs;}; + void addQARequirement(string req){_reqsQA.push_back(req);_masksAdded=false;}; + void setQARequirements( std::vector reqs){_reqsQA=reqs;_masksAdded=false;}; void requireOkForAsymmetry(bool ok){_reqOKAsymmetry=ok;}; void requireGolden(bool ok){_reqGolden=ok;}; - bool passQAReqs(int evNo); + bool passQAReqs(int evNb); - void setRun(int runNb){_runNo=runNb;} + void setRun(int runNb){_runNb=runNb;} void copySettings(const qadb_reader& other); - + + private: @@ -43,29 +44,43 @@ namespace clas12 { std::vector _reqsQA;//! bool _reqOKAsymmetry{false};//! bool _reqGolden{false};//! - int _runNo{0};//! + int _runNb{0};//! + bool _masksAdded{false}; //ifdefs must go last , or can lead to issues with PROOF //i.e. refences are slighty shifted #ifdef CLAS_QADB - + public: + + int GetMask(){return _qa.GetMask();}; bool query(int runNb, int evNb){return _qa.Query(runNb,evNb);}; + bool querybyFileNb(int runNb, int fileNb){return _qa.QueryByFilenum(runNb,fileNb);}; + int getMaxFileNb(int runNb){return _qa.GetMaxFilenum(runNb);}; int getFileNb(){return _qa.GetFilenum();}; - bool isGolden(){return _qa.Golden();}; + int getRunNb(){return _qa.GetRunnum();}; + bool isGolden(int runNb, int evNb){return _qa.Golden(runNb,evNb);}; int getMinEventNb(){return _qa.GetEvnumMin();}; int getMaxEventNb(){return _qa.GetEvnumMax();}; - int getDefect(){return _qa.GetDefect();}; - int getDefectForSector(int sector){return _qa.GetDefectForSector(sector);}; + int getDefect(int sector=0){return _qa.GetDefect(sector);}; bool hasDefect(const char * defectName, int sector){return _qa.HasDefect(defectName,sector);}; bool hasDefect(const char * defectName){return _qa.HasDefect(defectName);}; string getComment(){return _qa.GetComment();}; - bool isOkForAsymmetry(int runNb, int evNb){return _qa.OkForAsymmetry(runNb,evNb);}; + double getCharge(){return _qa.GetCharge();}; + void resetAccCharge(){_qa.ResetAccumulatedCharge();}; + void addMask(const char * defectName, bool maskBit){_qa.SetMaskBit(defectName,maskBit);}; + void addAllMasks(); + double getAccCharge(){return _qa.GetAccumulatedCharge();}; + private: QADB _qa;//! - + +#else + public: + double getAccCharge(){return 0.0;}; + #endif diff --git a/Clas12Banks/rcdb_reader.cpp b/Clas12Banks/rcdb_reader.cpp index 48daad7..4b99d8d 100644 --- a/Clas12Banks/rcdb_reader.cpp +++ b/Clas12Banks/rcdb_reader.cpp @@ -205,7 +205,9 @@ namespace clas12 { void rcdb_root::readRun(int runNb){ - + if(runNb==11) return;//Simulation + if(runNb==10) return;//Simulation + //make file and list unique_ptr so deleted when we return auto rcdbFile=std::unique_ptr{TFile::Open(_rootFile.data())}; if(rcdbFile.get()==nullptr){ diff --git a/Clas12Banks/region_band.cpp b/Clas12Banks/region_band.cpp index 08819b0..8d526d5 100644 --- a/Clas12Banks/region_band.cpp +++ b/Clas12Banks/region_band.cpp @@ -12,8 +12,8 @@ namespace clas12 { /////////////////////////////////////////////////////// ///Constructor used for event, ///give all detector banks to prevent crashes when looking for FD - region_band::region_band(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event): - region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event) + region_band::region_band(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event,mcpar_ptr mcp): + region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event,mcp) { _region=clas12::BD; } diff --git a/Clas12Banks/region_band.h b/Clas12Banks/region_band.h index 4076934..601dc7b 100644 --- a/Clas12Banks/region_band.h +++ b/Clas12Banks/region_band.h @@ -27,9 +27,10 @@ namespace clas12 { public: region_band(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, - cal_ptr calp, scint_ptr scp,trck_ptr trp, - traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event); - ~region_band()=default; + cal_ptr calp, scint_ptr scp,trck_ptr trp, + traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event, + mcpar_ptr mcp=nullptr); + ~region_band() final=default; bool sort() override; diff --git a/Clas12Banks/region_cdet.cpp b/Clas12Banks/region_cdet.cpp index d80771b..60de298 100644 --- a/Clas12Banks/region_cdet.cpp +++ b/Clas12Banks/region_cdet.cpp @@ -18,8 +18,8 @@ namespace clas12 { /////////////////////////////////////////////////////// ///Constructor used for event, ///give all detector banks to prevent crashes when looking for FT - region_cdet::region_cdet(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event): - region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event) + region_cdet::region_cdet(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event,mcpar_ptr mcp): + region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event,mcp) { _region=clas12::CD; } diff --git a/Clas12Banks/region_cdet.h b/Clas12Banks/region_cdet.h index 4060dcf..2a24251 100644 --- a/Clas12Banks/region_cdet.h +++ b/Clas12Banks/region_cdet.h @@ -34,8 +34,9 @@ namespace clas12 { region_cdet(par_ptr pars,covmat_ptr cm, scint_ptr scp, trck_ptr trp,traj_ptr trj); region_cdet(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, - trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event); - ~region_cdet()=default; + trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event, + mcpar_ptr mcp=nullptr); + ~region_cdet() final=default; bool sort() final; diff --git a/Clas12Banks/region_fdet.cpp b/Clas12Banks/region_fdet.cpp index 7f26953..696e6ac 100644 --- a/Clas12Banks/region_fdet.cpp +++ b/Clas12Banks/region_fdet.cpp @@ -10,8 +10,8 @@ namespace clas12 { /////////////////////////////////////////////////////// ///Constructor used for event, ///give all detector banks to prevent crashes when looking for FT - region_fdet::region_fdet(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj,cher_ptr chp, ft_ptr ftp,event_ptr event): - region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event) + region_fdet::region_fdet(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj,cher_ptr chp, ft_ptr ftp,event_ptr event,mcpar_ptr mcp): + region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event,mcp) { _region=clas12::FD; } diff --git a/Clas12Banks/region_fdet.h b/Clas12Banks/region_fdet.h index c8e9fcf..208f423 100644 --- a/Clas12Banks/region_fdet.h +++ b/Clas12Banks/region_fdet.h @@ -34,8 +34,9 @@ namespace clas12 { // region_fdet()=default; region_fdet(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, - traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event); - ~region_fdet()=default; + traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event, + mcpar_ptr mcp=nullptr); + ~region_fdet() final =default; bool sort() final; diff --git a/Clas12Banks/region_ft.cpp b/Clas12Banks/region_ft.cpp index c1ef1f9..b3b6595 100644 --- a/Clas12Banks/region_ft.cpp +++ b/Clas12Banks/region_ft.cpp @@ -12,8 +12,8 @@ namespace clas12 { /////////////////////////////////////////////////////// ///Constructor used for event, ///give all detector banks to prevent crashes when looking for FD - region_ft::region_ft(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event): - region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event) + region_ft::region_ft(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event,mcpar_ptr mcp): + region_particle(pars,ftbpars,cm,calp,scp,trp,trj,chp,ftp,event,mcp) { _region=clas12::FT; } diff --git a/Clas12Banks/region_ft.h b/Clas12Banks/region_ft.h index 36ad600..47272ab 100644 --- a/Clas12Banks/region_ft.h +++ b/Clas12Banks/region_ft.h @@ -28,8 +28,9 @@ namespace clas12 { region_ft(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp,trck_ptr trp, - traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event); - ~region_ft()=default; + traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event, + mcpar_ptr mcp=nullptr); + ~region_ft() final=default; bool sort() override; diff --git a/Clas12Banks/region_particle.cpp b/Clas12Banks/region_particle.cpp index f3766f5..81238e0 100644 --- a/Clas12Banks/region_particle.cpp +++ b/Clas12Banks/region_particle.cpp @@ -41,7 +41,7 @@ namespace clas12 { { } - region_particle::region_particle(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event): + region_particle::region_particle(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, cher_ptr chp, ft_ptr ftp,event_ptr event, mcpar_ptr mcp): _parts(pars), _ftbparts(ftbpars), _covmat(cm), @@ -51,11 +51,12 @@ namespace clas12 { _traj(trj), _cher(chp), _ft(ftp), - _event(event) + _event(event), + _mcpart(mcp) { } - + float region_particle::getTheta() const{ _parts->setEntry(_pentry); float x=_parts->getPx(); diff --git a/Clas12Banks/region_particle.h b/Clas12Banks/region_particle.h index 3de4b4e..cbaa0cc 100644 --- a/Clas12Banks/region_particle.h +++ b/Clas12Banks/region_particle.h @@ -24,6 +24,8 @@ #include "event.h" #include "cherenkov.h" #include "forwardtagger.h" +#include "mcparticle.h" +#include "mcmatch.h" namespace clas12 { @@ -47,7 +49,8 @@ namespace clas12 { //For all regions region_particle(par_ptr pars,ftbpar_ptr ftbpars,covmat_ptr cm, cal_ptr calp, scint_ptr scp, trck_ptr trp, traj_ptr trj, - cher_ptr chp, ft_ptr ftp,event_ptr event); + cher_ptr chp, ft_ptr ftp,event_ptr event, + mcpar_ptr mcp=nullptr); virtual ~region_particle() =default; @@ -56,8 +59,9 @@ namespace clas12 { /// i.e. how the detector banks relate to that region virtual bool sort(){ _pentry=_parts->getEntry(); - //check for covarince matrix + //check for covariance matrix if(_covmat)_pcmat=_covmat->getIndex(_pentry); + if(_mcpart)_pmc=_mcpart->match(_pentry); return true; } @@ -84,7 +88,9 @@ namespace clas12 { virtual ft_ptr ft(ushort lay) const{_ft->setIndex(-1);return _ft;}; const CovMatrix* cmat() const{_covmat->setIndex(_pcmat);return _covmat->matrix();}; - + + mcpar_ptr mc() const{_mcpart->setEntry(_pmc);return _mcpart;}; + short getRegion() const {return _region;} float getTheta() const; @@ -98,23 +104,31 @@ namespace clas12 { float getPdgMass(); void useFTBPid(){if(_ftbparts)_useFTBPid=1;} - + + float getMCThetaDiff() {return getTheta()-mc()->getTheta();} + float getMCPhiDiff() {return getPhi()-mc()->getPhi();} + float getMCPDiff() {return getP()-mc()->getP();} + + //if(_parts->getCharge()) protected: - par_ptr _parts; - ftbpar_ptr _ftbparts; - covmat_ptr _covmat; - ft_ptr _ft; - cal_ptr _cal; - scint_ptr _scint; - trck_ptr _trck; - traj_ptr _traj; - cher_ptr _cher; - event_ptr _event; + par_ptr _parts={nullptr}; + ftbpar_ptr _ftbparts={nullptr}; + covmat_ptr _covmat={nullptr}; + ft_ptr _ft={nullptr}; + cal_ptr _cal={nullptr}; + scint_ptr _scint={nullptr}; + trck_ptr _trck={nullptr}; + traj_ptr _traj={nullptr}; + cher_ptr _cher={nullptr}; + event_ptr _event={nullptr}; + mcmatch_ptr _mcmatch={nullptr}; + mcpar_ptr _mcpart={nullptr}; //particle index short _pentry=-1; + short _pmc=-1; short _pcmat=-1; short _region=-1; short _useFTBPid=0; diff --git a/Clas12Banks/scintextras.cpp b/Clas12Banks/scintextras.cpp new file mode 100644 index 0000000..4edf945 --- /dev/null +++ b/Clas12Banks/scintextras.cpp @@ -0,0 +1,23 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +#include "scintextras.h" + + +namespace clas12 { + + + scintextras::scintextras(hipo::schema __schema): hipo::bank(__schema) { + + _dedx_order = __schema.getEntryOrder("dedx"); + _size_order = __schema.getEntryOrder("size"); + _layermulti_order = __schema.getEntryOrder("layermult"); + + + } + + +} diff --git a/Clas12Banks/scintextras.h b/Clas12Banks/scintextras.h new file mode 100644 index 0000000..f333049 --- /dev/null +++ b/Clas12Banks/scintextras.h @@ -0,0 +1,87 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: scintextras.h + * Author: dglazier + * + * Created on April 27, 2017, 10:01 AM + */ + +#ifndef CLAS12_SCINTEXTRAS_H +#define CLAS12_SCINTEXTRAS_H + +#include "bank.h" +#include +//#include "scintillator.h" + + +namespace clas12 { + + class scintillator; + + class scintextras : public hipo::bank { + + + public: + + + scintextras()=default; + + scintextras(hipo::schema __schema); + + ~scintextras() override=default; + + + double getDedx() const noexcept{ + if(_index>-1)return getFloat(_dedx_order,_index); + return 0.; + } + int getSize() const noexcept{ + if(_index>-1)return getShort(_size_order,_index); + return 0; + } + int getLayermulti() const noexcept{ + if(_index>-1)return getByte(_layermulti_order,_index); + return 0; + } + + double getDedx(int index) const noexcept{ + if(index>-1)return getFloat(_dedx_order,index); + return 0.; + } + int getSize(int index) const noexcept{ + if(index>-1)return getShort(_size_order,index); + return 0; + } + int getLayermulti(int index) const noexcept{ + if(index>-1)return getByte(_layermulti_order,index); + return 0; + } + + + void setBankEntry(short i){ _index=i;} //faster for BankHist + + private: + friend scintillator; + + void setIndex(short i){ _index=i;} + + + int _dedx_order=-1; + int _size_order=-1; + int _layermulti_order=-1; + + int _index=-1; + + }; //class scintextras + + using scintextra_ptr=clas12::scintextras*; + using scintextra_uptr=std::unique_ptr; + +}//namespace clas12 + +#endif /* UTILS_H */ diff --git a/Clas12Banks/scintillator.cpp b/Clas12Banks/scintillator.cpp index dc42df5..cecb2ff 100644 --- a/Clas12Banks/scintillator.cpp +++ b/Clas12Banks/scintillator.cpp @@ -10,22 +10,44 @@ namespace clas12 { - scintillator::scintillator(hipo::schema __schema): clas12::particle_detector(__schema) { + scintillator::scintillator(hipo::schema aschema,hipo::schema extras): + clas12::particle_detector(aschema), + _extras{new scintextras(extras)} + { - if(useItem("layer"))_layer_order = __schema.getEntryOrder("layer"); - if(useItem("energy"))_energy_order = __schema.getEntryOrder("energy"); - if(useItem("path"))_path_order = __schema.getEntryOrder("path"); - if(useItem("time"))_time_order = __schema.getEntryOrder("time"); - if(useItem("sector"))_sector_order = __schema.getEntryOrder("sector"); - if(useItem("status"))_status_order = __schema.getEntryOrder("status"); - if(useItem("x"))_x_order = __schema.getEntryOrder("x"); - if(useItem("y"))_y_order = __schema.getEntryOrder("y"); - if(useItem("z"))_z_order = __schema.getEntryOrder("z"); - if(useItem("hx"))_hx_order = __schema.getEntryOrder("hx"); - if(useItem("hy"))_hy_order = __schema.getEntryOrder("hy"); - if(useItem("hz"))_hz_order = __schema.getEntryOrder("hz"); - if(useItem("chi2"))_chi2_order = __schema.getEntryOrder("chi2"); - if(useItem("component"))_component_order = __schema.getEntryOrder("component"); + if(useItem("layer"))_layer_order = aschema.getEntryOrder("layer"); + if(useItem("energy"))_energy_order = aschema.getEntryOrder("energy"); + if(useItem("path"))_path_order = aschema.getEntryOrder("path"); + if(useItem("time"))_time_order = aschema.getEntryOrder("time"); + if(useItem("sector"))_sector_order = aschema.getEntryOrder("sector"); + if(useItem("status"))_status_order = aschema.getEntryOrder("status"); + if(useItem("x"))_x_order = aschema.getEntryOrder("x"); + if(useItem("y"))_y_order = aschema.getEntryOrder("y"); + if(useItem("z"))_z_order = aschema.getEntryOrder("z"); + if(useItem("hx"))_hx_order = aschema.getEntryOrder("hx"); + if(useItem("hy"))_hy_order = aschema.getEntryOrder("hy"); + if(useItem("hz"))_hz_order = aschema.getEntryOrder("hz"); + if(useItem("chi2"))_chi2_order = aschema.getEntryOrder("chi2"); + if(useItem("component"))_component_order = aschema.getEntryOrder("component"); + + } + scintillator::scintillator(hipo::schema aschema): + clas12::particle_detector(aschema) { + + if(useItem("layer"))_layer_order = aschema.getEntryOrder("layer"); + if(useItem("energy"))_energy_order = aschema.getEntryOrder("energy"); + if(useItem("path"))_path_order = aschema.getEntryOrder("path"); + if(useItem("time"))_time_order = aschema.getEntryOrder("time"); + if(useItem("sector"))_sector_order = aschema.getEntryOrder("sector"); + if(useItem("status"))_status_order = aschema.getEntryOrder("status"); + if(useItem("x"))_x_order = aschema.getEntryOrder("x"); + if(useItem("y"))_y_order = aschema.getEntryOrder("y"); + if(useItem("z"))_z_order = aschema.getEntryOrder("z"); + if(useItem("hx"))_hx_order = aschema.getEntryOrder("hx"); + if(useItem("hy"))_hy_order = aschema.getEntryOrder("hy"); + if(useItem("hz"))_hz_order = aschema.getEntryOrder("hz"); + if(useItem("chi2"))_chi2_order = aschema.getEntryOrder("chi2"); + if(useItem("component"))_component_order = aschema.getEntryOrder("component"); } diff --git a/Clas12Banks/scintillator.h b/Clas12Banks/scintillator.h index 13daea0..e2cf599 100644 --- a/Clas12Banks/scintillator.h +++ b/Clas12Banks/scintillator.h @@ -15,6 +15,7 @@ #define CLAS12_SCINTILLATOR_H #include "particle_detector.h" +#include "scintextras.h" namespace clas12 { @@ -27,7 +28,8 @@ namespace clas12 { scintillator()=default; - scintillator(hipo::schema __schema); + scintillator(hipo::schema aschema); + scintillator(hipo::schema aschema,hipo::schema extras); ~scintillator() override=default; @@ -88,13 +90,25 @@ namespace clas12 { if(_index>-1)return getFloat(_hz_order,_index); return 0; } - double getChi2() const noexcept{ + double getChi2() const noexcept{ if(_index>-1)return getFloat(_chi2_order,_index); return 0; } - - - + + + //get extras + double getDedx() const noexcept{ + return _extras.get()!=nullptr ? _extras->getDedx(_index):0; + } + int getSize() const noexcept{ + return _extras.get()!=nullptr ? _extras->getSize(_index):0; + } + int getLayermulti() const noexcept{ + return _extras.get()!=nullptr ? _extras->getLayermulti(_index):0; + } + + scintextras* getExtras()const {return _extras.get();} + private: int _layer_order=-1; @@ -112,7 +126,7 @@ namespace clas12 { int _hz_order=-1; int _chi2_order=-1; - + scintextra_uptr _extras; }; //class scintillator diff --git a/Clas12Root/BankHist.cpp b/Clas12Root/BankHist.cpp index cbe9102..f07ee54 100644 --- a/Clas12Root/BankHist.cpp +++ b/Clas12Root/BankHist.cpp @@ -13,11 +13,11 @@ namespace clas12root { _mapOfParts["RECFT::Particle"]="ftbparticle"; _mapOfParts["REC::Calorimeter"]="calorimeter"; _mapOfParts["REC::Scintillator"]="scintillator"; + _mapOfParts["REC::ScintExtras"]="scintextras"; _mapOfParts["REC::Cherenkov"]="cherenkov"; _mapOfParts["REC::Track"]="tracker"; _mapOfParts["REC::Traj"]="traj"; _mapOfParts["REC::ForwardTagger"]="forwardtagger"; - _mapOfParts["MC::Lund"]="mcparticle"; _mapOfParts["REC::CovMat"]="covmatrix"; _mapOfParts["RAW::vtp"]="vtp"; _mapOfParts["RAW::scaler"]="scaler"; @@ -29,6 +29,8 @@ namespace clas12root { _mapOfParts["HEL::flip"]="helflip"; _mapOfParts["MC::Particle"]="mcparticle"; _mapOfParts["MC::Lund"]="mcparticle"; + _mapOfParts["MC::Event"]="mcevent"; + _mapOfParts["MC::IsParticleMatched"]="mcmatch"; } diff --git a/Clas12Root/CMakeLists.txt b/Clas12Root/CMakeLists.txt index 0c97311..446c0f2 100644 --- a/Clas12Root/CMakeLists.txt +++ b/Clas12Root/CMakeLists.txt @@ -46,9 +46,12 @@ target_link_libraries(${CLAS12ROOT} ${ROOT_LIBRARIES} ${HIPO} ${CLAS12BANKS}) install(TARGETS ${CLAS12ROOT} LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") -FILE(GLOB ROOT_C12ROOT_PCM ${CMAKE_BINARY_DIR}/Clas12Root/*pcm) +#FILE(GLOB ROOT_C12ROOT_PCM ${CMAKE_BINARY_DIR}/Clas12Root/*pcm) -install (FILES ${ROOT_C12ROOT_PCM} +#install (FILES ${ROOT_C12ROOT_PCM} +# DESTINATION "${CMAKE_INSTALL_LIBDIR}") + +install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libClas12Root_rdict.pcm DESTINATION "${CMAKE_INSTALL_LIBDIR}") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/Clas12Root/HipoChain.cpp b/Clas12Root/HipoChain.cpp index e51e0da..e6a84db 100644 --- a/Clas12Root/HipoChain.cpp +++ b/Clas12Root/HipoChain.cpp @@ -75,20 +75,20 @@ namespace clas12root { /////Warning any changes to this function should ////also be considered for HipoSelector::Process std::cout<<"HipoChain::NextFile() "<<_idxFile<<" out of "<=GetNFiles()) + if(_idxFile>=GetNFiles()) return kFALSE;//no more files - std::cout<<"HipoChain::NextFile() "<setRcdbVals(FetchRunRcdb(_c12->getFilename())); - + _c12.reset(new clas12::clas12reader{*GetC12Reader(),GetFileName(_idxFile++).Data(),_readerTags}); + ConnectDataBases(); + //if there is a root rcdb file use it + //if(_rcdbFileName.Length())_c12->setRcdbVals(FetchRunRcdb(_c12->getFilename())); + _c12ptr = _c12.get(); return kTRUE; } - + clas12::clas12reader* HipoChain::GetC12Reader() { if( (_c12ptr=_c12.get()) ) diff --git a/Clas12Root/HipoChain.h b/Clas12Root/HipoChain.h index 660deef..3e6ca9e 100644 --- a/Clas12Root/HipoChain.h +++ b/Clas12Root/HipoChain.h @@ -58,6 +58,7 @@ namespace clas12root { void AddBeamCharge(Double_t bc){_totBeamCharge+=bc;} Double_t TotalBeamCharge() const noexcept{return _totBeamCharge;} + void SetTotalBeamCharge(Double_t bc){_totBeamCharge+=bc;} clas12::clas12databases* db() {return &_db;} void ConnectDataBases(){_c12->connectDataBases(&_db);} diff --git a/Clas12Root/HipoROOTOut.cpp b/Clas12Root/HipoROOTOut.cpp index 6f87ddf..3d12205 100644 --- a/Clas12Root/HipoROOTOut.cpp +++ b/Clas12Root/HipoROOTOut.cpp @@ -46,11 +46,9 @@ namespace clas12root{ Int_t NtempFiles=1; TString tempMacro=_curMacro; while(gSystem->FindFile(_tempDir,tempMacro)){ - cout<<_curMacro<GetString(); @@ -93,7 +91,7 @@ namespace clas12root{ void HipoROOTOut::CompileAction(){ PreCompileAction(); TMacro macro(_curMacro); - macro.Print(); + if(_verbose)macro.Print(); auto result=gROOT->LoadMacro(Form("%s++",_curMacro.Data())); diff --git a/Clas12Root/HipoROOTOut.h b/Clas12Root/HipoROOTOut.h index 19a9019..087a50d 100644 --- a/Clas12Root/HipoROOTOut.h +++ b/Clas12Root/HipoROOTOut.h @@ -46,6 +46,7 @@ namespace clas12root { vector RemoveArithmetic(TString& expr); void SetEntries(Long64_t n){_nEntriesToProcess=n;} + void SetVerbose(short v=1){_verbose=v;} protected : TString _tempActionName; @@ -54,7 +55,7 @@ namespace clas12root { TString GetCurrMacroName(){return _curMacro;} Int_t GetNActions(){return _Nactions;} - private : + private : TString _hipoFileName; TString _curMacro; @@ -64,7 +65,7 @@ namespace clas12root { TChain _chain; Int_t _iHipoFile=0; Long64_t _nEntriesToProcess=-1; - + short _verbose=0; };//class HipoROOTOut } diff --git a/Clas12Root/HipoSelector.cpp b/Clas12Root/HipoSelector.cpp index 94b22eb..c62a097 100644 --- a/Clas12Root/HipoSelector.cpp +++ b/Clas12Root/HipoSelector.cpp @@ -109,6 +109,33 @@ namespace clas12root{ } return kTRUE; } + + void HipoSelector::SlaveTerminate() + { + //Get accumulated charge for each and add to fOutput to concatenate +#ifdef CLAS_QADB + if(qadb()!=nullptr){ + auto chargeHist=new TH1D("accumulatedCharge","accumulatedCharge",1,0,1); + chargeHist->SetBinContent(1,qadb()->getAccCharge()); + fOutput->Add(chargeHist); + } +#endif + + } + + void HipoSelector::Terminate() + { + +#ifdef CLAS_QADB + //Get total charge accumulated charge + if(qadb()!=nullptr){ + auto chargeHist=dynamic_cast(fOutput->FindObject("accumulatedCharge")); + _chain->SetTotalBeamCharge(chargeHist->GetBinContent(1)); + std::cout<<"Total accumulated charge: "<GetBinContent(1)<addExactPid(11,1); //if want some filters + + //Get a c12 object for configuring + auto config_c12=chain.GetC12Reader(); + config_c12->addExactPid(11,1); //if want some filters + + //get c12 obect for running + auto& c12=chain.C12ref(); while (chain.Next()){ - c12=chain.GetC12Reader(); + auto electrons=c12->getByID(11); .... } @@ -215,19 +221,6 @@ Also you can check trigger bits directly c12.checkTriggerBit(24); -### Jupyter - -To install rootbooks see https://root.cern.ch/how/how-create-rootbook - - mkdir myNotebooks - cp -r $CLAS12ROOT/RunRoot/jupy myNotebooks/. - cd myNotebooks/jupy - -Start a ROOT note book : - - root --notebook - -Click on the notebook CLAS12Reader3Pi.ipynb and follow the tutorial ## Ex 2 Drawing particle histograms from hipo files @@ -291,15 +284,6 @@ For Run::config ParticleHist [0] hists.SetEntries(1E6); -### Jupyter - -Go to directory containing notebooks e.g. $CLAS12ROOT/RunRoot/jupy - -Start a ROOT note book : - - root --notebook - -Click on the notebook HipoDraw.ipynb and follow the tutorial ## Ex 4 Filtering and Skimming into a ROOT ntuple (tree) @@ -325,16 +309,6 @@ You can perform some arithmetic and define a new branch e.g. treemaker.AddAtLeastPid(211,1);//and at least 1 pi+ treemaker.AddZeroOfRestPid(); //and zero of any other particle type (default is any) -### Jupyter - -Go to directory containing notebooks e.g. $CLAS12ROOT/RunRoot/jupy - -Start a ROOT note book : - - root --notebook - -Click on the notebook HipoToRootTree.ipynb and follow the tutorial - ## Ex 3 Using HipoSelector & PROOFLite @@ -376,19 +350,6 @@ As a more complete example you can check testSelector in RunRoot which implement clas12proof 8 RunRoot/testSelector.C+ RunRoot/Ex3b_TestSelector.C - -### Jupyter - -Go to directory containing notebooks e.g. $CLAS12ROOT/RunRoot/jupy - -Start a ROOT note book : - - root --notebook - -Click on the notebook CreateHipoSelector.ipynb and follow instructions. This creates the selector you wish to run. - -Once this is complete you should open the notebook HipoProof.ipynb and process the selector with PROOF - ## Ex 5 Writing out specific events to a hipo file The clas12writer class allows you to write out specific events to a new hipo file. The idea behind this is to avoid repeating the same event selection everytime you want to access information about a specific set of events. The writer is assigned a clas12reader from which it gets the event information, and is initialised with the desired location for the outputted hipo file. You can also choose not to write out certain banks to speed the process up. @@ -401,39 +362,6 @@ To run: Note the use of the + sign after the macro name. This compiles the script meaning it will run much faster. The script will then ask you for the locations of an input hipo file and an output file. The script is similar to Ex1_CLAS12Writer.C so you can compare the two. -## Ex 7 Scaler beam charge information - -To normalise events you will need the beam charge. This is stored in 2 ways in clas12 DSTs. (1) accumalating in REC::Event::beamCharge (2) accumulating in tag=1 RAW::scaler::fcupgated . The problem with (1) for trains is that the events are not garaunteed to be in correct time order, so the last event in the hipo file may not have the largest beamCharge. And indeed if you have a large event filter you may not include any events with the largest beam cahrge in your train. (2) contains all the scaler reads and therefore the correct total charge, but these events are not in time order and the are not interspersed with the correct hipo events (I think). - -To make sure the correct beam charge is accessed and time history rates can be produced for a file there is a scaler_reader class. At file initialisation this will read all the tag=1 events (which is quite fast) and sort all the scaler events by event number. It will return the difference between the highest and lowest beamCharge, so it should work for individual run files as well as files with whole runs. It also allows you to add counters for any monitoring and will increment REC::* information with the correct associated scaler event. - -For example, - - clas12reader c12("file.hipo",{0}); //reader for tag 0 events - - //create the scaler reader and make some counters - //the counters have an entry for each scaler read - //you can increment them for each real event corresponding - //to the scaler read in the normal event loop - auto scal=c12.scalerReader(); - auto count_mesonex=scal->addLongCounter(); - auto count_events=scal->addLongCounter(); - while(c12.next()==true){ - auto currEvent=c12.runconfig()->getEvent(); - //check for valid charge events, i.e. RUN::Scaler::BeamCharge!<0 - if( scal->validCharge(currEvent) ==false ) continue; - if( c12.checkTriggerBit(24) ) //check if mesonex trigger fired for this event - scal->incrementLong(count_mesonex,currEvent,1); - //counter for all events - scal->incrementLong(count_events,currEvent,1); - - } - -Be aware that if your events have been filtered this will effect the rates. - -To try the example - - clas12root --in=/work/jlab/clas12data/v16/skim9_5038.hipo RunRoot/Ex7_ScalerReader.C+ ### Jupyter @@ -453,12 +381,11 @@ To use any database you must set the corresponding environment variables setenv RCDB_HOME /where/is/rcdb setenv CCDB_HOME /where/is/ccdb -setenv CLASQADB_HOME /where/is/clasqaDB +setenv QADB /where/is/clasqaDB ands pecify the location of the database before you create your clas12root object clas12databases::SetCCDBLocalConnection("/where/to/ccdb.sqlite"); - clas12databases::SetQADBConnection("/where/to/qaDB.json"); clas12databases::SetRCDBRootConnection("/where/to/rcdb.root"); These local files can be created using the $CLAS12ROOT/RunRoot/PrepareDatabases.C macro. You are best copying this locally and editing for any datafiles you want to add to the RCDB file list. @@ -507,10 +434,10 @@ Where ccdbElSF is a std::vector> and so you can access the e clas12root can use the Quality Assurance database .json files found at https://github.com/c-dilks/clasqaDB/tree/master to reject events that have been identified as failing to meet certain requirements. This is implemented in an analysis using the clas12reader with the functions - c12.db().qadb_requireOkForAsymmetry(true); - c12.db().qadb_requireGolden(true); - c12.db().qadb_addQARequirement("MarginalOutlier"); - c12.db().qadb_addQARequirement("TotalOutlier"); + c12.db()->qadb_requireOkForAsymmetry(true); + c12.db()->qadb_requireGolden(true); + c12.db()->qadb_addQARequirement("MarginalOutlier"); + c12.db()->qadb_addQARequirement("TotalOutlier"); c12.applyQA(); @@ -518,13 +445,11 @@ Or in case you use HipoChain (also for when running PROOF/HipoSelector) auto c12=chain.GetC12Reader(); - c12->db().qadb_requireOkForAsymmetry(true); - c12->db().qadb_requireGolden(true); - c12->db().qadb_addQARequirement("MarginalOutlier"); - c12->db().qadb_addQARequirement("TotalOutlier"); - c12->applyQA(); - - + c12->db()->qadb_requireOkForAsymmetry(true); + c12->db()->qadb_requireGolden(true); + c12->db()->qadb_addQARequirement("MarginalOutlier"); + c12->db()->qadb_addQARequirement("TotalOutlier"); + c12->applyQA(); where requireOkForAsymmetry(true) requires only events that were identified as suitable for asymmetry calculations, and requireGolden(true) requires only events without any defects. addQARequirement("Requirement") allows to reject events that fail to meet the specified requirement. These can be: @@ -535,16 +460,14 @@ where requireOkForAsymmetry(true) requires only events that were identified as s LowLiveTime: live time < 0.9 Misc: miscellaneous defect -The QA database is contained in several .json files that can be found on the clasqaDB github [repository](https://github.com/c-dilks/clasqaDB/tree/master). These can be merged within clas12root using the jsonFileMerger class with the functions: +The clasqaDB software also returns the accumulated charge for events that have passed the quality assurance requirements. This is accessed with: - jsonFileMerger merger("/absolute/path/for/output.json"); - merger.addFile("/absolute/path/for/input1.json"); - merger.addFile("/absolute/path/for/input2.json"); - merger.mergeAllFiles(); + c12.db()->qadb()->getAccCharge(); + +Or if using a HipoChain + + chain.TotalBeamCharge() -This step can be performed with the RunRoot PrepareDatabases.C script, -You should copy this locally and edit the HipoChain files if you are using RCDB. - More information on the Quality Assurance process can be found in the RGA analysis note. ### Using databases with HipoSelector @@ -577,7 +500,6 @@ Inside your Selector class for RCDB tables : See Ex3b_TestSelector.C and testSelector.C and .h for implementation example. To use the databases you need to comment in the lines clas12databases::SetCCDBLocalConnection("ccdb.sqlite"); - clas12databases::SetQADBConnection("qaDB.json"); clas12databases::SetRCDBRootConnection("rcdb.root"); Having run PrepareDatabases.C with the HipoChain set for the files you wish to process. diff --git a/RunRoot/Ex10_clas12Databases.C b/RunRoot/Ex10_clas12Databases.C index 17f6c7b..0586a9d 100644 --- a/RunRoot/Ex10_clas12Databases.C +++ b/RunRoot/Ex10_clas12Databases.C @@ -18,7 +18,6 @@ void Ex10_clas12Databases(){ //It is recommended to edit and run the scrpit PrepareDatabases.C //for this purpose //clas12databases::SetCCDBLocalConnection("ccdb.sqlite"); - //clas12databases::SetQADBConnection("qaDB.json"); //clas12databases::SetRCDBRootConnection("rcdb.root"); @@ -58,6 +57,13 @@ void Ex10_clas12Databases(){ while(c12.next()) { } + + /* + * The clasqaDB software also provides the accumulated charge for events + * that pass the quality assurance requirements. + */ + cout<<"Accumulated charge past QA: "<getAccCharge()<<" nC"<Stop("db"); gBenchmark->Print("db"); diff --git a/RunRoot/Ex10_clas12DatabasesChain.C b/RunRoot/Ex10_clas12DatabasesChain.C index 50cdaef..fa7f62e 100644 --- a/RunRoot/Ex10_clas12DatabasesChain.C +++ b/RunRoot/Ex10_clas12DatabasesChain.C @@ -18,13 +18,12 @@ void Ex10_clas12DatabasesChain(){ It is recommended to edit and run the script PrepareDatabases.C for this purpose*/ //clas12databases::SetCCDBLocalConnection("ccdb.sqlite"); - //clas12databases::SetQADBConnection("qaDB.json"); //clas12databases::SetRCDBRootConnection("rcdb.root"); clas12root::HipoChain chain; // chain.Add("/where/are/my/files/f1.hipo"); //chain.Add("/where/are/my/files/f2.hipo"); - chain.Add("/work/jlab/clas12data/skim14_005038.hipo"); + chain.SetReaderTags({0}); //create clas12reader with just tag 0 events auto config_c12=chain.GetC12Reader(); @@ -55,10 +54,10 @@ void Ex10_clas12DatabasesChain(){ * additional information. */ if(config_c12->qadb()!=nullptr){ - config_c12->db().qadb_requireOkForAsymmetry(true); - config_c12->db().qadb_requireGolden(true); - config_c12->db().qadb_addQARequirement("MarginalOutlier"); - config_c12->db().qadb_addQARequirement("TotalOutlier"); + config_c12->db()->qadb_requireOkForAsymmetry(true); + config_c12->db()->qadb_requireGolden(true); + config_c12->db()->qadb_addQARequirement("MarginalOutlier"); + config_c12->db()->qadb_addQARequirement("TotalOutlier"); /* * applyQA specifies to the clas12reader that quality assurance * cuts will be applied, based on the .json file given as an @@ -90,7 +89,13 @@ void Ex10_clas12DatabasesChain(){ } //break; } - + + /* + * The clasqaDB software also provides the accumulated charge for events + * that pass the quality assurance requirements. + */ + cout<<"Accumulated charge past QA: "<< chain.TotalBeamCharge()<<" nC"<Stop("db"); gBenchmark->Print("db"); } diff --git a/RunRoot/Ex1_CLAS12ReaderChain.C b/RunRoot/Ex1_CLAS12ReaderChain.C index bbed055..6435b3a 100644 --- a/RunRoot/Ex1_CLAS12ReaderChain.C +++ b/RunRoot/Ex1_CLAS12ReaderChain.C @@ -72,7 +72,6 @@ void Ex1_CLAS12ReaderChain(){ auto& c12=chain.C12ref(); while (chain.Next()){ - //c12=chain.GetC12Reader(); //c12->event()->getStartTime(); diff --git a/RunRoot/Ex3_ProofLite.C b/RunRoot/Ex3_ProofLite.C index 45cc8e1..3d015dd 100644 --- a/RunRoot/Ex3_ProofLite.C +++ b/RunRoot/Ex3_ProofLite.C @@ -10,11 +10,6 @@ chain.Add("/WHERE/IS/MY/HIPO/file.hipo"); clas12root::myFirstSelector sel(&chain); - ////////////////////////////////////// - //To creat rcdb data RCDB_HOME must be set prior to installation - //chain.WriteRcdbData("rcdb.root"); //Must use this first time to create local copy - //Then when we have local copy can just use the following - //chain.SetRcdbFile("rcdb.root"); gProof->Process(&sel,chain.GetNRecords()); } diff --git a/RunRoot/Ex3b_TestSelector.C b/RunRoot/Ex3b_TestSelector.C index 6241672..f07f25e 100644 --- a/RunRoot/Ex3b_TestSelector.C +++ b/RunRoot/Ex3b_TestSelector.C @@ -7,7 +7,6 @@ //selector name { //clas12databases::SetCCDBLocalConnection("ccdb.sqlite"); - //clas12databases::SetQADBConnection("qaDB.json"); //clas12databases::SetRCDBRootConnection("rcdb.root"); clas12root::HipoChain chain; diff --git a/RunRoot/Ex4_TreeMaker.C b/RunRoot/Ex4_TreeMaker.C index 9a7bd77..0e01fc6 100644 --- a/RunRoot/Ex4_TreeMaker.C +++ b/RunRoot/Ex4_TreeMaker.C @@ -7,6 +7,7 @@ //make branch with given formula and alias it to name Time //treemaker.Branch("P.Time-EVNT.StartTime/F","Time"); //treemaker.Branch("P.Time-EVNT.FTBStartTime/F","FTBTime"); + //treemaker.Branch("P.Time-PBANK.Vt/F","FTBTime"); treemaker.Branch("P.Time/F"); treemaker.Branch("P.Path/F"); treemaker.Branch("P.DetEnergy/P.P/F","SampFrac"); diff --git a/RunRoot/Ex9_QualityAssurance.C b/RunRoot/Ex9_QualityAssurance.C index 880d000..f4b5723 100644 --- a/RunRoot/Ex9_QualityAssurance.C +++ b/RunRoot/Ex9_QualityAssurance.C @@ -8,23 +8,6 @@ using namespace clas12; using namespace std; void Ex9_QualityAssurance(){ - - - /* - * The jsonFileMerger class included in clas12root allows to - * quickly merge several jason files. It takes as an - * argument the absolute path for the merged output. - * - * addFile takes as argument the absolute path for an input - * .json file to be merged. - * - * mergeAllFiles merges all the added files and saves the output - * to the specified location - */ - jsonFileMerger merger("/absolute/path/for/output.json"); - merger.addFile("/absolute/path/for/input1.json"); - merger.addFile("/absolute/path/for/input2.json"); - merger.mergeAllFiles(); //clas12reader declared as usual. clas12reader c12("/path/to/data.hipo"); @@ -35,7 +18,7 @@ void Ex9_QualityAssurance(){ * argument. This file should contain the Clas12 Quality Assurance * database. */ - c12.applyQA("/absolute/path/to/qaDB.json"); + c12.applyQA(); /* * Several quality assurance requirements can be specified. @@ -49,14 +32,20 @@ void Ex9_QualityAssurance(){ * See RGA analysis note and clasqaDB github repository for * additional information. */ - c12.getQAReader()->requireOkForAsymmetry(true); - c12.getQAReader()->requireGolden(true); - c12.getQAReader()->addQARequirement("MarginalOutlier"); - c12.getQAReader()->addQARequirement("TotalOutlier"); + c12.qadb()->requireOkForAsymmetry(true); + c12.qadb()->requireGolden(true); + c12.qadb()->addQARequirement("MarginalOutlier"); + c12.qadb()->addQARequirement("TotalOutlier"); //The analysis can then proceed as usual. while(c12.next()) { //Do rest of analysis... } + /* + * The clasqaDB software also provides the accumulated charge for events + * that pass the quality assurance requirements. + */ + cout<<"Accumulated charge past QA: "<getAccCharge()<<" nC"<mcevent(); + cout<<" beam energy "<getEbeam()<<" type "<getBtype()<mcparts(); const Int_t Ngen=mcpbank->getRows(); diff --git a/RunRoot/ExMC_CLAS12ReaderChain.C b/RunRoot/ExMC_CLAS12ReaderChain.C new file mode 100644 index 0000000..eb1f727 --- /dev/null +++ b/RunRoot/ExMC_CLAS12ReaderChain.C @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "clas12reader.h" +#include "HipoChain.h" + +using namespace clas12; + +void ExMC_CLAS12ReaderChain(){ + + + + auto* hPDiff=new TH1F("PDiff","PDiff",200,-10,10); + auto* hThDiff=new TH1F("ThDiff","ThDiff",200,-180,180); + auto* hPhDiff=new TH1F("PhDiff","PhDiff",200,-360,360); + + gBenchmark->Start("timer"); + int counter=0; + + clas12root::HipoChain chain; + // chain.Add("/WHERE/IS/MY/HIPO/file2.hipo"); + // chain.Add("/WHERE/IS/MY/HIPO/file*.hipo"); + + ////////////////////////////////////// + //To creat rcdb data RCDB_HOME must be set prior to installation + //chain.WriteRcdbData("rcdb.root"); //Must use this first time to create local copy + //Then when we have local copy can just use the following + //chain.SetRcdbFile("rcdb.root"); + + auto config_c12=chain.GetC12Reader(); + chain.SetReaderTags({0}); //create clas12reader with just tag 0 events + //config_c12->scalerReader();//if you want integrated charge + //Add some event Pid based selections + //////////config_c12->AddAtLeastPid(211,1); //at least 1 pi+ + //config_c12->addExactPid(11,1); //exactly 1 electron + //config_c12->addExactPid(211,1); //exactly 1 pi+ + //config_c12->addExactPid(-211,1); //exactly 1 pi- + //config_c12->addExactPid(2212,1); //exactly 1 proton + //config_c12->addExactPid(22,2); //exactly 2 gamma + //////config_c12->addZeroOfRestPid(); //nothing else + //////config_c12->useFTBased(); //and use the Pids from RECFT + + //now get reference to (unique)ptr for accessing data in loop + //this will point to the correct place when file changes + auto& c12=chain.C12ref(); + + while (chain.Next()){ + //loop over all reconstructed particles + for(auto p : c12->getDetParticles()){ + + if(p->mc()->isMatched()){//this particle has an mc match + //if charged FD, check for sufficient layers + if( p->getRegion()==clas12::FD && p->par()->getCharge() ) + if(p->mc()->getMatch()->checkFDSuperLayers(5,4)==false) + continue; + // p->mc()->getMatch()->checkBitInPattern(33);//check other bits + + hPDiff->Fill(p->getMCPDiff()); + hThDiff->Fill(p->getMCThetaDiff()*TMath::RadToDeg()); + hPhDiff->Fill(p->getMCPhiDiff()*TMath::RadToDeg()); + } + + } + counter++; + } + cout<<"Number of Events = " <Stop("timer"); + gBenchmark->Print("timer"); + TCanvas* can=new TCanvas(); + can->Divide(3,1); + can->cd(1); + hPDiff->Draw(); + can->cd(2); + hThDiff->Draw(); + can->cd(3); + hPhDiff->Draw(); + + +} diff --git a/RunRoot/LoadClas12Root.C b/RunRoot/LoadClas12Root.C index 40b42c3..8d4e641 100644 --- a/RunRoot/LoadClas12Root.C +++ b/RunRoot/LoadClas12Root.C @@ -19,7 +19,7 @@ void LoadClas12Root(){ gROOT->SetMacroPath(Form("%s:%s/RunRoot/",gROOT->GetMacroPath(),CLAS12ROOT.Data())); - TString QADB=gSystem->Getenv("CLASQADB_HOME"); + TString QADB=gSystem->Getenv("QADB"); if(QADB.Length()!=0){ //For #ifdef CLAS_QADB in header files gSystem->AddIncludePath("-DCLAS_QADB"); gROOT->ProcessLine("#define CLAS_QADB"); //For cling interpreter @@ -37,5 +37,12 @@ void LoadClas12Root(){ gROOT->ProcessLine("#define RCDB_MYSQ"); //For cling interpreter //gROOT->ProcessLine("#define RCDB_SQLITE"); //For cling interpreter } - + //remove aclic warnings for ccdb.... + gSystem->SetAclicMode(TSystem::EAclicMode::kOpt); + TString optFlags = gSystem->GetFlagsOpt(); + optFlags+=" -Wno-ignored-qualifiers"; + optFlags+=" -Wno-format"; + gSystem->SetFlagsOpt(optFlags.Data()); + + } diff --git a/RunRoot/PrepareDatabases.C b/RunRoot/PrepareDatabases.C index 76df9d5..3a8e1ec 100644 --- a/RunRoot/PrepareDatabases.C +++ b/RunRoot/PrepareDatabases.C @@ -24,7 +24,7 @@ void PrepareDatabases(){ -#ifdef CLAS_QADB + /* * The jsonFileMerger class included in clas12root allows to @@ -37,9 +37,15 @@ void PrepareDatabases(){ * mergeAllFiles merges all the added files and saves the output * to the specified location */ - + + +/* Deprecated - clasqaDB software now premerges the database files +and automatically opens these. + + +#ifdef QADB jsonFileMerger merger("qaDB.json"); - TString QAHOME=gSystem->Getenv("CLASQADB_HOME"); + TString QAHOME=gSystem->Getenv("QADB"); std::cout<<"CLASQA adding json file "<<(QAHOME+"/qa.inbending1/qaTree.json").Data()< +#include +#include + +#include "CCDB/Providers/IAuthentication.h" +#include "CCDB/Model/ObjectsOwner.h" +#include "CCDB/Model/Assignment.h" +#include "CCDB/Model/ConstantsTypeTable.h" +#include "CCDB/Model/Directory.h" +#include "CCDB/Model/RunRange.h" +#include "CCDB/Model/Variation.h" +#include "CCDB/CCDBError.h" + + + +/* @class DataProvider + * This is the main base interface to the Providers class family. + * Each derived Provider, provides access to data from a specified data source + * I.e. MySQLDataProvider works with MySQL database, SQLiteDataProvider works with SQLite + * + *============================================== + *Low Level API + * + * ^ ^ ^ + * | | | + * +------------------------------------------+ + * | Data Model: Assignment, TypeTable, ... | - Data model is returned to user + * +------------------------------------------+ + * ^ + * | + * | + * +------------------------------------------+ + * | DataProvider - Interface to database | - User calls DataProvider functions to get data user needs + * +------------------------------------------+ + * | + * +---------------------+ + * / \ + * +----------------+ +----------------+ + * | MySQLProvider | | SQLiteProvider| - Classes inherited from DataProvider do actual queries to data sources + * +----------------+ +----------------+ + * | | + * <================> <================> + * | MySQL Database | | SQLite | - Data storages + * <________________> <________________> + * + * + * + * + */ +namespace ccdb +{ + +class DataProvider: public ObjectsOwner +{ +public: + + DataProvider(void); + virtual ~DataProvider(void); + + //---------------------------------------------------------------------------------------- + // C O N N E C T I O N + //---------------------------------------------------------------------------------------- + + /** + * @brief Connects to database using connection string + * + * Connects to database using connection string + * connection string might be in form: + * mysql://:@: + * + * @param connectionString "mysql://:@: " + * @return true if connected + */ + virtual bool Connect(std::string connectionString) = 0; + + /** + * @brief closes connection to data + */ + virtual void Disconnect()= 0; + + /** + * @brief indicates ether the connection is open or not + * + * @return true if connection is open + */ + virtual bool IsConnected()=0; + + /** @brief Connection string that was used on last successful connect. + * + * Connection string that was used on last successful connect. + * If no any successfull connects were done string::empty will be returned + * + * @return Last connection string or string::empty() if no successfull connection was done + */ + virtual std::string GetConnectionString(); + + //---------------------------------------------------------------------------------------- + // D I R E C T O R Y M A N G E M E N T + //---------------------------------------------------------------------------------------- +#ifndef __GNUC__ + #pragma region Directory managemend +#endif + /** @brief Gets directory by its full path + * + * @param Full path of the directory + * @return DDirectory object if directory exists, NULL otherwise + */ + virtual Directory* GetDirectory(const string& path)=0; + + /** @brief return reference to root directory + * + * Root directory contains all other directories. It is not stored in any database + * + * @warning User should not delete this object + * + * @return DDirectory object pointer + */ + virtual Directory * GetRootDirectory(); + + /** @brief Searches for directory + * + * Searches directories that matches the pattern + * inside parent directory with path @see parentPath + * or globally through all type tables if parentPath is empty + * The pattern might contain + * '*' - any character sequence + * '?' - any single character + * + * paging could be done with @see startWith @see take + * startWith=0 and take=0 means select all records; + * + * objects that are contained in vector& resultDirectories will be + * 1) if this provider owned - deleted (@see ReleaseOwnership) + * 2) if not owned - just leaved on user control + * + * @param [out] resultDirectories search result + * @param [in] searchPattern Pattern to search + * @param [in] parentPath Parent path. If NULL search through all directories + * @param [in] startRecord record number to start with + * @param [in] selectRecords number of records to select. 0 means select all records + * @return bool true if there were error (even if 0 directories found) + */ + virtual bool SearchDirectories(vector& resultDirectories, const string& searchPattern, const string& parentPath="", int take=0, int startWith=0)=0; + + + /** @brief SearchDirectories + * + * Searches directories that matches the pattern + * inside parent directory with path @see parentPath + * or globally through all type tables if parentPath is empty + * The pattern might contain + * '*' - any character sequence + * '?' - any single character + * + * paging could be done with @see startWith @see take + * startWith=0 and take=0 means select all records; + * + * objects that are contained in vector& resultDirectories will be + * 1) if this provider owned - deleted (@see ReleaseOwnership) + * 2) if not owned - just leaved on user control + * @param [in] searchPattern Pattern to search + * @param [in] parentPath Parent path. If NULL search through all directories + * @param [in] startRecord record number to start with + * @param [in] selectRecords number of records to select. 0 means select all records + * @return list of + */ + virtual vector SearchDirectories(const string& searchPattern, const string& parentPath="", int take=0, int startWith=0); + + protected: + + /** @brief Reads all directories from DB + * + * Explicitly forces to load directories from DB and build directory structure + * (!) At this implementation all existing directories references will be deleted, + * thus references to them will become broken + * @return bool + */ + virtual bool LoadDirectories() = 0; + + virtual void BuildDirectoryDependencies(); /// Builds directory relational structure. Used right at the end of RetriveDirectories(). + virtual bool CheckDirectoryListActual(); /// Checks if directory list is actual i.e. nobody changed directories in database + virtual bool UpdateDirectoriesIfNeeded(); /// Update directories structure if this is required + +#ifndef __GNUC__ + #pragma endregion Directory managemend +#endif + //---------------------------------------------------------------------------------------- + // C O N S T A N T T Y P E T A B L E + //---------------------------------------------------------------------------------------- +#ifndef __GNUC__ + #pragma region Type tables +#endif + + public: + /** @brief Gets ConstantsType information from the DB + * + * @param [in] path absolute path of the type table + * @return new object of ConstantsTypeTable + */ + virtual ConstantsTypeTable * GetConstantsTypeTable(const string& path, bool loadColumns=false); + + /** @brief Gets ConstantsType information from the DB + * + * @param [in] name name of ConstantsTypeTable + * @param [in] parentDir directory that contains type table + * @return new object of ConstantsTypeTable + */ + virtual ConstantsTypeTable * GetConstantsTypeTable(const string& name, Directory *parentDir, bool loadColumns=false)=0; + + /** @brief Gets ConstantsType information from the DB + * + * @param [in] name name of ConstantsTypeTable + * @param [in] parentDir directory that contains type table + * @return new object of ConstantsTypeTable + */ + virtual bool GetConstantsTypeTables(vector& typeTables,const string& parentDirPath, bool loadColumns=false) =0; + + /** @brief Get all "constants" from current directory + * + * @param parentDir + * @return vector of constants + */ + virtual vector GetConstantsTypeTables (Directory *parentDir, bool loadColumns=false)=0; + + /** @brief Get all "constants" from current directory + * + * @param parentDir + * @return vector of constants + */ + virtual bool GetConstantsTypeTables(vector& typeTables, Directory *parentDir, bool loadColumns=false) =0; + + /** @brief Searches for type tables that matches the patten + * + * Searches type table that matches the pattern + * inside parent directory with path @see parentPath + * or globally through all type tables if parentPath is empty + * The pattern might contain + * '*' - any character sequence + * '?' - any single character + * + * paging could be done with @see take ans @see startWith + * take=0, startWith=0 means select all records; + * + * objects that are contained in vector& resultDirectories will be + * 1) if this provider owned - deleted (@see ReleaseOwnership) + * 2) if not owned - just leaved on user control + * @param pattern + * @param parentPath + * @return bool + */ + virtual bool SearchConstantsTypeTables(vector& typeTables, const string& pattern, const string& parentPath = "", bool loadColumns=false, int take=0, int startWith=0 )=0; + + /** @brief Searches for type tables that matches the patten + * + * Searches type table that matches the pattern + * inside parent directory with path @see parentPath + * or globally through all type tables if parentPath is empty + * The pattern might contain + * '*' - any character sequence + * '?' - any single character + * + * paging could be done with @see startWith @see take + * startRecord=0 and selectRecords=0 means select all records; + * + * objects that are contained in vector& resultDirectories will be + * 1) if this provider owned - deleted (@see ReleaseOwnership) + * 2) if not owned - just leaved on user control + * @param pattern + * @param parentPath + * @return vector + */ + virtual vector SearchConstantsTypeTables(const string& pattern, const string& parentPath = "", bool loadColumns=false, int take=0, int startWith=0 )=0; + + /** + * @brief This function counts number of type tables for a given directory + * @param [in] directory to look tables in + * @return number of tables to return + */ + virtual int CountConstantsTypeTables(Directory *dir)=0; + + /** @brief Loads columns for this table + * + * @param parentDir + * @return vector of constants + */ + virtual bool LoadColumns(ConstantsTypeTable* table) =0; + +#ifndef __GNUC__ + #pragma endregion Type tables +#endif + + //---------------------------------------------------------------------------------------- + // R U N R A N G E S + //---------------------------------------------------------------------------------------- + + /** @brief GetRun Range from db + * + * @param int min + * @param int max + * @param const char * name + * @return DRunRange* return NULL if not found or failed + */ + virtual RunRange* GetRunRange(int min, int max, const string& name = "")=0; + + + /** + * @brief Searches all run ranges associated with this type table + * + * @param [out] resultRunRanges result run ranges + * @param [in] table table to search run ranges in + * @param [in] variation variation to search, if not set all variations will be selected + * @param [in] take how many records to take + * @param [in] startWith start record to take + * @return + */ + virtual bool GetRunRanges(vector& resultRunRanges, ConstantsTypeTable *table, const string& variation="", int take=0, int startWith=0 )=0; + + /** + * @brief Searches all run ranges associated with this type table + * + * @param [out] resultRunRanges result run ranges + * @param [in] table table to search run ranges in + * @param [in] variation variation to search, if not set all variations will be selected + * @param [in] take how many records to take + * @param [in] startWith start record to take + * @return + */ + virtual bool GetRunRanges(vector& resultRunRanges, const string& typeTablePath, const string& variation="",int take=0, int startWith=0 ); + + /** @brief GetRun Range from db + * + * @param int min + * @param int max + * @param const char * name + * @return DRunRange* return NULL if not found or failed + */ + virtual RunRange* GetRunRange(const string& name)=0; + + //---------------------------------------------------------------------------------------- + // V A R I A T I O N + //---------------------------------------------------------------------------------------- + /** @brief Get variation by name + * + * @param const char * name + * @return DVariation* + */ + virtual Variation* GetVariation(const string& name)=0; + + /** + * @brief Searches all variations associated with this type table + * @param [out] resultVariations result variations + * @param [in] table table to search run ranges in + * @param [in] run specified run to search for, if 0 searches for all run ranges + * @param [in] take how many records to take + * @param [in] startWith start record to take + * @return + */ + virtual bool GetVariations(vector& resultVariations, ConstantsTypeTable *table, int run=0, int take=0, int startWith=0 )=0; + + /** + * @brief Searches all variations associated with this type table + * @param [out] resultVariations result variations + * @param [in] table table to search run ranges in + * @param [in] run specified run to search for, if 0 searches for all run ranges + * @param [in] take how many records to take + * @param [in] startWith start record to take + * @return + */ + virtual vector GetVariations(ConstantsTypeTable *table, int run=0, int take=0, int startWith=0 )=0; + + /** + * @brief Searches all variations associated with this type table + * @param [out] resultVariations result variations + * @param [in] path path to table to search run ranges in + * @param [in] run specified run to search for, if 0 searches for all run ranges + * @param [in] take how many records to take + * @param [in] startWith start record to take + * @return + */ + virtual bool GetVariations(vector& resultVariations, const string& path, int run=0, int take=0, int startWith=0 ); + + + //---------------------------------------------------------------------------------------- + // A S S I G N M E N T S + //---------------------------------------------------------------------------------------- +#ifndef __GNUC__ + #pragma region Assignments +#endif + + /** @brief Get Assignment with data blob only + * + * This function is optimized for fast data retrieving and is assumed to be performance critical; + * This function doesn't return any specified information like variation object or run-range object + * @see GetAssignmentFull + * @param [in] run - run number + * @param [in] path - object path + * @param [in] variation - variation name + * @param [in] loadColumns - optional, do we need to load table columns information (for column names and types) or not + * @return DAssignment object or NULL if no assignment is found or error + */ + virtual Assignment* GetAssignmentShort(int run, const string& path, const string& variation="default", bool loadColumns=false)=0; + + + /** @brief Get specified by creation time version of Assignment with data blob only. + * + * This function is optimized for fast data retrieving and is assumed to be performance critical; + * This function doesn't return any specified information like variation object or run-range object + * The Time is a timestamp, data that is equal or earlier in time than that timestamp is returned + * + * @remarks this function is named so + * @param [in] run - run number + * @param [in] path - object path + * @param [in] time - timestamp, data that is equal or earlier in time than that timestamp is returned + * @param [in] variation - variation name + * @param [in] loadColumns - optional, do we need to load table columns information (for column names and types) or not + * @return DAssignment object or NULL if no assignment is found or error + */ + virtual Assignment* GetAssignmentShort(int run, const string& path, time_t time, const string& variation="default", bool loadColumns=false)=0; + + + /** @brief Get last Assignment with all related objects + * + * @param int run + * @param path to constant path + * @return NULL if no assignment is found or error + */ + virtual Assignment* GetAssignmentFull(int run, const string& path, const string& variation="default")=0; + + + /** @brief Get specified version of Assignment with all related objects + * + * @param int run + * @param const char * path + * @param const char * variation + * @param int version + * @return DAssignment* + */ + virtual Assignment* GetAssignmentFull(int run, const string& path, int version, const string& variation="default")=0; + + /** + * @brief Complex and universal function to retrieve assignments + * + * @warning this function is too complex for users. + * Use overloaded GetAssignments instead of it. + * And only use this function if others are inapropriate + * + * This function is universal assignments getter. + * Provided fields allows to select assignments (arrays and single assignments) + * for most cases. Other GetAssignments(...) and GetAssignmentFull(...) + * functions relie on this function. + * + * + * runMin, runMax: + * applied if one !=0. Thus runMin=runMax=0 will select all run ranges + * If one needs particular run, runMin=runMax= should be used + * + * runRangeName: + * will be ignored if equals to "" + * + * variation: + * if "", all variations will be get + * + * date: + * unix timestamp that indicates the latest time to select assignments from + * if 0 - time will be ignored + * sortby: + * 0 - `assignments`.`created` DESC + * 1 - `assignments`.`created` ASC + * + * take, startWith + * paging parameters + * + * @param [out] assingments result assignment list + * @param [in] path path of type table + * @param [in] run specified range. If not set all ranges + * @param [in] variation variation, if not set, all variations + * @param [in] date nearest date + * @param [in] sortBy sortby order + * @param [in] startWith record to start with + * @param [in] take records to select + * @return true if no errors (even if no assignments was selected) + */ + virtual bool GetAssignments(vector &assingments,const string& path, int runMin, int runMax, const string& runRangeName, const string& variation, time_t beginTime, time_t endTime, int sortBy=0, int take=0, int startWith=0)=0; + + + /** + * @brief Get assigments for particular run + * + * returns vector of assignments + * Variation: if variation is not empty string the assignments for specified variation will be returned + * otherwise all variations will be accepted + * + * Date: if date is not 0, assignments which are earlier than this date will be returned + * otherwise returned assignments will be not filtered by date + * + * Paging: paging could be done with @see take ans @see startWith + * take=0, startWith=0 means select all records; + * + * + * @param [out] assingments + * @param [in] path + * @param [in] run + * @param [in] variation + * @param [in] date + * @param [in] take + * @param [in] startWith + * @return + */ + virtual bool GetAssignments(vector &assingments,const string& path, int run, const string& variation="", time_t date=0, int take=0, int startWith=0)=0; + + /** + * @brief Get assigments for particular run + * + * returns vector of assignments + * Variation: if variation is not empty string the assignments for specified variation will be returned + * otherwise all variations will be accepted + * + * Date: if date is not 0, assignments which are earlier than this date will be returned + * otherwise returned assignments will be not filtered by date + * + * Paging: paging could be done with @see take ans @see startWith + * take=0, startWith=0 means select all records; + * + * + * @param [in] path + * @param [in] run + * @param [in] variation + * @param [in] date + * @param [in] take + * @param [in] startWith + * @return assingments + */ + virtual vector GetAssignments(const string& path, int run, const string& variation="", time_t date=0, int take=0, int startWith=0)=0; + + /** + * @brief Get assigments for particular run + * + * returns vector of assignments + * Variation: if variation is not emty string the assignments for specified variation will be returned + * otherwise all variations will be accepted + * + * Date: if date is not 0, assignments wich are earlier than this date will be returned + * otherwise returned assignments will be not filtred by date + * + * Paging: paging could be done with @see take ans @see startWith + * take=0, startWith=0 means select all records; + * + * + * @param [out] assingments + * @param [in] path + * @param [in] run + * @param [in] variation + * @param [in] date + * @param [in] take + * @param [in] startWith + * @return + */ + virtual bool GetAssignments(vector &assingments,const string& path, const string& runName, const string& variation="", time_t date=0, int take=0, int startWith=0)=0; + + /** + * @brief Get assigments for particular run + * + * returns vector of assignments + * Variation: if variation is not emty string the assignments for specified variation will be returned + * otherwise all variations will be accepted + * + * Date: if date is not 0, assignments wich are earlier than this date will be returned + * otherwise returned assignments will be not filtred by date + * + * Paging: paging could be done with @see take ans @see startWith + * take=0, startWith=0 means select all records; + * + * + * @param [out] assingments + * @param [in] path + * @param [in] run + * @param [in] variation + * @param [in] date + * @param [in] take + * @param [in] startWith + * @return + */ + virtual vector GetAssignments(const string& path, const string& runName, const string& variation="", time_t date=0, int take=0, int startWith=0)=0; + + + /** + * @brief Fill assignment with data if it has proper ID + * + * The function actually gets assignment by ID. + * + * A problem: is that for DB providers the id is assignment->GetId(). + * For file provider the id is probably a type table full path + * A solution: + * is to have this function that accepts DAssignment* assignment. + * DAssignment* assignment incapsulates the id (one way or another) + * And each provider could check if this DAssignment have valid Id, + * fill assignment with data and return true. + * Or just return "false" if something goes wrong; + * + * @param [in, out] assignment to fill + * @return true if success and assignment was filled with data + */ + virtual bool FillAssignment(Assignment* assignment)=0; + +#ifndef __GNUC__ + #pragma endregion Assignments +#endif + + //---------------------------------------------------------------------------------------- + // E R R O R H A N D L I N G + //---------------------------------------------------------------------------------------- + /** + * @brief Get number of errors + * @return + */ + virtual int GetNErrors(); + + /** + * @brief Get vector of last errors + */ + virtual const std::vector& GetErrorCodes(); + + /** @brief return vector of errors. + * @warning the error objects are deleted on next function that clears errors. + * (!) Copy this error objects before next provider function call. + * @return std::vector + */ + virtual std::vector GetErrors(); + + /** + * @brief Gets last of the last error + * @return error code + */ + virtual int GetLastError(); + + /** @brief Logs error + * + * @param errorCode Error codes see DCCDBGlobals.h + * @param module Caller should specify method name here + * @param message Message of the error + * @return void + */ + virtual void Error(int errorCode, const std::string& module, const std::string& message); + + /** @brief Logs error + * + * @param errorCode Error codes see DCCDBGlobals.h + * @param module Caller should specify method name here + * @param message Message of the error + * @return void + */ + virtual void Warning(int errorCode, const std::string& module, const std::string& message); + + /** @brief Clears Errors + * function is called on start of each function that produce errors + * @return void + */ + virtual void ClearErrors(); + + //---------------------------------------------------------------------------------------- + // O T H E R F U N C T I O N S + //---------------------------------------------------------------------------------------- + + /** @brief Validates name for constant type table or directory or column + * + * @param string name + * @return bool + */ + bool ValidateName(const string& name); + + + + //---------------------------------------------------------------------------------------- + // L O G G I N G + //---------------------------------------------------------------------------------------- + std::string GetLogUserName() const { return mLogUserName; } ///User name for logging + void SetLogUserName(std::string val) { mLogUserName = val; } ///User name for logging + + + +protected: + /** @brief Sets IsLoaded() and resets IsChanged()Yt + * + * @param obj + * @return void + */ + void SetObjectLoaded(StoredObject* obj); + + /******* D I R E C T O R I E S W O R K *******/ + vector mDirectories; + map mDirectoriesById; + map mDirectoriesByFullPath; + bool mDirsAreLoaded; //Directories are loaded from database + bool mNeedCheckDirectoriesUpdate; //Do we need to check each time iff directories are updated or not + Directory *mRootDir; ///root directory. This directory contains all other directories. It is not stored in databases + + + /** + @brief Clear error state on start of each function that emits error + */ + virtual void ClearErrorsOnFunctionStart(); + + vector mErrorCodes; ///vector of last errors + + vector mErrors; ///errors + + int mLastError; ///last error + + const int mMaximumErrorsToHold; ///=100 Maximum errors to hold in @see mLastErrors + + std::string mLogUserName; ///User name + + std::string mConnectionString; ///Connection string that was used on last successfully connect. + + IAuthentication * mAuthentication; + + map mVariationsById; +}; +} +#endif // _DDataProvider_ + diff --git a/ccdb_patch/Directory.h b/ccdb_patch/Directory.h new file mode 100644 index 0000000..c8a9f32 --- /dev/null +++ b/ccdb_patch/Directory.h @@ -0,0 +1,115 @@ +/* + * Directory.h + * + * Created on: Sep 15, 2010 + * Author: romanov + */ + +#ifndef CONSTANTDIRECTORY_H_ +#define CONSTANTDIRECTORY_H_ +#include +#include +#include + +#include "CCDB/Model/StoredObject.h" +#include "CCDB/Model/ObjectsOwner.h" +#include "CCDB/Globals.h" + +using namespace std; + +namespace ccdb{ + +class Directory : public StoredObject +{ + +public: + + /** @brief Stored object constructor + * + * @param [in] owner + * @param [in] provider + * @return + */ + Directory(ObjectsOwner * owner, DataProvider *provider=NULL); + + Directory(); ///Default constructor + + virtual ~Directory(); ///Destructor + + /** + * @brief Get + * @return pointer to parent directory. NULL if there is no parent directory + */ + Directory* GetParentDirectory(); + + /** + * @brief Gets the vector of pointers to subdirectories + * @return vector of pointers to subdirectories + */ + const vector& GetSubdirectories(); + + /** + * @brief Adds a subdirectory of this directory + * + * Adds a subdirectory of this directory + * Automatically adds "this" as mParent for child + * + * @param subDirectory Child directory to be added + */ + void AddSubdirectory(Directory *subdirectory); + + /** + * @brief deletes all subdirectories recursively + */ + void DisposeSubdirectories(); + + dbkey_t GetId() const; ///DB id + void SetId(dbkey_t val); ///DB id + + dbkey_t GetParentId() const; ///DB id of parent directory. Id=0 - root directory + void SetParentId(dbkey_t val); ///DB id of parent directory. Id=0 - root directory + + string GetName() const; ///Name of the directory + void SetName(string val); ///Name of the directory + + string GetFullPath() const; ///Full path (including self name) of the directory + void SetFullPath(string val); ///Full path (including self name) of the directory + + time_t GetCreatedTime() const; ///Creation time + void SetCreatedTime(time_t val); ///Creation time + + time_t GetModifiedTime() const; ///Last modification time + void SetModifiedTime(time_t val);///Last modification time + + string GetComment() const; ///Full description of the directory + void SetComment(string val); ///Full description of the directory +protected: + + /** + * @brief Sets parent directory of this directory + * + * Sets parent directory of this directory. + * The function should not be used unless from @link AddSubdirecrory method + * So one uses only AddSubdirecrory to generate directories structure + * @param parent Parent directory. Might be NULL if No parent is present + */ + void SetParent(Directory *parent); //TODO delete this and check everything works + +private: + string mName; ///Name of directorey like in db + string mFullPath; ///full path + string mComment; ///Comment like in db + Directory *mParent; + vector mSubDirectories; + dbkey_t mParentId; + dbkey_t mId; + time_t mCreatedTime; + time_t mModifiedTime; + + + Directory(const Directory& rhs):StoredObject{rhs}{} + Directory& operator=(const Directory& rhs); +}; + +} +#endif /* CONSTANTDIRECTORY_H_ */ diff --git a/ccdb_patch/Library_SConscript b/ccdb_patch/Library_SConscript new file mode 100644 index 0000000..731f8f8 --- /dev/null +++ b/ccdb_patch/Library_SConscript @@ -0,0 +1,141 @@ +Import('default_env', 'ccdb_sqlite_lib') +env = default_env.Clone() #Clone it to add library specified things + + +#TODO move to normal debug\release modes +#debugcflags = ['-W1', '-GX', '-EHsc', '-D_DEBUG', '/MDd'] #extra compile flags for debug +#releasecflags = ['-O2', '-EHsc', '-DNDEBUG', '/MD'] #extra compile flags for release + +#Mac Os X requires install_name flag to be built properly +if env['PLATFORM'] == 'darwin': + print() + print("Darwin platform is detected. Setting -install_name @rpath/"+'${TARGET.file}') + env.Append(SHLINKFLAGS = ['-install_name', '@rpath/'+'${TARGET.file}']) + + +#Set target and sources +lib_target = "ccdb" +lib_sources = [ + + #some global objects + "Console.cc", + "Log.cc", + "CCDBError.cc", + "GlobalMutex.cc", + "IMutex.cc", + "ISyncObject.cc", + "PthreadMutex.cc", + "PthreadSyncObject.cc", + + #user api + "Calibration.cc", + "CalibrationGenerator.cc", + "SQLiteCalibration.cc", + + #helper classes + "Helpers/StringUtils.cc", + "Helpers/PathUtils.cc", + "Helpers/WorkUtils.cc", + "Helpers/TimeProvider.cc", + + #model and provider + "Model/ObjectsOwner.cc", + "Model/StoredObject.cc", + "Model/Assignment.cc", + "Model/ConstantsTypeColumn.cc", + "Model/ConstantsTypeTable.cc", + "Model/Directory.cc", + "Model/EventRange.cc", + "Model/RunRange.cc", + "Model/Variation.cc", + "Providers/DataProvider.cc", + "Providers/FileDataProvider.cc", + "Providers/SQLiteDataProvider.cc", + "Providers/IAuthentication.cc", + "Providers/EnvironmentAuthentication.cc", + ] + +#additional variables +env.Append(LIBS = ['pthread']) +env.Append(LIBS = ccdb_sqlite_lib) + +if env['PLATFORM'] != 'darwin': + env.Append(LIBS = ['rt']) + +env.Append(CCFLAGS='-Wno-unknown-pragmas -g -O2 -std=c++11') #Disable unknown pragmas warnings. CCDB files have '#pragma region' records to structurize files. + +if ARGUMENTS.get("with-m32","false")=="true": + print("compile with -m32 flag") + env.Append(CCFLAGS='-m32') #Disable unknown pragmas warnings. CCDB files have '#pragma region' records to structurize files. +else: + print("To compile with -m32 forced use 'with-m32=true' flag") + +#Build with mysql or no? +#Read user flag for using mysql dependencies or not +if ARGUMENTS.get("mysql","no")=="yes" or ARGUMENTS.get("with-mysql","true")=="true": + #User wants mysql! + print("Building CCDB using MySQL dependencies") + print("To build CCDB without mysql dependencies. Run scons with 'with-mysql=false'") + print("") + + print('WhereIs("mysql_config"): {}'.format(WhereIs("mysql_config"))) + + mysql_config_path = WhereIs("mysql_config") + + if not mysql_config_path: + print() + print("ERROR. Can't find 'mysql_config' utility which is needed to build CCDB with MySQL support.") + print("Two options is possible to build CCDB:") + print(" 1. Install mysql_config (RHEL has it in mysql-devel package, Ubuntu in libmysqlclient-dev)") + print(" 2. Build CCDB without MySQL dependencies (use 'mysql=no' scons flag)") + print() + Exit() + + mysql_sources = [ + #user api + "MySQLCalibration.cc", + + #model and provider + "Providers/MySQLConnectionInfo.cc", + "Providers/MySQLDataProvider.cc"] + + lib_sources.extend(mysql_sources) + env.Append(CPPDEFINES='CCDB_MYSQL') + + from subprocess import Popen, PIPE + import shlex + + process = Popen([mysql_config_path, "--libs", "--cflags"], stdout=PIPE) + (output, err) = process.communicate() + exit_code = process.wait() + + mysql_lib_location_flag = "" + for token in shlex.split(output): + if token.startswith('-L'): + env.Append(LINKFLAGS=[token]) # Add something like -L/usr/lib64/mysql to lib flags + break + + env.Append(LIBS=['mysqlclient']) + env.ParseConfig('mysql_config --cflags') +else: + print("CCDB is being build WITHOUT MySQL support. Use 'with-mysql=true' flag to explicitly enable MySQL support") + + +if ARGUMENTS.get("with-perflog","false")=="true": + print("with-perflog=true - compile with performance logging ") + env.Append(CPPDEFINES='CCDB_PERFLOG_ON') +else: + print("with-perflog=false - NO performance logging ") + +if ARGUMENTS.get("with-cacheon", "true")=="true": + print("with-cacheon=true - with data cache on by default ") + env.Append(CPPDEFINES='CCDB_CACHE_ON') +else: + print("with-cacheon=false - with data cache off by default ") + +#Making library +lib = env.SharedLibrary(target = lib_target, source = lib_sources) +env.Install('#lib', lib) + +static_lib = env.StaticLibrary(target = lib_target, source = lib_sources) +env.Install('#lib', static_lib) \ No newline at end of file diff --git a/ccdb_patch/SConstruct b/ccdb_patch/SConstruct new file mode 100644 index 0000000..7253943 --- /dev/null +++ b/ccdb_patch/SConstruct @@ -0,0 +1,38 @@ +import sys +import os + +#Setup default environment. This environment +if not 'CCDB_HOME' in os.environ: + print("CCDB_HOME environment variable is not found but should be set to compile the CCDB") + print("One can run 'source environment.bash' from your bash shell to automatically set environment variables") + exit(1) + +#Create 'default' environment. Other environments will be a copy of this one +default_env = Environment( + #>> CCDB related default staff << + CPPPATH = ['#include', '#src', '#include/SQLite'], + ENV = os.environ, +) + +#Read user flag for using mysql dependencies or not +if ARGUMENTS.get("clang","false")=="true": + default_env["CXX"] = "clang++" + default_env["ENV"]["TERM"]=os.environ["TERM"] + +#Export 'default' environment for everything that whishes to use it +Export('default_env') + +#Create 'working' environment +default_env.Repository('src') + +#Attach SConsctipts +SConscript('src/SQLite/SConscript', 'default_env', variant_dir='tmp/SQLite', duplicate=0) +SConscript('src/Library/SConscript', 'default_env', variant_dir='tmp/Library', duplicate=0) +SConscript('src/Tests/SConscript', 'default_env', variant_dir='tmp/Tests', duplicate=0) + +if ARGUMENTS.get("with-examples","false")=="true": + print("Building with examples. To run example print example_ccdb_ in console") + SConscript('examples/SConscript', 'default_env', variant_dir='tmp/Examples', duplicate=0) +else: + print("Building without examples. To build with examples add 'with-examples=true' flag") + diff --git a/clasqaDB b/clasqaDB new file mode 160000 index 0000000..fa90188 --- /dev/null +++ b/clasqaDB @@ -0,0 +1 @@ +Subproject commit fa9018891b3c10e28b16ac4d62be0b63247e5825 diff --git a/hipo4/CMakeLists.txt b/hipo4/CMakeLists.txt index d4ac1a6..d5e1421 100644 --- a/hipo4/CMakeLists.txt +++ b/hipo4/CMakeLists.txt @@ -14,7 +14,11 @@ endif() install(TARGETS Hipo4 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") -FILE(GLOB ROOT_HIPO_PCM ${CMAKE_BINARY_DIR}/hipo4/*pcm) +#FILE(GLOB ROOT_HIPO_PCM ${CMAKE_BINARY_DIR}/hipo4/*pcm) + +#install (FILES ${ROOT_HIPO_PCM} +# DESTINATION "${CMAKE_INSTALL_LIBDIR}") + +install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libHipo4_rdict.pcm + DESTINATION "${CMAKE_INSTALL_LIBDIR}") -install (FILES ${ROOT_HIPO_PCM} - DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/hipo4/ntuple_reader.cpp b/hipo4/ntuple_reader.cpp index 30baa53..b7db504 100644 --- a/hipo4/ntuple_reader.cpp +++ b/hipo4/ntuple_reader.cpp @@ -8,7 +8,7 @@ namespace hipo{ ntuple_reader::ntuple_reader(string name){ _reader.open(name.data()); _reader.readDictionary(_dict); - //_dict.show(); + // _dict.show(); //create getters functions _getters[0]=[](hipo::bank* b,void *addr,int item, int index){ @@ -33,7 +33,7 @@ namespace hipo{ } _schemaID[name]=_bankNumber++; auto sch=_dict.getSchema(name.data()); - + bank_uptr bank{new hipo::bank{sch}}; _bankNames.push_back(name); _itemLinksAndGets.push_back(data_addrs_to_func(sch.getEntries())); @@ -158,8 +158,7 @@ namespace hipo{ auto ptr = double_uptr(new double); auto raw = ptr.get(); auto isch=_schemaID[bankName]; - - //Check item exists + //Check item exists auto& sch = _schemas[isch]; if(sch.exists(itemName.data())==false){ std::cerr<<"Error item "<first(rawBank,itemFuncAndAddr->second,pos++,0); + if(itemFuncAndAddr.get()!=nullptr){ + itemFuncAndAddr->first(rawBank,itemFuncAndAddr->second,pos,0); + } + pos++; } ++ibank; } diff --git a/hipo4/ntuple_reader.h b/hipo4/ntuple_reader.h index 93a4cf7..42a4797 100644 --- a/hipo4/ntuple_reader.h +++ b/hipo4/ntuple_reader.h @@ -31,7 +31,12 @@ namespace hipo { int64_t& getLong(string bankName,string itemName); float& getFloat(string bankName,string itemName); double& getDouble(string bankName,string itemName); - + + + void show(const string& bank){ + auto sch=_dict.getSchema(bank.data()); + sch.show(); + } private: hipo::reader _reader; hipo::dictionary _dict; diff --git a/hipo4/reader.cpp b/hipo4/reader.cpp index ecd7e32..31c40c6 100644 --- a/hipo4/reader.cpp +++ b/hipo4/reader.cpp @@ -51,7 +51,7 @@ namespace hipo { */ reader::reader(){ printWarning(); - hipoutils.printLogo(); + if(_verbose)hipoutils.printLogo(); } /** @@ -129,13 +129,15 @@ namespace hipo { header.version = word_8&0x000000FF; header.bitInfo = (word_8>>8)&0x00FFFFFF; header.firstRecordPosition = 4*header.headerLength + header.userHeaderLength; - printf("----------------------------------------\n"); - printf("**** reader:: header version : %d \n",header.version); - printf("**** reader:: header length : %d \n",header.headerLength*4); - printf("**** reader:: first record pos : %lu\n",header.firstRecordPosition); - printf("**** reader:: trailer position : %lu\n",header.trailerPosition); - printf("**** reader:: file size : %lu\n",inputStreamSize); - printf("----------------------------------------\n"); + if(_verbose){ + printf("----------------------------------------\n"); + printf("**** reader:: header version : %d \n",header.version); + printf("**** reader:: header length : %d \n",header.headerLength*4); + printf("**** reader:: first record pos : %lu\n",header.firstRecordPosition); + printf("**** reader:: trailer position : %lu\n",header.trailerPosition); + printf("**** reader:: file size : %lu\n",inputStreamSize); + printf("----------------------------------------\n"); + } //int *signature = reinterpret_cast(&headerBuffer[0]); //printf("signature = %X\n",(unsigned int) *signature); //std::cout << "signature = " << std::ios::hex << (*signature) << '\n'; @@ -151,13 +153,13 @@ namespace hipo { void reader::readIndex(){ inputRecord.readRecord(inputStream,header.trailerPosition,0); - printf("*** reader:: trailer record event count : %d\n",inputRecord.getEventCount()); + if(_verbose)printf("*** reader:: trailer record event count : %d\n",inputRecord.getEventCount()); hipo::event event; inputRecord.readHipoEvent(event,0); - event.show(); + if(_verbose)event.show(); hipo::structure base; event.getStructure(base,32111,1); - base.show(); + if(_verbose)base.show(); readerEventIndex.clear(); int rows = base.getSize()/32; @@ -184,7 +186,7 @@ void reader::readIndex(){ } readerEventIndex.rewind(); //printf("**** reader:: header version : %d \n",readerEventIndex.getMaxEvents()); - printf("**** reader:: # of events : %d \n",readerEventIndex.getMaxEvents()); + if(_verbose)printf("**** reader:: # of events : %d \n",readerEventIndex.getMaxEvents()); } /** * Checks if there are more events in the file to advance to. diff --git a/hipo4/reader.h b/hipo4/reader.h index e50f213..e597749 100644 --- a/hipo4/reader.h +++ b/hipo4/reader.h @@ -209,7 +209,8 @@ namespace hipo { hipo::record inputRecord; hipo::readerIndex readerEventIndex; std::vector tagsToRead; - + short _verbose = {0} ; + void readHeader(); void readIndex(); public: @@ -225,10 +226,10 @@ namespace hipo { void open(const char *filename); void setTags(int tag){ tagsToRead.push_back(tag);} - void setTags(std::vector tags){ tagsToRead=std::move(tags);} - - - bool hasNext(); + void setTags(std::vector tags){ tagsToRead=std::move(tags);} + void setVerbose(short level=1){_verbose=level;} + + bool hasNext(); bool next(); bool gotoEvent(int eventNumber); bool gotoRecord(int irec); diff --git a/hipo4/record.cpp b/hipo4/record.cpp index 3d75543..d528779 100644 --- a/hipo4/record.cpp +++ b/hipo4/record.cpp @@ -126,7 +126,7 @@ namespace hipo { //showBuffer(&recordBuffer[0], 10, 200); //unzipBenchmark.resume(); if(recordHeader.compressionType==0){ - printf("compression type = 0 data length = %d\n",decompressedLength); + //printf("compression type = 0 data length = %d\n",decompressedLength); memcpy((&recordBuffer[0]),(&recordCompressedBuffer[0]),decompressedLength); } else { int unc_result = getUncompressed((&recordCompressedBuffer[0]) , (&recordBuffer[0]), diff --git a/hipo4/writer.cpp b/hipo4/writer.cpp index e8709dc..87f6d90 100644 --- a/hipo4/writer.cpp +++ b/hipo4/writer.cpp @@ -48,8 +48,9 @@ namespace hipo { for(int i = 0; i < schemaList.size(); i++){ std::string schemaString = writerDictionary.getSchema(schemaList[i].c_str()).getSchemaString(); std::string schemaStringJson = writerDictionary.getSchema(schemaList[i].c_str()).getSchemaStringJson(); - printf("STR : %s\n",schemaString.c_str()); - printf("JSON : %s\n",schemaStringJson.c_str()); + //---> Can open after debug level is introduced in the class + //printf("STR : %s\n",schemaString.c_str()); + //printf("JSON : %s\n",schemaStringJson.c_str()); schemaEvent.reset(); structure schemaNode(120,2,schemaString); structure schemaNodeJson(120,1,schemaStringJson); diff --git a/installC12Root b/installC12Root index 5a7f195..8ad2cb9 100755 --- a/installC12Root +++ b/installC12Root @@ -1,8 +1,6 @@ -cp $HIPO/hipo4/*.h hipo4/. -cp $HIPO/hipo4/*.cpp hipo4/. +#cp $HIPO/hipo4/*.h hipo4/. +#cp $HIPO/hipo4/*.cpp hipo4/. mkdir build cd build cmake ../ -make -cmake ../ make install diff --git a/installDBs b/installDBs index 46548ab..2ad6642 100755 --- a/installDBs +++ b/installDBs @@ -1,11 +1,15 @@ -git clone --recurse-submodules https://github.com/c-dilks/clasqaDB.git -setenv CLASQADB_HOME $PWD/clasqaDB/ +#git clone --recurse-submodules https://github.com/c-dilks/clasqaDB.git +setenv QADB $PWD/clasqaDB/ -git clone --recurse-submodules https://github.com/jeffersonlab/rcdb.git +#git clone --recurse-submodules https://github.com/jeffersonlab/rcdb.git setenv RCDB_HOME $PWD/rcdb -git clone --recurse-submodules https://github.com/JeffersonLab/ccdb.git +#git clone --recurse-submodules https://github.com/JeffersonLab/ccdb.git +#cp $CLAS12ROOT/ccdb_patch/Directory.h $CCDB_HOME/include/CCDB/Model/Directory.h +#cp $CLAS12ROOT/ccdb_patch/DataProvider.h $CCDB_HOME/include/CCDB/Providers/DataProvider.h +#cp $CLAS12ROOT/ccdb_patch/Library_SConscript $CCDB_HOME/src/Library/SConscript +#cp $CLAS12ROOT/ccdb_patch/SConstruct $CCDB_HOME/SConstruct cd ccdb source environment.csh diff --git a/rcdb b/rcdb new file mode 160000 index 0000000..78bd83d --- /dev/null +++ b/rcdb @@ -0,0 +1 @@ +Subproject commit 78bd83dc19d359eeaee6d3e09a07b47bb9bd1de4 diff --git a/tutorial/Analysis.C b/tutorial/Analysis.C index 5fecb6b..a4f5054 100644 --- a/tutorial/Analysis.C +++ b/tutorial/Analysis.C @@ -3,7 +3,20 @@ HipoChain chain; chain.Add("/where/is/myHipo.hipo"); - + + auto config_c12=chain.GetC12Reader(); + config_c12->addExactPid(11,1); //exactly 1 electron + config_c12->addExactPid(211,1); //exactly 1 pi+ + config_c12->addExactPid(-211,1); //exactly 1 pi- + config_c12->addExactPid(2212,1); //exactly 1 proton + config_c12->addExactPid(22,2); //exactly 2 gamma + /////////config_c12->addZeroOfRestPid(); //nothing else + // config_c12->useFTBased(); //and use the Pids from RECFT + + //now get reference to (unique)ptr for accessing data in loop + //this will point to the correct place when file changes + auto& c12=chain.C12ref(); + //create particles before looping to be more efficient TLorentzVector p4_gamma1; TLorentzVector p4_gamma2; @@ -12,48 +25,33 @@ TH1F hmass("pi0mass","Invariant Mass to 2#gamma",100,0,0.6); TH1F htime("DeltaTime","Time difference of 2#gamma",100,-10,10); - //loop over files - for(int ifile=0;ifilegetDetParticles().empty()) + continue; - c12.addExactPid(11,1); //exactly 1 electron - c12.addExactPid(211,1); //exactly 1 pi+ - c12.addExactPid(-211,1); //exactly 1 pi- - c12.addExactPid(2212,1); //exactly 1 proton - c12.addExactPid(22,2); //exactly 2 gamma - - /////////c12.addZeroOfRestPid(); //nothing else - // c12.useFTBased(); //and use the Pids from RECFT - - //loop over all events in the file - while(c12.next()==true){ - - if(c12.getDetParticles().empty()) - continue; - - auto parts=c12.getDetParticles(); - - auto electron=c12.getByID(11)[0]; - auto gamma1=c12.getByID(22)[0]; - auto gamma2=c12.getByID(22)[1]; - auto proton=c12.getByID(2212)[0]; - auto pip=c12.getByID(211)[0]; - auto pim=c12.getByID(-211)[0]; - - p4_gamma1.SetXYZM(gamma1->par()->getPx(),gamma1->par()->getPy(),gamma1->par()->getPz(),0); - p4_gamma2.SetXYZM(gamma2->par()->getPx(),gamma2->par()->getPy(),gamma2->par()->getPz(),0); - - auto pi0 = p4_gamma1 + p4_gamma2; - - //Fill histograms if gammas are in FD - if(gamma1->getRegion()==FD && gamma2->getRegion()==FD){ - hmass.Fill(pi0.M()); - htime.Fill(gamma1->getTime() - gamma2->getTime() ); - } + auto parts=c12->getDetParticles(); + + auto electron=c12->getByID(11)[0]; + auto gamma1=c12->getByID(22)[0]; + auto gamma2=c12->getByID(22)[1]; + auto proton=c12->getByID(2212)[0]; + auto pip=c12->getByID(211)[0]; + auto pim=c12->getByID(-211)[0]; + + + p4_gamma1.SetXYZM(gamma1->par()->getPx(),gamma1->par()->getPy(),gamma1->par()->getPz(),0); + p4_gamma2.SetXYZM(gamma2->par()->getPx(),gamma2->par()->getPy(),gamma2->par()->getPz(),0); + + auto pi0 = p4_gamma1 + p4_gamma2; + + //Fill histograms if gammas are in FD + if(gamma1->getRegion()==FD && gamma2->getRegion()==FD){ + hmass.Fill(pi0.M()); + htime.Fill(gamma1->getTime() - gamma2->getTime() ); } - } - + TCanvas can; can.Divide(2,1); can.cd(1); diff --git a/tutorial/AnalysisWithExtraBanks.C b/tutorial/AnalysisWithExtraBanks.C index 96ef38a..667b924 100644 --- a/tutorial/AnalysisWithExtraBanks.C +++ b/tutorial/AnalysisWithExtraBanks.C @@ -2,9 +2,28 @@ HipoChain chain; chain.Add("/home/dglazier/clas12/clas12root/tutorial/skim.hipo"); - //chain.Add("/where/is/myHipo.hipo"); + chain.SetReaderTags({0}); //create clas12reader with just tag 0 events + //chain.Add("/where/is/myHipo.hipo"); + auto config_c12=chain.GetC12Reader(); + config_c12->addExactPid(11,1); //exactly 1 electron + config_c12->addExactPid(211,1); //exactly 1 pi+ + config_c12->addExactPid(-211,1); //exactly 1 pi- + config_c12->addExactPid(2212,1); //exactly 1 proton + config_c12->addExactPid(22,2); //exactly 2 gamma + //Add extra bank for reading and get its ID + auto idx_RECPart= config_c12->addBank("REC::Particle"); + //Add an item in the bank for reading and get its ID + auto iPid= config_c12->getBankOrder(idx_RECPart,"pid"); + + //get track based hits id and layers + //Add extra bank for reading and get its ID + auto idx_TRCKHits= config_c12->addBank("TimeBasedTrkg::TBHits"); + //Add an item in the bank for reading and get its ID + auto iTrckId = config_c12->getBankOrder(idx_TRCKHits,"id"); + auto iTrckLayer = config_c12->getBankOrder(idx_TRCKHits,"layer"); + //create particles before looping to be more efficient TLorentzVector p4_gamma1; TLorentzVector p4_gamma2; @@ -13,71 +32,49 @@ TH1F hmass("pi0mass","Invariant Mass to 2#gamma",100,0,0.6); TH1F htime("DeltaTime","Time difference of 2#gamma",100,-10,10); - //loop over files - for(int ifile=0;ifilegetDetParticles().empty()) + continue; - //Loop over entries in the bank for this event using its ID = idx_RECPart - //get the value of its PID from its id = iPid - for(auto ipa=0;ipagetRows();ipa++){ - cout<<"particle "<getInt(iPid,ipa)<getBank(idx_RECPart)->getRows();ipa++){ + cout<<"particle "<getBank(idx_RECPart)->getInt(iPid,ipa)<getRows();itr++){ - cout<<"track "<getInt(iTrckId,itr)<<" layer "<getInt(iTrckLayer,itr)<getBank(idx_TRCKHits)->getRows();itr++){ + cout<<"track "<getBank(idx_TRCKHits)->getInt(iTrckId,itr)<<" layer "<getBank(idx_TRCKHits)->getInt(iTrckLayer,itr)<getDetParticles(); - auto electron=c12.getByID(11)[0]; - auto gamma1=c12.getByID(22)[0]; - auto gamma2=c12.getByID(22)[1]; - auto proton=c12.getByID(2212)[0]; - auto pip=c12.getByID(211)[0]; - auto pim=c12.getByID(-211)[0]; + auto electron=c12->getByID(11)[0]; + auto gamma1=c12->getByID(22)[0]; + auto gamma2=c12->getByID(22)[1]; + auto proton=c12->getByID(2212)[0]; + auto pip=c12->getByID(211)[0]; + auto pim=c12->getByID(-211)[0]; - p4_gamma1.SetXYZM(gamma1->par()->getPx(),gamma1->par()->getPy(),gamma1->par()->getPz(),0); - p4_gamma2.SetXYZM(gamma2->par()->getPx(),gamma2->par()->getPy(),gamma2->par()->getPz(),0); + p4_gamma1.SetXYZM(gamma1->par()->getPx(),gamma1->par()->getPy(),gamma1->par()->getPz(),0); + p4_gamma2.SetXYZM(gamma2->par()->getPx(),gamma2->par()->getPy(),gamma2->par()->getPz(),0); - auto pi0 = p4_gamma1 + p4_gamma2; + auto pi0 = p4_gamma1 + p4_gamma2; - //Fill histograms if gammas are in FD - if(gamma1->getRegion()==FD && gamma2->getRegion()==FD){ - hmass.Fill(pi0.M()); - htime.Fill(gamma1->getTime() - gamma2->getTime() ); - } - } - + //Fill histograms if gammas are in FD + if(gamma1->getRegion()==FD && gamma2->getRegion()==FD){ + hmass.Fill(pi0.M()); + htime.Fill(gamma1->getTime() - gamma2->getTime() ); + } } + + TCanvas can; can.Divide(2,1);