From 954193957140b5e0fcfb5eaf1275b0098cbab2ee Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 8 Jun 2016 12:07:55 +0100 Subject: [PATCH 01/37] Only update the version to use, in the HPD image task, when publishing is enabled. --- Rich/RichOnlineCalib/doc/release.notes | 4 ++ .../src/RichOnlineHPDImageSummary.cpp | 51 +++++++++---------- .../src/RichOnlineHPDImageSummary.h | 11 +++- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/Rich/RichOnlineCalib/doc/release.notes b/Rich/RichOnlineCalib/doc/release.notes index 9b61c9f77..c2b69a5de 100644 --- a/Rich/RichOnlineCalib/doc/release.notes +++ b/Rich/RichOnlineCalib/doc/release.notes @@ -4,6 +4,10 @@ ! Purpose : Rich online automatic calibration !----------------------------------------------------------------------------- +! 2016-06-08 - Chris Jones + - Only update the version to use, in the HPD image task, when publishing is + enabled. + ! 2016-05-23 - Chris Jones - Adapt to the improvements in RichHPDImageSummary. diff --git a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp index 591bc38f4..a4e690b5c 100644 --- a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp +++ b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp @@ -193,7 +193,7 @@ StatusCode OnlineSummary::initialize() resetCalibCounters(); // Print Partition and publishing status - info() << "Partition = '" << m_partition << "' OK2Publish = " << okToPublishCalibs() << endmsg; + info() << "Partition = '" << m_partition << "', OK2Publish = " << okToPublishCalibs() << endmsg; // Are we publishing ? if ( okToPublishCalibs() ) @@ -201,7 +201,7 @@ StatusCode OnlineSummary::initialize() // Check the file system where the calibrations are to be written is accessible sc = createDir( m_xmlFilePath ); // write to summary file - writeToDimSummaryFile( m_Name + " Initialized" ); + writeToDimSummaryFile( m_Name + " Initialized" ); } // send a message to camera to say we are ready @@ -213,7 +213,7 @@ StatusCode OnlineSummary::initialize() //============================================================================= -OnlineSummary::HPDFitDimData * +OnlineSummary::HPDFitDimData * OnlineSummary::getHPDFitDimData( const Rich::DAQ::HPDCopyNumber & copyNumber ) { // find this HPD in the map @@ -244,8 +244,8 @@ OnlineSummary::getHists( const LHCb::RichSmartID& smartID ) // make a new occupancy histogram std::ostringstream name; name << "Rich_HPD_" << copyNumber.data() << "_Occupancy"; - m_hists[smartID].first.reset( new TH1D( name.str().c_str(), - name.str().c_str(), + m_hists[smartID].first.reset( new TH1D( name.str().c_str(), + name.str().c_str(), 201, -0.5, 200.5 ) ); std::ostringstream mess; mess << "Created occupancy histogram for HPD " << copyNumber << " " << smartID; @@ -467,8 +467,8 @@ void OnlineSummary::runCalibration( const std::string& type ) info() << "Starting HPD Calibration for run " << m_runNumber << " ..." << endmsg; // update the version to use for this calibration run - const bool versionOK = ( setVersion(m_Rich1TaskName) && - setVersion(m_Rich2TaskName) ); + // only do this when publishing + const bool versionOK = setVersions(); // To store HPD occupancies HPDOccData Rich1_OccsVec, Rich2_OccsVec; @@ -835,13 +835,13 @@ void OnlineSummary::runCalibration( const std::string& type ) const auto avHitsPerEvent = ( m_nEventsThisRun>0 ? m_nHitsThisRun/(double)m_nEventsThisRun : 0 ); const auto meanHPDOcc = ( !allPDIDs.empty() ? avHitsPerEvent / allPDIDs.size() : 0.0 ); std::ostringstream mocc; - mocc << "Av. HPD Occ. = " << meanHPDOcc + mocc << "Av. HPD Occ. = " << meanHPDOcc << ", Av. Hits/Event = " << avHitsPerEvent << ", #hits = " << m_nHitsThisRun << ", #events = " << m_nEventsThisRun; info() << mocc.str() << endmsg; cameraTool()->Append("TEXT",mocc.str()); - if ( m_nEventsThisRun >= m_minEventsForInactiveHPDs && + if ( m_nEventsThisRun >= m_minEventsForInactiveHPDs && avHitsPerEvent >= m_avTotalHitsForInactiveHPDs && m_nHitsThisRun >= ( m_avTotalHitsForInactiveHPDs * m_minEventsForInactiveHPDs ) && meanHPDOcc >= m_minAvHPDOccForInactiveHPDs ) @@ -934,20 +934,20 @@ void OnlineSummary::runCalibration( const std::string& type ) if ( UNLIKELY(m_printAllHPDs) ) { unsigned int nStrange(0); - for ( const auto& HPD : strangeHPDs ) + for ( const auto& HPD : strangeHPDs ) { if ( ++nStrange <= m_maxStrangeHPDReports ) { draw(HPD); } } unsigned int nOKHPD(0); - for ( const auto& HPD : okHPDs ) + for ( const auto& HPD : okHPDs ) { if ( ++nOKHPD <= m_maxOKHPDReports ) { draw(HPD); } } } - + // Close PDF summary printCanvas("]"); - + } // If printing all HPD images, reset their titles afterwards. @@ -1103,7 +1103,7 @@ StatusCode OnlineSummary::execute() } // Check to see if a calibration should be run due to a new run being detected - if ( UNLIKELY( m_runNumber != 0 && + if ( UNLIKELY( m_runNumber != 0 && m_runNumber != RunNumber ) ) { std::ostringstream mess; @@ -1194,10 +1194,10 @@ StatusCode OnlineSummary::finalize() deleteCanvas(); // clean up state listeners //finaliseDIMStates(); - if ( okToPublishCalibs() ) + if ( okToPublishCalibs() ) { // write to summary file - writeToDimSummaryFile( m_Name + " Finalized" ); + writeToDimSummaryFile( m_Name + " Finalized" ); } // return return SummaryBase::finalize(); @@ -1243,7 +1243,7 @@ void OnlineSummary::fillHistograms() std::ostringstream mess; mess << smartID.rich() << " is Inactive"; Warning( mess.str() ).ignore(); - continue; + continue; } // hits for this HPD @@ -1258,11 +1258,11 @@ void OnlineSummary::fillHistograms() // Fill occupancy histogram if ( hists.first ) { hists.first->Fill( double(hits.size()) ); } - // Fill the image histogram. Note this is copied from + // Fill the image histogram. Note this is copied from // SummaryBase::execute() locally here for CPU efficiency - if ( hists.second ) + if ( hists.second ) { - for ( const auto& h : hits ) + for ( const auto& h : hits ) { hists.second->Fill(h.pixelCol(),h.pixelRow()); } } @@ -1319,7 +1319,7 @@ bool OnlineSummary::writeHpdXml( HPDOccData& hpdOccs, // HPD image calibrations for ( const auto& i : hpdImages ) { xmlFile << i << "\n" << "\n"; } - + // HPD occupancies { std::string occS = ""; @@ -1578,7 +1578,6 @@ bool OnlineSummary::writeCachedConditions() cameraTool()->Append("TEXT",mess.str().c_str()); OK = false; } - } return OK; @@ -1850,10 +1849,10 @@ void OnlineSummary::draw( const HPDFitResult& hpd ) const using namespace std; const auto & res = hpd.fitResult; //draw( hpd.imageHist, "zcol" ); - const auto hList = - { hpd.imageHist, - hpd.fitResult.originalHist().get(), - hpd.fitResult.processedHist().get(), + const auto hList = + { hpd.imageHist, + hpd.fitResult.originalHist().get(), + hpd.fitResult.processedHist().get(), hpd.fitResult.fittedHist().get() }; unsigned int iPad(0); for ( const auto h : hList ) diff --git a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h index 9b83ac3e9..0d342dd84 100644 --- a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h +++ b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h @@ -234,10 +234,19 @@ namespace Rich std::string getLastLine(std::fstream& in) const; //============================================================================= - // Function to set version number + // Method to set version number for a given detector //============================================================================= bool setVersion( const std::string& subDet ); + //============================================================================= + // Update both detector versions + //============================================================================= + inline bool setVersions() + { + return ( okToPublishCalibs() ? + setVersion(m_Rich1TaskName) && setVersion(m_Rich2TaskName) : true ); + } + //============================================================================= // Function to get version of xml files //============================================================================= -- GitLab From d1ca384aa6980d8ae7681bf053c48c6b0651cbfe Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Fri, 10 Jun 2016 11:37:56 +0100 Subject: [PATCH 02/37] small clean up --- .../src/RichOnlineHPDImageSummary.cpp | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp index a4e690b5c..aca64c5bc 100644 --- a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp +++ b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp @@ -471,16 +471,17 @@ void OnlineSummary::runCalibration( const std::string& type ) const bool versionOK = setVersions(); // To store HPD occupancies - HPDOccData Rich1_OccsVec, Rich2_OccsVec; + std::map<Rich::DetectorType,HPDOccData> OccsVecs; // To store HPD image condition strings - HPDImageData Rich1_ImageVec, Rich2_ImageVec; + std::map<Rich::DetectorType,HPDImageData> ImageVecs; // reserve sizes - Rich1_OccsVec .reserve( 200 ); - Rich1_ImageVec.reserve( 200 ); - Rich2_OccsVec .reserve( 300 ); - Rich2_ImageVec.reserve( 300 ); + const auto nR1HPD(200), nR2HPD(300); + OccsVecs [Rich::Rich1].reserve( nR1HPD ); + ImageVecs[Rich::Rich1].reserve( nR1HPD ); + OccsVecs [Rich::Rich2].reserve( nR2HPD ); + ImageVecs[Rich::Rich2].reserve( nR2HPD ); // reset summary histograms m_imageShiftSummaryHist->Reset(); @@ -498,7 +499,7 @@ void OnlineSummary::runCalibration( const std::string& type ) auto messLevel = ICameraTool::INFO; // get the list of all HPD SmartIDs - const LHCb::RichSmartID::Vector& allPDIDs = hpdSmartIDsToProcess(); + const auto & allPDIDs = hpdSmartIDsToProcess(); // List of strange HPD fits to report in detail later on HPDFitResult::Vector strangeHPDs; @@ -528,8 +529,11 @@ void OnlineSummary::runCalibration( const std::string& type ) // Loop over HPDs for ( const auto& smartID : allPDIDs ) { + // Which RICH ? + const auto rich = smartID.rich(); + // Count HPDs per RICH - ++totalHPDs[smartID.rich()]; + ++totalHPDs[rich]; // message for camera for this HPD std::ostringstream hpdMess; @@ -616,13 +620,7 @@ void OnlineSummary::runCalibration( const std::string& type ) } // save results to write later on - if ( okToPublishCalibs() ) - { - if ( smartID.rich() == Rich::DetectorType::Rich1 ) - { Rich1_OccsVec.push_back( HpdOcc ); } - else if ( smartID.rich() == Rich::DetectorType::Rich2 ) - { Rich2_OccsVec.push_back( HpdOcc ); } - } + if ( okToPublishCalibs() ) { OccsVecs[rich].push_back(HpdOcc); } //====================================== // Now HPD image shift @@ -769,7 +767,7 @@ void OnlineSummary::runCalibration( const std::string& type ) } // The condition string - std::string condS = xmlString(siAlign); + auto condS = xmlString(siAlign); // if the HPD fit was not done if ( UNLIKELY( !usedHPDFit ) ) @@ -792,18 +790,12 @@ void OnlineSummary::runCalibration( const std::string& type ) } // Now write out xml file - if ( okToPublishCalibs() ) - { - if ( smartID.rich() == Rich::DetectorType::Rich1 ) - { Rich1_ImageVec.push_back( condS ); } - else if ( smartID.rich() == Rich::DetectorType::Rich2 ) - { Rich2_ImageVec.push_back( condS ); } - } + if ( okToPublishCalibs() ) { ImageVecs[rich].push_back(condS); } } // Si alignment condition OK // inactive HPDs - if ( !hpdSawHits ) { emptyHPDs[smartID.rich()].push_back(smartID); } + if ( !hpdSawHits ) { emptyHPDs[rich].push_back(smartID); } // Add summary for this HPD to camera message cameraTool()->Append("TEXT",hpdMess.str()); @@ -872,8 +864,10 @@ void OnlineSummary::runCalibration( const std::string& type ) bool r1XMLOK(true), r2XMLOK(true); if ( okToPublishCalibs() ) { - r1XMLOK = writeHpdXml( Rich1_OccsVec, Rich1_ImageVec, - emptyHPDs[Rich::Rich1], m_Rich1TaskName ); + r1XMLOK = writeHpdXml( OccsVecs [Rich::Rich1], + ImageVecs[Rich::Rich1], + emptyHPDs[Rich::Rich1], + m_Rich1TaskName ); if ( !r1XMLOK ) { std::ostringstream mess; @@ -881,8 +875,10 @@ void OnlineSummary::runCalibration( const std::string& type ) warning() << mess.str() << endmsg; cameraTool()->Append("TEXT",mess.str()); } - r2XMLOK = writeHpdXml( Rich2_OccsVec, Rich2_ImageVec, - emptyHPDs[Rich::Rich2], m_Rich2TaskName ); + r2XMLOK = writeHpdXml( OccsVecs [Rich::Rich2], + ImageVecs[Rich::Rich2], + emptyHPDs[Rich::Rich2], + m_Rich2TaskName ); if ( !r2XMLOK ) { std::ostringstream mess; -- GitLab From 0e735b692a88b6035799196c793b10c8a4f0e564 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 14 Jun 2016 11:39:23 +0100 Subject: [PATCH 03/37] Various cleanups to some monitors --- .../RichOnlineMonitors/src/RichDAQMonitor.cpp | 32 ++---------- Rich/RichOnlineMonitors/src/RichDAQMonitor.h | 50 ++++++++++--------- .../src/RichHPDNHitMonitor.cpp | 11 ++-- .../src/RichMissingHPDMonitor.cpp | 7 +-- .../src/RichMissingHPDMonitor.h | 12 +++-- 5 files changed, 43 insertions(+), 69 deletions(-) diff --git a/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp b/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp index 4057f7fc2..555024113 100755 --- a/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp @@ -28,33 +28,9 @@ using namespace Rich::Mon; // Standard constructor, initializes variables //============================================================================= DAQMonitor::DAQMonitor( const std::string& name, - ISvcLocator* pSvcLocator) - : Rich::HistoAlgBase ( name , pSvcLocator ), - m_RichSys ( NULL ), - m_SmartIDDecoder ( NULL ), - m_HpdUKL1DisableTool ( NULL ), - m_CamTool ( NULL ), - m_nEvts ( 0 ), - m_nEvtsLastUpdate ( 0 ), - m_TimeLastUpdate ( 0 ), - m_Name ( name ), - m_AlertEmptyEvent ( 0 ), - m_AlertActiveHPDs ( 0 ), - m_AlertEmptyHPD ( 0 ), - m_AlertDuplicateHPDL0 ( 0 ), - m_AlertEventID ( 0 ), - m_AlertBxID ( 0 ), - m_AlertL0ID ( 0 ), - m_AlertInvalidOdinTime ( 0 ), - m_AlertMissingOdin ( 0 ), - m_AlertParityFooter ( 0 ), - m_AlertHPDInhibit ( 0 ), - m_AlertHPDNotInhibitInvalidSmartRef( 0 ), - m_AlertExtendedHeader ( 0 ), - m_AlertHPDSuppressed ( 0 ), - m_SendAlertMessages ( false ), - m_SendAlertDirect ( false ), - m_AlertLevelBxID ( 3 ) + ISvcLocator* pSvcLocator ) + : Rich::HistoAlgBase ( name , pSvcLocator ), + m_Name ( name ) { // Add partition to camera name const char* partitionName = getenv("PARTITION"); @@ -1251,7 +1227,7 @@ StatusCode DAQMonitor::SendErrorSummary(const std::string& odinInfo) std::map<std::string,int>::const_iterator iAlertBegin; std::map<std::string,int>::const_iterator iAlertEnd; - if (m_AlertActiveHPDs > 0) + if ( m_AlertActiveHPDs > 0 ) { if (m_SendAlertMessages) { diff --git a/Rich/RichOnlineMonitors/src/RichDAQMonitor.h b/Rich/RichOnlineMonitors/src/RichDAQMonitor.h index 52cda9e1a..f62a45f61 100755 --- a/Rich/RichOnlineMonitors/src/RichDAQMonitor.h +++ b/Rich/RichOnlineMonitors/src/RichDAQMonitor.h @@ -129,25 +129,26 @@ namespace Rich private: /// Pointer to RICH system detector element - mutable const DeRichSystem * m_RichSys; + mutable const DeRichSystem * m_RichSys = nullptr; /// Raw Buffer Decoding tool - mutable const Rich::DAQ::IRawBufferToSmartIDsTool * m_SmartIDDecoder; + mutable const Rich::DAQ::IRawBufferToSmartIDsTool * m_SmartIDDecoder = nullptr; /// HPD disabling tool - mutable Rich::Mon::IHpdUkL1DisableTool * m_HpdUKL1DisableTool; + mutable Rich::Mon::IHpdUkL1DisableTool * m_HpdUKL1DisableTool = nullptr; - mutable ICameraTool * m_CamTool; ///< CAMERA error reporting tool + /// CAMERA error reporting tool + mutable ICameraTool * m_CamTool = nullptr; - unsigned long long m_nEvts; ///< Event count - unsigned long long m_nEvtsLastUpdate; ///< Event count for last message + unsigned long long m_nEvts{0}; ///< Event count + unsigned long long m_nEvtsLastUpdate{0}; ///< Event count for last message bool m_ExtendedVerbose; ///< even more output ulonglong m_OdinMinGpsTime; ///< Time at which data is considered to be valid int m_NL1Boards; ///< Number of UKL1 boards used bool m_CheckOdin; ///< enable/disable checks comparing to the ODIN bank bool m_RemoveFaultyHpdUKL1; ///< remove faulty HPDs from data - stream in UKL1 - time_t m_TimeLastUpdate; + time_t m_TimeLastUpdate{0}; int m_UpdateTimerInterval; ///< Interval at which to send error messages (in seconds) bool m_CheckEmptyHPD; ///< check for empty HPDs (w/o extended headers) bool m_MonitorBxID; ///< Monitor BX ID errors (not simulated in FEST) @@ -159,23 +160,24 @@ namespace Rich bool m_vetoNoBias; ///< Veto no bias events - int m_AlertEmptyEvent; - int m_AlertActiveHPDs; - int m_AlertEmptyHPD; - int m_AlertDuplicateHPDL0; - int m_AlertEventID; - int m_AlertBxID; - int m_AlertL0ID; - int m_AlertInvalidOdinTime; - int m_AlertMissingOdin; - int m_AlertParityFooter; - int m_AlertHPDInhibit; - int m_AlertHPDNotInhibitInvalidSmartRef; - int m_AlertExtendedHeader; - int m_AlertHPDSuppressed; - bool m_SendAlertMessages; ///< send text in addition to number of occourrance - bool m_SendAlertDirect; ///< send alerts as they arise to CAMERA (or just every nth event as summary) - int m_AlertLevelBxID; ///< level with which BsID errors are sent to CAMERA + unsigned int m_AlertEmptyEvent{0}; + unsigned int m_AlertActiveHPDs{0}; + unsigned int m_AlertEmptyHPD{0}; + unsigned int m_AlertDuplicateHPDL0{0}; + unsigned int m_AlertEventID{0}; + unsigned int m_AlertBxID{0}; + unsigned int m_AlertL0ID{0}; + unsigned int m_AlertInvalidOdinTime{0}; + unsigned int m_AlertMissingOdin{0}; + unsigned int m_AlertParityFooter{0}; + unsigned int m_AlertHPDInhibit{0}; + unsigned int m_AlertHPDNotInhibitInvalidSmartRef{0}; + unsigned int m_AlertExtendedHeader{0}; + unsigned int m_AlertHPDSuppressed{0}; + + bool m_SendAlertMessages{false}; ///< send text in addition to number of occourrance + bool m_SendAlertDirect{false}; ///< send alerts as they arise (or just every nth event as summary) + int m_AlertLevelBxID; ///< level with which BsID errors are sent to CAMERA bool m_Plot2DHisto; int m_MinErrorRate; diff --git a/Rich/RichOnlineMonitors/src/RichHPDNHitMonitor.cpp b/Rich/RichOnlineMonitors/src/RichHPDNHitMonitor.cpp index f84b40364..88d3950c7 100755 --- a/Rich/RichOnlineMonitors/src/RichHPDNHitMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichHPDNHitMonitor.cpp @@ -308,6 +308,10 @@ StatusCode HPDNHitMonitor::execute() // to be sure if ( !odin ) return StatusCode::SUCCESS; + const bool triggerSelected = ( odin->triggerType() == LHCb::ODIN::PhysicsTrigger || + odin->triggerType() == LHCb::ODIN::TechnicalTrigger || + odin->triggerType() == LHCb::ODIN::CalibrationTrigger ); + // // main loop - get all RICH SmartIDs corresponding to HPDs/hits // @@ -382,10 +386,6 @@ StatusCode HPDNHitMonitor::execute() } } - const bool triggerSelected = ( odin->triggerType() == LHCb::ODIN::PhysicsTrigger || - odin->triggerType() == LHCb::ODIN::TechnicalTrigger || - odin->triggerType() == LHCb::ODIN::CalibrationTrigger ); - if ( richDetector == Rich::Rich1 ) { nAllHitsRich1 += hitSmartIDs.size(); @@ -730,8 +730,7 @@ HPDNHitMonitor::GetRichPanelHistId(const Rich::DetectorType rich, { // create the name std::ostringstream id; - id << Rich::text(rich) - << Rich::text(rich, panel); + id << Rich::text(rich) << Rich::text(rich,panel); return id.str(); }// getRichPanelHistId() diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp index 60763d911..0168d1223 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp @@ -24,12 +24,7 @@ DECLARE_ALGORITHM_FACTORY( MissingHPDMonitor ) MissingHPDMonitor::MissingHPDMonitor( const std::string& name, ISvcLocator* pSvcLocator) : Rich::HistoAlgBase ( name , pSvcLocator ), - m_RichSys ( NULL ), - m_SmartIDDecoder ( NULL ), - m_HpdUKL1DisableTool ( NULL ), - m_CamTool ( NULL ), m_taeEvents ( 1, "" ), - m_nEvts ( 0 ), m_Name ( name ) { m_activeRICH[Rich::Rich1] = true; @@ -103,7 +98,7 @@ StatusCode MissingHPDMonitor::execute() } // main loop over HPDs in the data - const Rich::DAQ::L1Map &l1Map = smartIDDecoder()->allRichSmartIDs(m_taeEvents); + const auto & l1Map = smartIDDecoder()->allRichSmartIDs(m_taeEvents); if ( msgLevel(MSG::VERBOSE) ) verbose() << "L1 map has size " << l1Map.size() << endmsg; diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h index 19ecbfe4e..97ca2da87 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h @@ -108,14 +108,16 @@ namespace Rich private: /// Pointer to RICH system detector element - mutable const DeRichSystem * m_RichSys; + mutable const DeRichSystem * m_RichSys = nullptr; /// Raw Buffer Decoding tool - mutable const Rich::DAQ::IRawBufferToSmartIDsTool * m_SmartIDDecoder; + mutable const Rich::DAQ::IRawBufferToSmartIDsTool * m_SmartIDDecoder = nullptr; - mutable Rich::Mon::IHpdUkL1DisableTool * m_HpdUKL1DisableTool; ///< HPD reporting/disable tool + /// HPD reporting/disable tool + mutable Rich::Mon::IHpdUkL1DisableTool * m_HpdUKL1DisableTool = nullptr; - mutable ICameraTool * m_CamTool; ///< The camera reporting tool + /// The camera reporting tool + mutable ICameraTool * m_CamTool = nullptr; std::vector<std::string> m_taeEvents; ///< The TAE location(s) to monitor @@ -125,7 +127,7 @@ namespace Rich bool m_vetoNoBias; ///< Veto no bias events /// Count events - unsigned long long m_nEvts; + unsigned long long m_nEvts{0}; std::string m_Name; ///< Name for camera messages -- GitLab From 2c29e3757c570722812bc1dec384163f0802127d Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 14 Jun 2016 11:39:57 +0100 Subject: [PATCH 04/37] make number of runs in run stats summary a configurable option --- Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp | 5 +++-- Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp index aca64c5bc..1585e6683 100644 --- a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp +++ b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp @@ -94,6 +94,8 @@ OnlineSummary::OnlineSummary( const std::string& name, declareProperty("MaxFracInactiveHPDs", m_maxFracHPDsForInactiveList = 0.4 ); + declareProperty("RunStatsCacheSize", m_maxRunsToWrite = 10 ); + } //============================================================================ @@ -1527,10 +1529,9 @@ bool OnlineSummary::writeCachedConditions() if ( file.is_open() ) { cameraTool()->Append("TEXT","Run Stats Cache Location = "+runStatsFile()); - const unsigned int maxRunsToWrite = 10; // should eventually make a JO.. unsigned int nRun(0); for ( auto iRun = m_processedRuns.rbegin(); - iRun != m_processedRuns.rend() && ++nRun <= maxRunsToWrite; ++iRun ) + iRun != m_processedRuns.rend() && ++nRun <= m_maxRunsToWrite; ++iRun ) { file << iRun->first << std::endl; file << iRun->second << std::endl; diff --git a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h index 0d342dd84..ac7de862b 100644 --- a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h +++ b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.h @@ -623,16 +623,19 @@ namespace Rich std::string m_Rich1TaskName; /// Minimum number of entries in HPD image plots for fit - unsigned int m_minImageEntries ; + unsigned int m_minImageEntries; /// Minimum number of entries in HPD occ plots - unsigned int m_minOccEntries ; + unsigned int m_minOccEntries; /// Maximum fraction of HPDs for inactive list double m_maxFracHPDsForInactiveList; + /// Number of runs to include in the run stats cache + unsigned int m_maxRunsToWrite; + /// Precision for XML - unsigned int m_Precision ; + unsigned int m_Precision; // xml file path info std::string m_xmlFilePath; -- GitLab From 1ec8a96777a6fd0ac5b6a6aff7db488e0f019588 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 14 Jun 2016 11:40:48 +0100 Subject: [PATCH 05/37] add trigger bit 35 to DAQ monitor veto list --- Rich/Panoptes/options/RichDAQMon.py | 2 +- Rich/Panoptes/options/RichDAQMon_Offline.py | 2 +- Rich/Panoptes/options/daq-before.log | 874 ++++++++++++++++++++ 3 files changed, 876 insertions(+), 2 deletions(-) create mode 100644 Rich/Panoptes/options/daq-before.log diff --git a/Rich/Panoptes/options/RichDAQMon.py b/Rich/Panoptes/options/RichDAQMon.py index 59ed899e7..e598d35a4 100644 --- a/Rich/Panoptes/options/RichDAQMon.py +++ b/Rich/Panoptes/options/RichDAQMon.py @@ -64,7 +64,7 @@ def start(mode='Online'): if partition in ["LHCb"] : # LHCb global running Panoptes().TriggerMask = [48,55,57,96] - Panoptes().VetoMask = [100,104,105,106] + Panoptes().VetoMask = [35,100,104,105,106] else : # local runs Panoptes().TriggerMask = [48,55,57,96] diff --git a/Rich/Panoptes/options/RichDAQMon_Offline.py b/Rich/Panoptes/options/RichDAQMon_Offline.py index e088be1d2..071b67ef3 100644 --- a/Rich/Panoptes/options/RichDAQMon_Offline.py +++ b/Rich/Panoptes/options/RichDAQMon_Offline.py @@ -9,7 +9,7 @@ Panoptes().Mode = 'Offline' Panoptes().UseConditionsMap = False Panoptes().EvtMax = -1 -EventSelector().PrintFreq = 1000 +EventSelector().PrintFreq = 5000 importOptions( '$PANOPTESROOT/options/RichDAQMon-Common.py' ) diff --git a/Rich/Panoptes/options/daq-before.log b/Rich/Panoptes/options/daq-before.log new file mode 100644 index 000000000..37a69e5d3 --- /dev/null +++ b/Rich/Panoptes/options/daq-before.log @@ -0,0 +1,874 @@ +# setting LC_ALL to "C" +# Restarting with LD_PRELOAD='libtcmalloc.so' +# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon_Offline.py' +# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon-Common.py' +CondDBTag = cond-20160517 DDDBTag = dddb-20150724 +# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon-Common.py' +# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon_Offline.py' +# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/OfflineDataFiles.py' +# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/OfflineDataFiles.py' +# applying configuration of RichPixelCreatorConfig +# /***** User RichPixelCreatorConfig/RichPixelCreatorConfig ****************************************** +# |-UseClustersAsPixels = [False, False] (default: [False, False]) +# |-PixelCleaning = 'None' (default: 'HotHPDs') +# |-OutputLevel = 3 +# |-MaxHPDOccupancy = [200, 200] (default: [200, 200]) +# |-DataType = '' +# |-FindClusters = True +# |-Detectors = [True, True] (default: [True, True]) +# |-MaxPixels = 30000 +# |-HPDOccScaleFactor = [9999, 9999] (default: [9999, 9999]) +# |-Context = 'Offline' +# |-MaxHotPixelClusterSize = [10, 8] (default: [10, 8]) +# |-SpecialData = [] (default: []) +# |-BookKeeping = False +# \----- (End of User RichPixelCreatorConfig/RichPixelCreatorConfig) --------------------------------- +# applying configuration of Panoptes +# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/LHCbDevNightly/GaudiConf/options/RawDataIO.opts' +# EventPersistencySvc.CnvServices += { "LHCb::RawDataCnvSvc" }; +# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/LHCbDevNightly/GaudiConf/options/RawDataIO.opts' +['pciy.hep.phy.cam.ac.uk:45123'] +# /***** User Panoptes/Panoptes ********************************************************************** +# |-MonitorReconstructedEvents = False +# |-UseOnlineCondDBtag = False (default: False) +# |-SaverCycle = 6000000 (default: 900) +# |-SkipEvents = 0 +# |-WriteOutSelectedEvents = False +# |-UsePrivateTracking = False (default: False) +# |-MonName = 'RichDAQMon' (default: 'RichDAQMon') +# |-SuppressDecodingWarningsErrors = False +# |-DDDBtag = 'dddb-20150724' (default: '') +# |-MonitorRawEvents = True +# |-VeloOpen = False +# |-SaveHistograms = 1 +# |-UseOracle = False +# |-MessageSvcOutputLevel = 3 +# |-UseConditionsMap = False (default: False) +# |-Partition = '' (default: None) +# |-EvtMax = -1 (default: -1) +# |-TriggerMask = [48, 55, 57, 96] (default: [48, 55, 57, 96]) +# |-MonitorExpressEvents = False +# |-IgnoreEventIDMisMatches = False +# |-FieldOff = False +# |-Mode = 'Offline' (default: 'Offline') +# |-Simulation = False +# |-SelectedEventsDataFile = 'SelectedEvents.raw' +# |-UseIncidentSvc = True +# |-DisableUpdateAndReset = False +# |-DataType = '2016' (default: '2016') +# |-ResetHistogramsAfterSave = 1 +# |-CondDBtag = 'cond-20160517' (default: '') +# |-RawEventLocations = [''] (default: ['']) +# |-VetoMask = [100, 104, 105, 106] (default: [100, 104, 105, 106]) +# |-UseMonitorSvc = False +# |-msgSvc = ServiceHandle('MessageSvc') (default: None) +# \----- (End of User Panoptes/Panoptes) ------------------------------------------------------------- +# applying configuration of LHCbApp +# /***** User LHCbApp/LHCbApp ************************************************************************ +# |-Persistency = None +# |-OutputLevel = 3 +# |-DataType = '2016' (default: '2012') +# |-TimeStamp = False +# |-SkipEvents = 0 +# |-EvtMax = -1 (default: -1) +# |-CondDBtag = 'cond-20160517' (default: '') +# |-DQFLAGStag = '' +# |-IgnoreDQFlags = True +# |-Monitors = [] (default: []) +# |-Detectors = [] (default: []) +# |-LocalDataTypes = [] (default: []) +# |-XMLSummary = None +# |-Simulation = False +# |-DDDBtag = 'dddb-20150724' (default: '') +# |-OnlineMode = False +# \----- (End of User LHCbApp/LHCbApp) --------------------------------------------------------------- +# applying configuration of DDDBConf +# WARNING: Using default tag dq-20150717 for partition DQFLAGS +# WARNING: Using default tag head-2015604 for partition CALIBOFF +# /***** User DDDBConf/DDDBConf ********************************************************************** +# |-DataType = '2016' (default: '2012') +# |-InitialTime = 'Safe' +# |-Simulation = False +# |-AutoTags = False +# |-DbRoot = 'conddb:/lhcb.xml' +# |-OnlineMode = False +# \----- (End of User DDDBConf/DDDBConf) ------------------------------------------------------------- +# applying configuration of Camera +# /***** User Camera/Camera ************************************************************************** +# |-CameraServers = ['pciy.hep.phy.cam.ac.uk:45123'] (default: []) +# \----- (End of User Camera/Camera) ----------------------------------------------------------------- +# applying configuration of RichMonitoringSysConf +# /***** User RichMonitoringSysConf/RichMonitoringSysConf ******************************************** +# |-DaqMon_SendAlertDirect = False +# |-NHitMon_IndividualTriggerMonitors = True (default: True) +# |-SendNHitEventSnapshots = True (default: True) +# |-NHitMon_FillHistograms = True +# |-DaqMon_MaxErrorMessages = 10000 (default: 500) +# |-SnapshotNBins = 200 (default: 200) +# |-MonitorHitMaps = True (default: True) +# |-HPDImageMovement_UseCutBasedMethod = False +# |-HPDDisable_AlwaysDisable = False (default: False) +# |-HPDDisable_BufferSize = 1000 (default: 1000) +# |-OutputLevelNhits = 3 +# |-NHitMon_HitThreshold = 50 (default: 50) +# |-MonitorIFB = False (default: True) +# |-MonitorCalibration = False (default: True) +# |-HPDDisable_HistoryTime = 30 (default: 600) +# |-NHitMon_MovingAverageSlow = 500 (default: 500) +# |-NHitMon_ExtendedVerbose = False +# |-NHitMon_UpdateTimerInterval = 30 (default: 900) +# |-UsePhysicsEvents = True +# |-MonitorMirrorAlign = False (default: False) +# |-HitMapsMon_HighResHitMaps = False +# |-RandomTestHPDDisableRate = -1.0 +# |-MonitorPhoton = False (default: False) +# |-NHitMon_TriggerTypes = [0, 1, 3, 6, 7] (default: [0]) +# |-HPDDisable_DisableCheckHeartBeat = 3 (default: 2) +# |-RandomTestHPDErrorBurstSize = 1100 +# |-DaqMon_SendAlertMessages = True +# |-SnapshotRingType = 'Isolated' (default: 'Isolated') +# |-NHitMon_PullThreshold = 5 +# |-HPDImageMovement_DisplaySmartIDWarnings = False +# |-HPDDisable = False (default: True) +# |-RandomTestHPDErrorInterval = 5000 +# |-RawDataDBCheck = True (default: False) +# |-MissingHPDCheck = True (default: False) +# |-DaqMon_PrintMessages = True (default: False) +# |-Partition = '' (default: '') +# |-HotPixelCheck = True (default: False) +# |-HPDDisable_DisableCheckInterval = 999999 (default: 100) +# |-MonitorDarkIFB = False +# |-DaqMon_Plot2DHisto = False (default: False) +# |-OutputLevelHitmaps = 3 +# |-RichRecInitPhotons = False (default: False) +# |-MonitorRaw = False (default: True) +# |-MonitorTracks = True +# |-HPDDisable_FailureRateThreshold = 0.01 +# |-DaqMon_MonitorBXID = True (default: True) +# |-HitMapsMon_HPDCountEnabled = False (default: True) +# |-OutputLevelHPDImageMovement = 3 +# |-HitMapsMon_HotPixEnabled = False (default: True) +# |-SendEventSnapshots = True (default: True) +# |-RichRecInitPixels = False (default: True) +# |-MonitorDAQ = True (default: True) +# |-OutputLevelDisable = 3 +# |-TestPattern = '' +# |-HPDDisable_UpdateTimerInterval = 30 (default: 30) +# |-RichRecCheckProcStatus = False (default: False) +# |-DaqMon_RemoveFaultyHPD = False (default: True) +# |-NHitMon_HistoNHitMax = 10000 (default: 10000) +# |-RandomTestHPDErrorRate = -1.0 +# |-NHitMon_HistoNHitMin = 0 +# |-MonitorTracklessRing = False (default: False) +# |-NHitMon_MovingAverageFast = 20 (default: 20) +# |-OutputLevelDAQMon = 3 +# |-OutputLevelCalibration = 3 +# |-SendDaqEventSnapshots = True (default: True) +# |-RawEventLocations = [''] (default: ['']) +# |-EnableCameraRunFolder = True +# |-RawDataDecodingCheck = True (default: False) +# |-HitMapsMon_ScaleFactor = -1 +# |-OutputLevelIFB = 3 +# |-DaqMon_UpdateTimerInterval = 30 (default: 900) +# |-MonitorPixels = False (default: True) +# |-RichRecPidConfig = 'None' (default: 'None') +# |-HitMapsMon_HitsPerHPDMaps = False +# |-MonitorReconstruction = False (default: True) +# |-AssociateRingsToTracks = False +# |-RichRecTracklessRingAlgs = [''] (default: ['']) +# |-HPDDisable_2DHisto = True (default: False) +# |-HPDImageMovement_UpdateFrequency = 1000 +# |-MonitorNhits = True (default: True) +# |-HPDImageMovement_CutThreshold = 0.1 +# |-HPDImageMovement_HistoUpdateFrequency = 1000 +# |-SnapshotUpdateInterval = 99999 (default: 300) +# |-HPDImageMovement_MakeHistos = False +# |-MonitorImageMovements = False (default: True) +# |-RandomTestHPDDResetInterval = 10000 +# |-RichRecInitTracks = False (default: False) +# |-HitMapsMon_LowResHitMaps = True (default: False) +# |-Mode = 'Offline' (default: 'Offline') +# |-Context = 'Offline' +# |-RawDataSizeCheck = True (default: False) +# |-CalibMon_UpdateTimerInterval = 900 +# |-HitMapsMon_IndividualMaps = False +# |-MonitorPID = False (default: False) +# |-NHitMon_RemoveFaultyHPD = False (default: False) +# |-HPDDisable_CameraSummaryInterval = 40 (default: 300) +# |-OutputLevelCameraRunFolder = 3 +# |-OutputLevelTestPattern = 3 +# \----- (End of User RichMonitoringSysConf/RichMonitoringSysConf) ----------------------------------- +# skipping configuration of XMLSummary +# skipping configuration of RichEventSnapshotConf +# skipping configuration of RichRecSysConf +# skipping configuration of RichRecSysConf_RichPixelCreatorConfig +# applying configuration of RichHitMapMonitorConf +# /***** User RichHitMapMonitorConf/RichHitMapMonitorConf ******************************************** +# |-HitMapMon_HotPixEventInterval = 10000 +# |-OutputLevelHitmaps = 3 +# |-HitMapsMon_HighResHitMaps = False +# |-HitMapsMon_HPDCountEnabled = False (default: True) +# |-HitMapsMon_IndividualMaps = False +# |-HitMapsMon_MonFreq = 1 +# |-HitMapMonSequencer = <GaudiSequencer/RichDAQ at 0x86d6da0> +# | (default: <GaudiSequencer/HitMapMonDefaultSequencer at 0x18ea6e0>) +# |-HitMapsMon_HitsPerHPDMaps = False +# |-HitMapsMon_LowResHitMaps = True (default: False) +# |-Context = 'Offline' +# |-HitMapsMon_ScaleFactor = -1 +# |-HitMapsMon_HotPixEnabled = False (default: True) +# \----- (End of User RichHitMapMonitorConf/RichHitMapMonitorConf) ----------------------------------- +# skipping configuration of RichRecSysConf_RichPhotonCreatorConfig +# skipping configuration of RichRecSysConf_RichENNRingFinderConf +# applying configuration of CondDB +# /***** User CondDB/CondDB ************************************************************************** +# |-Upgrade = False +# |-EnableRunStampCheck = True +# |-DBSnapshotDirectory = '/group/online/hlt/conditions' +# |-LatestLocalTagsByDataType = [] (default: []) +# |-Online = False +# |-LogFile = '' +# |-SQLiteLocalCopiesDir = '' +# |-EnableRunChangeHandler = False +# |-RunChangeHandlerConditions = {'online_%d.xml': ['Conditions/Online/LHCb/Magnet/Set', 'Conditions/Online/Velo/MotionSystem', 'Conditions/Online/LHCb/Lumi/LumiSettings', 'Conditions/Online/LHCb/LHCFillingScheme', 'Conditions/Online/LHCb/RunParameters', 'Conditions/Online/Rich1/R1HltGasParameters', 'Conditions/Online/Rich2/R2HltGasParameters']} +# | (default: {'online_%d.xml': ['Conditions/Online/LHCb/Magnet/Set', 'Conditions/Online/Velo/MotionSystem', 'Conditions/Online/LHCb/Lumi/LumiSettings', 'Conditions/Online/LHCb/LHCFillingScheme', 'Conditions/Online/LHCb/RunParameters', 'Conditions/Online/Rich1/R1HltGasParameters', 'Conditions/Online/Rich2/R2HltGasParameters']}) +# |-Tags = {} (default: {}) +# |-LoadCALIBDB = 'OFFLINE' +# |-AllLocalTagsByDataType = [] (default: []) +# |-UseOracle = False +# |-RunStampCondition = '' +# |-PartitionConnectionString = {} (default: {}) +# |-LocalTags = {} (default: {}) +# |-IgnoreHeartBeat = True (default: False) +# |-Overrides = [] (default: []) +# |-Simulation = False +# |-QueryGranularity = 0 +# |-LatestGlobalTagByDataType = '' +# |-UseDBSnapshot = False +# |-DisableLFC = False +# |-HeartBeatCondition = '/Conditions/Online/LHCb/Tick' +# |-LatestGlobalTagByDataTypes = [] (default: []) +# |-UseLatestTags = [] (default: []) +# |-OverwriteSQLiteLocalCopy = False +# \----- (End of User CondDB/CondDB) ----------------------------------------------------------------- +# skipping configuration of RichRecSysConf_RichTemplateRingFinderConf +# skipping configuration of RichRecQCConf +# skipping configuration of RichRecSysConf_CKThetaResolutionConfig +# skipping configuration of RichRecSysConf_RichTrackCreatorConfig +# skipping configuration of RichRecSysConf_RichGlobalPIDConfig +# skipping configuration of RichRecSysConf_RichTrackCreatorConfig_RichSegmentCreatorConf +# skipping configuration of RichRecQCConf_RichAlignmentConf +# skipping configuration of RichOfflineRec +# skipping configuration of RichOfflineRec_RichGlobalPIDConfig +# skipping configuration of RichOfflineRec_RichENNRingFinderConf +# skipping configuration of RichOfflineRec_RichPixelCreatorConfig +# skipping configuration of RichOfflineRec_RichTemplateRingFinderConf +# skipping configuration of RichOfflineRec_CKThetaResolutionConfig +# skipping configuration of RichOfflineRec_RichTrackCreatorConfig +# skipping configuration of RichOfflineRec_RichPhotonCreatorConfig +# skipping configuration of RichOfflineRec_RichTrackCreatorConfig_RichSegmentCreatorConf +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to PanoptesDevNightly version HEAD + running on pciy on Fri Jun 3 16:43:48 2016 +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +DetectorPersistencySvc INFO Added successfully Conversion service:XmlCnvSvc +DetectorDataSvc SUCCESS Detector description database: conddb:/lhcb.xml +RndmGenSvc.Engine INFO Generator engine type:CLHEP::RanluxEngine +RndmGenSvc.Engine INFO Current Seed:1234567 Luxury:3 +RndmGenSvc INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine> +TimingAuditor.TIMER INFO This machine has a speed about 3.06 times the speed of a 2.8 GHz Xeon. +RichMoni INFO Member list: HltRoutingBitsFilter/PhysicsFilter, GaudiSequencer/RichDAQ, Rich::Mon::CameraRunFolder/CameraRunFolder, with context 'Offline' +RichDAQ INFO Member list: GaudiSequencer/DAQSeq, GaudiSequencer/NHitSeq, Rich::Mon::HitMapsMonitor/HitMapMon, with context 'Offline' +DAQSeq INFO Member list: Rich::DAQ::DataDBCheck/RichRawDataDBCheck, Rich::DAQ::DataDecodingErrorMoni/RichRawDataDecodeCheck, Rich::DAQ::RawDataSize/RichRawDataSizeCheck, Rich::Mon::MissingHPDMonitor/RichMissingHPDCheck, Rich::Mon::HPDAnalysisAlg/RichHotPixels, GaudiSequencer/DAQMonitorCentralEventSeq, with context 'Offline' +RootHistSvc INFO Writing ROOT histograms to: PanoptesOfflineHistos.root +HistogramPersistencySvc INFO Added successfully Conversion service:RootHistSvc +COOLConfSvc INFO CORAL Connection Retrial Period set to 60s +COOLConfSvc INFO CORAL Connection Retrial Time-Out set to 900s +DDDB INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/DDDB.db/DDDB" +DDDB INFO Using TAG "dddb-20150724" +LHCBCOND INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/LHCBCOND.db/LHCBCOND" +LHCBCOND INFO Using TAG "cond-20160517" +CALIBOFF INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/CALIBOFF.db/CALIBOFF" +CALIBOFF INFO Using TAG "head-2015604" +ONLINE_2016 INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/ONLINE-2016.db/ONLINE" +ONLINE_2016 INFO Using TAG "" +ToolSvc.CameraTool INFO Publish to DIM P057428/RICH_MONITORING/MESSAGES +RichHotPixels INFO Loading HPD Analysis tools : [RichHotPixelFinder] +DAQMonitorCentralEventSeq INFO Member list: Rich::Mon::DAQMonitor/DAQMonitorCentral, Rich::Mon::SingleEventSnapshot/DAQMonitorCentralEvtSnapshot, with context 'Offline' +DAQMonitorCentral INFO sent alerts at 30 seconds interval or when 10000 are reached +DAQMonitorCentral INFO alert-level for BxID warnings 3 +DAQMonitorCentral INFO check with ODIN bank 1 +DAQMonitorCentral INFO monitor BxIDs 1 +DAQMonitorCentral INFO Plot 2D histograms 0 +DAQMonitorCentral INFO TAE location ( = central) +DAQMonitorCentral INFO Print Messages 1 +DAQMonitorCentral INFO number of currently active HPDs (from ConditionDB) 447 +ToolSvc.RichUKL1Disable INFO FailureRateThreshold 0.01 +ToolSvc.RichUKL1Disable INFO Plot2DHisto 1 +ToolSvc.RichUKL1Disable INFO SendDisableCommands 0 +ToolSvc.RichUKL1Disable INFO HistoryTime 30 +ToolSvc.RichUKL1Disable INFO ClearListAtNewRun 1 +ToolSvc.RichUKL1Disable INFO BufferSize 1000 +ToolSvc.RichUKL1Disable INFO DisableCheckInterval 999999 +ToolSvc.RichUKL1Disable INFO DisableCheckHeartBeat 3 +ToolSvc.RichUKL1Disable INFO CamSummaryInterval 40 +ToolSvc.RichUKL1Disable INFO AlwaysDisable 0 +NHitSeq INFO Member list: GaudiSequencer/CombinedNHitMonitorSeq, GaudiSequencer/CentralTrigger0NHitMonitorSeq, GaudiSequencer/CentralTrigger1NHitMonitorSeq, GaudiSequencer/CentralTrigger3NHitMonitorSeq, GaudiSequencer/CentralTrigger6NHitMonitorSeq, GaudiSequencer/CentralTrigger7NHitMonitorSeq, with context 'Offline' +CombinedNHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CombinedNHitMonitor, Rich::Mon::SingleEventSnapshot/CombinedNHitMonitorEvtSnapshot, with context 'Offline' +CombinedNHitMonitor INFO Fill histograms 1 +CombinedNHitMonitor INFO Threshold for too many hits 50 +CombinedNHitMonitor INFO Send diable command to UKL1 0 +CombinedNHitMonitor INFO Moving average over 500 events +CombinedNHitMonitor INFO Using TAE events [] +CombinedNHitMonitor INFO Send alerts every 30 s +CombinedNHitMonitor INFO Add camera snapshot messages 1 +CombinedNHitMonitor INFO Monitor event with Trigger types : PhysicsTrigger BeamGasTrigger TechnicalTrigger TimingTrigger CalibrationTrigger +CombinedNHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 +CentralTrigger0NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger0NHitMonitor, with context 'Offline' +CentralTrigger0NHitMonitor INFO Fill histograms 1 +CentralTrigger0NHitMonitor INFO Threshold for too many hits 50 +CentralTrigger0NHitMonitor INFO Send diable command to UKL1 0 +CentralTrigger0NHitMonitor INFO Moving average over 500 events +CentralTrigger0NHitMonitor INFO Using TAE events [] +CentralTrigger0NHitMonitor INFO Send alerts every 30 s +CentralTrigger0NHitMonitor INFO Add camera snapshot messages 0 +CentralTrigger0NHitMonitor INFO Monitor event with Trigger types : PhysicsTrigger +CentralTrigger0NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 +CentralTrigger1NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger1NHitMonitor, with context 'Offline' +CentralTrigger1NHitMonitor INFO Fill histograms 1 +CentralTrigger1NHitMonitor INFO Threshold for too many hits 50 +CentralTrigger1NHitMonitor INFO Send diable command to UKL1 0 +CentralTrigger1NHitMonitor INFO Moving average over 500 events +CentralTrigger1NHitMonitor INFO Using TAE events [] +CentralTrigger1NHitMonitor INFO Send alerts every 30 s +CentralTrigger1NHitMonitor INFO Add camera snapshot messages 0 +CentralTrigger1NHitMonitor INFO Monitor event with Trigger types : BeamGasTrigger +CentralTrigger1NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 +CentralTrigger3NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger3NHitMonitor, with context 'Offline' +CentralTrigger3NHitMonitor INFO Fill histograms 1 +CentralTrigger3NHitMonitor INFO Threshold for too many hits 50 +CentralTrigger3NHitMonitor INFO Send diable command to UKL1 0 +CentralTrigger3NHitMonitor INFO Moving average over 500 events +CentralTrigger3NHitMonitor INFO Using TAE events [] +CentralTrigger3NHitMonitor INFO Send alerts every 30 s +CentralTrigger3NHitMonitor INFO Add camera snapshot messages 0 +CentralTrigger3NHitMonitor INFO Monitor event with Trigger types : TechnicalTrigger +CentralTrigger3NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 +CentralTrigger6NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger6NHitMonitor, with context 'Offline' +CentralTrigger6NHitMonitor INFO Fill histograms 1 +CentralTrigger6NHitMonitor INFO Threshold for too many hits 50 +CentralTrigger6NHitMonitor INFO Send diable command to UKL1 0 +CentralTrigger6NHitMonitor INFO Moving average over 500 events +CentralTrigger6NHitMonitor INFO Using TAE events [] +CentralTrigger6NHitMonitor INFO Send alerts every 30 s +CentralTrigger6NHitMonitor INFO Add camera snapshot messages 0 +CentralTrigger6NHitMonitor INFO Monitor event with Trigger types : TimingTrigger +CentralTrigger6NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 +CentralTrigger7NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger7NHitMonitor, with context 'Offline' +CentralTrigger7NHitMonitor INFO Fill histograms 1 +CentralTrigger7NHitMonitor INFO Threshold for too many hits 50 +CentralTrigger7NHitMonitor INFO Send diable command to UKL1 0 +CentralTrigger7NHitMonitor INFO Moving average over 500 events +CentralTrigger7NHitMonitor INFO Using TAE events [] +CentralTrigger7NHitMonitor INFO Send alerts every 30 s +CentralTrigger7NHitMonitor INFO Add camera snapshot messages 0 +CentralTrigger7NHitMonitor INFO Monitor event with Trigger types : CalibrationTrigger +CentralTrigger7NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 +HitMapMon INFO MonFreq 1 +HitMapMon INFO HotPixEventInterval 10000 +HitMapMon INFO HotPixelEnabled 0 +HitMapMon INFO HPDCountEnabled 0 +HitMapMon INFO HitsPerHPDMaps 0 +HitMapMon INFO LowResolutionHitMaps 1 +HitMapMon INFO HighResolutionHitMaps 0 +HitMapMon INFO IndividualHpdMaps 0 +HitMapMon INFO LowResolutionScaleFactor 2 +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160817/160817_0000000093.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_1 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160817/160817_0000000093.raw' SVC='LHCb::MDFSelector' +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr INFO Application Manager Started successfully +EventSelector.DataStreamTool_1 INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 1. Record number within stream 1: 1 +EventPersistencySvc INFO Added successfully Conversion service:LHCb::RawDataCnvSvc +ONLINE_2015 INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/ONLINE-2015.db/ONLINE" +ONLINE_2015 INFO Using TAG "" +RichMissingHPDCheck INFO First event seen +DAQMonitorCentral INFO First event seen +DAQMonitorCentral INFO =============> New Run 160817 <============= +CombinedNHitMonitor INFO First event seen +CentralTrigger0NHitMonitor INFO First event seen +CentralTrigger1NHitMonitor INFO First event seen +CentralTrigger3NHitMonitor INFO First event seen +CentralTrigger6NHitMonitor INFO First event seen +CentralTrigger7NHitMonitor INFO First event seen +ToolSvc.RichUKL1Disable INFO State : LHC '' LHCb 'NO DIM SERVICE' +ToolSvc.RichUKL1Disable INFO HPD SOFTWARE disabling now INACTIVE +EventSelector SUCCESS Reading Event record 5001. Record number within stream 1: 5001 +EventSelector SUCCESS Reading Event record 10001. Record number within stream 1: 10001 +EventSelector SUCCESS Reading Event record 15001. Record number within stream 1: 15001 +EventSelector SUCCESS Reading Event record 20001. Record number within stream 1: 20001 +EventSelector SUCCESS Reading Event record 25001. Record number within stream 1: 25001 +EventSelector SUCCESS Reading Event record 30001. Record number within stream 1: 30001 +EventSelector SUCCESS Reading Event record 35001. Record number within stream 1: 35001 +ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +LHCBCOND.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 40001. Record number within stream 1: 40001 +EventSelector SUCCESS Reading Event record 45001. Record number within stream 1: 45001 +EventSelector SUCCESS Reading Event record 50001. Record number within stream 1: 50001 +EventSelector SUCCESS Reading Event record 55001. Record number within stream 1: 55001 +EventSelector SUCCESS Reading Event record 60001. Record number within stream 1: 60001 +EventSelector SUCCESS Reading Event record 65001. Record number within stream 1: 65001 +EventSelector SUCCESS Reading Event record 70001. Record number within stream 1: 70001 +EventSelector SUCCESS Reading Event record 75001. Record number within stream 1: 75001 +EventSelector SUCCESS Reading Event record 80001. Record number within stream 1: 80001 +CALIBOFF.DataBaseOperationLock INFO Connecting to database +ONLINE_2015.DataBaseOperati... INFO Connecting to database +DDDB.DataBaseOperationLock INFO Connecting to database +LHCBCOND.DataBaseOperationLock INFO Connecting to database +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c1.up.cdf +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c2.up.cdf +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c3.up.cdf +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c4.up.cdf +MagneticFieldSvc INFO Map scaled by factor 1 with polarity internally used: 1 signed relative current: 1 +EventSelector.DataStreamTool_1 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160821/160821_0000000045.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_2 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160821/160821_0000000045.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_2 INFO Compression:0 Checksum:1 +DAQMonitorCentral INFO =============> New Run 160821 <============= +EventSelector SUCCESS Reading Event record 85001. Record number within stream 2: 1429 +EventSelector SUCCESS Reading Event record 90001. Record number within stream 2: 6429 +EventSelector.DataStreamTool_2 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160831/160831_0000000167.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_3 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160831/160831_0000000167.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_3 INFO Compression:0 Checksum:1 +DAQMonitorCentral INFO =============> New Run 160831 <============= +EventSelector SUCCESS Reading Event record 95001. Record number within stream 3: 4344 +EventSelector SUCCESS Reading Event record 100001. Record number within stream 3: 9344 +EventSelector SUCCESS Reading Event record 105001. Record number within stream 3: 14344 +EventSelector SUCCESS Reading Event record 110001. Record number within stream 3: 19344 +LHCBCOND.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 115001. Record number within stream 3: 24344 +EventSelector SUCCESS Reading Event record 120001. Record number within stream 3: 29344 +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 125001. Record number within stream 3: 34344 +EventSelector SUCCESS Reading Event record 130001. Record number within stream 3: 39344 +EventSelector SUCCESS Reading Event record 135001. Record number within stream 3: 44344 +EventSelector SUCCESS Reading Event record 140001. Record number within stream 3: 49344 +EventSelector SUCCESS Reading Event record 145001. Record number within stream 3: 54344 +EventSelector SUCCESS Reading Event record 150001. Record number within stream 3: 59344 +EventSelector SUCCESS Reading Event record 155001. Record number within stream 3: 64344 +EventSelector SUCCESS Reading Event record 160001. Record number within stream 3: 69344 +EventSelector SUCCESS Reading Event record 165001. Record number within stream 3: 74344 +EventSelector SUCCESS Reading Event record 170001. Record number within stream 3: 79344 +EventSelector.DataStreamTool_3 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160834/160834_0000000307.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_4 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160834/160834_0000000307.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_4 INFO Compression:0 Checksum:1 +CALIBOFF.DataBaseOperationLock INFO Connecting to database +ONLINE_2015.DataBaseOperati... INFO Connecting to database +DDDB.DataBaseOperationLock INFO Connecting to database +DAQMonitorCentral INFO =============> New Run 160834 <============= +EventSelector SUCCESS Reading Event record 175001. Record number within stream 4: 1671 +EventSelector SUCCESS Reading Event record 180001. Record number within stream 4: 6671 +EventSelector SUCCESS Reading Event record 185001. Record number within stream 4: 11671 +EventSelector SUCCESS Reading Event record 190001. Record number within stream 4: 16671 +EventSelector SUCCESS Reading Event record 195001. Record number within stream 4: 21671 +EventSelector SUCCESS Reading Event record 200001. Record number within stream 4: 26671 +EventSelector SUCCESS Reading Event record 205001. Record number within stream 4: 31671 +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 210001. Record number within stream 4: 36671 +EventSelector SUCCESS Reading Event record 215001. Record number within stream 4: 41671 +EventSelector SUCCESS Reading Event record 220001. Record number within stream 4: 46671 +EventSelector SUCCESS Reading Event record 225001. Record number within stream 4: 51671 +EventSelector SUCCESS Reading Event record 230001. Record number within stream 4: 56671 +EventSelector SUCCESS Reading Event record 235001. Record number within stream 4: 61671 +EventSelector SUCCESS Reading Event record 240001. Record number within stream 4: 66671 +EventSelector SUCCESS Reading Event record 245001. Record number within stream 4: 71671 +EventSelector SUCCESS Reading Event record 250001. Record number within stream 4: 76671 +EventSelector SUCCESS Reading Event record 255001. Record number within stream 4: 81671 +EventSelector.DataStreamTool_4 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160836/160836_0000000211.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_5 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160836/160836_0000000211.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_5 INFO Compression:0 Checksum:1 +CALIBOFF.DataBaseOperationLock INFO Connecting to database +ONLINE_2015.DataBaseOperati... INFO Connecting to database +DDDB.DataBaseOperationLock INFO Connecting to database +DAQMonitorCentral INFO =============> New Run 160836 <============= +EventSelector SUCCESS Reading Event record 260001. Record number within stream 5: 4726 +EventSelector SUCCESS Reading Event record 265001. Record number within stream 5: 9726 +EventSelector SUCCESS Reading Event record 270001. Record number within stream 5: 14726 +EventSelector SUCCESS Reading Event record 275001. Record number within stream 5: 19726 +EventSelector SUCCESS Reading Event record 280001. Record number within stream 5: 24726 +EventSelector SUCCESS Reading Event record 285001. Record number within stream 5: 29726 +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 290001. Record number within stream 5: 34726 +EventSelector SUCCESS Reading Event record 295001. Record number within stream 5: 39726 +EventSelector SUCCESS Reading Event record 300001. Record number within stream 5: 44726 +EventSelector SUCCESS Reading Event record 305001. Record number within stream 5: 49726 +EventSelector SUCCESS Reading Event record 310001. Record number within stream 5: 54726 +EventSelector SUCCESS Reading Event record 315001. Record number within stream 5: 59726 +EventSelector SUCCESS Reading Event record 320001. Record number within stream 5: 64726 +EventSelector SUCCESS Reading Event record 325001. Record number within stream 5: 69726 +EventSelector SUCCESS Reading Event record 330001. Record number within stream 5: 74726 +EventSelector SUCCESS Reading Event record 335001. Record number within stream 5: 79726 +EventSelector.DataStreamTool_5 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174362/174362_0000000074.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_6 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174362/174362_0000000074.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_6 INFO Compression:0 Checksum:1 +CALIBOFF.DataBaseOperationLock INFO Connecting to database +ONLINE_2015.DataBaseOperati... INFO Connecting to database +ONLINE_2016.DataBaseOperati... INFO Connecting to database +DDDB.DataBaseOperationLock INFO Connecting to database +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c1.down.cdf +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c2.down.cdf +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c3.down.cdf +MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c4.down.cdf +MagneticFieldSvc INFO Map scaled by factor 1 with polarity internally used: -1 signed relative current: -1 +DAQMonitorCentral INFO =============> New Run 174362 <============= +EventSelector SUCCESS Reading Event record 340001. Record number within stream 6: 2843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 345001. Record number within stream 6: 7843 +EventSelector SUCCESS Reading Event record 350001. Record number within stream 6: 12843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 355001. Record number within stream 6: 17843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 360001. Record number within stream 6: 22843 +EventSelector SUCCESS Reading Event record 365001. Record number within stream 6: 27843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 370001. Record number within stream 6: 32843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 375001. Record number within stream 6: 37843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 380001. Record number within stream 6: 42843 +EventSelector SUCCESS Reading Event record 385001. Record number within stream 6: 47843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 390001. Record number within stream 6: 52843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 395001. Record number within stream 6: 57843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector SUCCESS Reading Event record 400001. Record number within stream 6: 62843 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +EventSelector.DataStreamTool_6 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000124.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_7 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000124.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_7 INFO Compression:0 Checksum:1 +ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) +ToolSvc.RichUKL1Disable INFO Clearing list of 124 HPD report(s) +CALIBOFF.DataBaseOperationLock INFO Connecting to database +ONLINE_2016.DataBaseOperati... INFO Connecting to database +DDDB.DataBaseOperationLock INFO Connecting to database +DAQMonitorCentral INFO =============> New Run 174430 <============= +EventSelector SUCCESS Reading Event record 405001. Record number within stream 7: 383 +EventSelector SUCCESS Reading Event record 410001. Record number within stream 7: 5383 +EventSelector SUCCESS Reading Event record 415001. Record number within stream 7: 10383 +EventSelector SUCCESS Reading Event record 420001. Record number within stream 7: 15383 +EventSelector SUCCESS Reading Event record 425001. Record number within stream 7: 20383 +EventSelector SUCCESS Reading Event record 430001. Record number within stream 7: 25383 +EventSelector SUCCESS Reading Event record 435001. Record number within stream 7: 30383 +EventSelector SUCCESS Reading Event record 440001. Record number within stream 7: 35383 +EventSelector SUCCESS Reading Event record 445001. Record number within stream 7: 40383 +EventSelector SUCCESS Reading Event record 450001. Record number within stream 7: 45383 +EventSelector SUCCESS Reading Event record 455001. Record number within stream 7: 50383 +EventSelector SUCCESS Reading Event record 460001. Record number within stream 7: 55383 +EventSelector SUCCESS Reading Event record 465001. Record number within stream 7: 60383 +EventSelector.DataStreamTool_7 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000125.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_8 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000125.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_8 INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 470001. Record number within stream 8: 1371 +EventSelector SUCCESS Reading Event record 475001. Record number within stream 8: 6371 +EventSelector SUCCESS Reading Event record 480001. Record number within stream 8: 11371 +EventSelector SUCCESS Reading Event record 485001. Record number within stream 8: 16371 +EventSelector SUCCESS Reading Event record 490001. Record number within stream 8: 21371 +EventSelector SUCCESS Reading Event record 495001. Record number within stream 8: 26371 +EventSelector SUCCESS Reading Event record 500001. Record number within stream 8: 31371 +EventSelector SUCCESS Reading Event record 505001. Record number within stream 8: 36371 +EventSelector SUCCESS Reading Event record 510001. Record number within stream 8: 41371 +EventSelector SUCCESS Reading Event record 515001. Record number within stream 8: 46371 +EventSelector SUCCESS Reading Event record 520001. Record number within stream 8: 51371 +EventSelector SUCCESS Reading Event record 525001. Record number within stream 8: 56371 +EventSelector SUCCESS Reading Event record 530001. Record number within stream 8: 61371 +EventSelector.DataStreamTool_8 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000126.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_9 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000126.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamTool_9 INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 535001. Record number within stream 9: 2328 +EventSelector SUCCESS Reading Event record 540001. Record number within stream 9: 7328 +EventSelector SUCCESS Reading Event record 545001. Record number within stream 9: 12328 +EventSelector SUCCESS Reading Event record 550001. Record number within stream 9: 17328 +EventSelector SUCCESS Reading Event record 555001. Record number within stream 9: 22328 +EventSelector SUCCESS Reading Event record 560001. Record number within stream 9: 27328 +EventSelector SUCCESS Reading Event record 565001. Record number within stream 9: 32328 +EventSelector SUCCESS Reading Event record 570001. Record number within stream 9: 37328 +EventSelector SUCCESS Reading Event record 575001. Record number within stream 9: 42328 +EventSelector SUCCESS Reading Event record 580001. Record number within stream 9: 47328 +EventSelector SUCCESS Reading Event record 585001. Record number within stream 9: 52328 +EventSelector SUCCESS Reading Event record 590001. Record number within stream 9: 57328 +EventSelector SUCCESS Reading Event record 595001. Record number within stream 9: 62328 +EventSelector.DataStreamTool_9 INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000129.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_10 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000129.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 600001. Record number within stream 10: 3071 +EventSelector SUCCESS Reading Event record 605001. Record number within stream 10: 8071 +EventSelector SUCCESS Reading Event record 610001. Record number within stream 10: 13071 +EventSelector SUCCESS Reading Event record 615001. Record number within stream 10: 18071 +EventSelector SUCCESS Reading Event record 620001. Record number within stream 10: 23071 +EventSelector SUCCESS Reading Event record 625001. Record number within stream 10: 28071 +EventSelector SUCCESS Reading Event record 630001. Record number within stream 10: 33071 +EventSelector SUCCESS Reading Event record 635001. Record number within stream 10: 38071 +EventSelector SUCCESS Reading Event record 640001. Record number within stream 10: 43071 +EventSelector SUCCESS Reading Event record 645001. Record number within stream 10: 48071 +EventSelector SUCCESS Reading Event record 650001. Record number within stream 10: 53071 +EventSelector SUCCESS Reading Event record 655001. Record number within stream 10: 58071 +EventSelector SUCCESS Reading Event record 660001. Record number within stream 10: 63071 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000137.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_11 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000137.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 665001. Record number within stream 11: 4037 +EventSelector SUCCESS Reading Event record 670001. Record number within stream 11: 9037 +EventSelector SUCCESS Reading Event record 675001. Record number within stream 11: 14037 +EventSelector SUCCESS Reading Event record 680001. Record number within stream 11: 19037 +EventSelector SUCCESS Reading Event record 685001. Record number within stream 11: 24037 +ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 690001. Record number within stream 11: 29037 +EventSelector SUCCESS Reading Event record 695001. Record number within stream 11: 34037 +EventSelector SUCCESS Reading Event record 700001. Record number within stream 11: 39037 +EventSelector SUCCESS Reading Event record 705001. Record number within stream 11: 44037 +EventSelector SUCCESS Reading Event record 710001. Record number within stream 11: 49037 +EventSelector SUCCESS Reading Event record 715001. Record number within stream 11: 54037 +EventSelector SUCCESS Reading Event record 720001. Record number within stream 11: 59037 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000132.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_12 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000132.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +CALIBOFF.DataBaseOperationLock INFO Connecting to database +ONLINE_2016.DataBaseOperati... INFO Connecting to database +DDDB.DataBaseOperationLock INFO Connecting to database +LHCBCOND.DataBaseOperationLock INFO Connecting to database +DAQMonitorCentral INFO =============> New Run 174824 <============= +EventSelector SUCCESS Reading Event record 725001. Record number within stream 12: 9 +EventSelector SUCCESS Reading Event record 730001. Record number within stream 12: 5009 +EventSelector SUCCESS Reading Event record 735001. Record number within stream 12: 10009 +EventSelector SUCCESS Reading Event record 740001. Record number within stream 12: 15009 +EventSelector SUCCESS Reading Event record 745001. Record number within stream 12: 20009 +EventSelector SUCCESS Reading Event record 750001. Record number within stream 12: 25009 +LHCBCOND.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 755001. Record number within stream 12: 30009 +EventSelector SUCCESS Reading Event record 760001. Record number within stream 12: 35009 +EventSelector SUCCESS Reading Event record 765001. Record number within stream 12: 40009 +EventSelector SUCCESS Reading Event record 770001. Record number within stream 12: 45009 +CombinedNHitMonitor INFO Seen 3 'unusual' events in past 30 secs ( 0.1 Evt/s ) +EventSelector SUCCESS Reading Event record 775001. Record number within stream 12: 50009 +EventSelector SUCCESS Reading Event record 780001. Record number within stream 12: 55009 +EventSelector SUCCESS Reading Event record 785001. Record number within stream 12: 60009 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000138.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_13 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000138.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 790001. Record number within stream 13: 3548 +EventSelector SUCCESS Reading Event record 795001. Record number within stream 13: 8548 +EventSelector SUCCESS Reading Event record 800001. Record number within stream 13: 13548 +EventSelector SUCCESS Reading Event record 805001. Record number within stream 13: 18548 +EventSelector SUCCESS Reading Event record 810001. Record number within stream 13: 23548 +EventSelector SUCCESS Reading Event record 815001. Record number within stream 13: 28548 +EventSelector SUCCESS Reading Event record 820001. Record number within stream 13: 33548 +EventSelector SUCCESS Reading Event record 825001. Record number within stream 13: 38548 +EventSelector SUCCESS Reading Event record 830001. Record number within stream 13: 43548 +EventSelector SUCCESS Reading Event record 835001. Record number within stream 13: 48548 +EventSelector SUCCESS Reading Event record 840001. Record number within stream 13: 53548 +EventSelector SUCCESS Reading Event record 845001. Record number within stream 13: 58548 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000143.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_14 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000143.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 850001. Record number within stream 14: 1789 +EventSelector SUCCESS Reading Event record 855001. Record number within stream 14: 6789 +EventSelector SUCCESS Reading Event record 860001. Record number within stream 14: 11789 +EventSelector SUCCESS Reading Event record 865001. Record number within stream 14: 16789 +EventSelector SUCCESS Reading Event record 870001. Record number within stream 14: 21789 +ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) +EventSelector SUCCESS Reading Event record 875001. Record number within stream 14: 26789 +EventSelector SUCCESS Reading Event record 880001. Record number within stream 14: 31789 +EventSelector SUCCESS Reading Event record 885001. Record number within stream 14: 36789 +EventSelector SUCCESS Reading Event record 890001. Record number within stream 14: 41789 +EventSelector SUCCESS Reading Event record 895001. Record number within stream 14: 46789 +EventSelector SUCCESS Reading Event record 900001. Record number within stream 14: 51789 +EventSelector SUCCESS Reading Event record 905001. Record number within stream 14: 56789 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000144.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_15 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000144.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 910001. Record number within stream 15: 170 +EventSelector SUCCESS Reading Event record 915001. Record number within stream 15: 5170 +EventSelector SUCCESS Reading Event record 920001. Record number within stream 15: 10170 +EventSelector SUCCESS Reading Event record 925001. Record number within stream 15: 15170 +EventSelector SUCCESS Reading Event record 930001. Record number within stream 15: 20170 +EventSelector SUCCESS Reading Event record 935001. Record number within stream 15: 25170 +EventSelector SUCCESS Reading Event record 940001. Record number within stream 15: 30170 +EventSelector SUCCESS Reading Event record 945001. Record number within stream 15: 35170 +EventSelector SUCCESS Reading Event record 950001. Record number within stream 15: 40170 +EventSelector SUCCESS Reading Event record 955001. Record number within stream 15: 45170 +EventSelector SUCCESS Reading Event record 960001. Record number within stream 15: 50170 +EventSelector SUCCESS Reading Event record 965001. Record number within stream 15: 55170 +EventSelector SUCCESS Reading Event record 970001. Record number within stream 15: 60170 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000145.raw by its physical name. +IODataManager ERROR You may not be able to navigate back to the input file -- processing continues +EventSelector INFO Stream:EventSelector.DataStreamTool_16 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000145.raw' SVC='LHCb::MDFSelector' +EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 +EventSelector SUCCESS Reading Event record 975001. Record number within stream 16: 3222 +EventSelector SUCCESS Reading Event record 980001. Record number within stream 16: 8222 +EventSelector SUCCESS Reading Event record 985001. Record number within stream 16: 13222 +EventSelector SUCCESS Reading Event record 990001. Record number within stream 16: 18222 +EventSelector SUCCESS Reading Event record 995001. Record number within stream 16: 23222 +EventSelector SUCCESS Reading Event record 1000001. Record number within stream 16: 28222 +EventSelector SUCCESS Reading Event record 1005001. Record number within stream 16: 33222 +EventSelector SUCCESS Reading Event record 1010001. Record number within stream 16: 38222 +EventSelector SUCCESS Reading Event record 1015001. Record number within stream 16: 43222 +EventSelector SUCCESS Reading Event record 1020001. Record number within stream 16: 48222 +EventSelector SUCCESS Reading Event record 1025001. Record number within stream 16: 53222 +EventSelector SUCCESS Reading Event record 1030001. Record number within stream 16: 58222 +EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. +EventLoopMgr INFO No more events in event selection +ApplicationMgr INFO Application Manager Stopped successfully +PhysicsFilter SUCCESS Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + |*"#accept" | 1033663 | 2.49e+05 |( 24.0890 +- 0.0420603)%| ------- | ------- | +RichRawDataDecodeCheck SUCCESS Booked 26 Histogram(s) : 2D=1 1DProf=25 +RichRawDataSizeCheck SUCCESS Booked 28 Histogram(s) : 1D=24 1DProf=4 +DAQMonitorCentral SUCCESS Booked 5 Histogram(s) : 1D=5 +DAQMonitorCentral SUCCESS Number of counters : 12 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "AlertActiveHPDs" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertBxID" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertEmptyEvent" | 180362 | 180362 | 1.0000 | 0.0000 | 1.0000 | 1.0000 | + | "AlertEmptyHPD" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertEventID" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertExtendedHeader" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertHPDInhibit" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertHPDNotInhibitInvalidSmartRef" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertHPDSuppressed" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertInvalidOdinTime" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertL0ID" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | + | "AlertParityFooter" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | +CombinedNHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 +CombinedNHitMonitorEvtSnapshotSUCCESS Booked 74 Histogram(s) : 2D=74 +CentralTrigger0NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 +CentralTrigger1NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 +CentralTrigger3NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 +CentralTrigger6NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 +CentralTrigger7NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 +HitMapMon SUCCESS Booked 8 Histogram(s) : 2D=8 +EventLoopMgr INFO Histograms converted successfully according to request. +ToolSvc INFO Removing all tools created by ToolSvc +ToolSvc.RichUKL1Disable SUCCESS Booked 4 Histogram(s) : 2D=4 +ToolSvc.RichSmartIDDecoder.... INFO ======================================================================================================================== +ToolSvc.RichSmartIDDecoder.... INFO RICH Level 1 : Decoding Summary : 1033663 events +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 1/ 8 V129 | L1 size = 17.03 +- 0.00 pds : 81.54 +- 0.01 words : 131.46 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 2/12 V129 | L1 size = 16.26 +- 0.00 pds : 85.34 +- 0.01 words : 148.88 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 3/ 1 V129 | L1 size = 6.80 +- 0.00 pds : 74.86 +- 0.01 words : 227.47 +- 0.02 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 4/ 6 V129 | L1 size = 15.60 +- 0.00 pds : 78.79 +- 0.01 words : 128.69 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 5/ 7 V129 | L1 size = 17.69 +- 0.00 pds : 77.44 +- 0.01 words : 118.96 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 6/ 3 V129 | L1 size = 13.64 +- 0.00 pds : 77.81 +- 0.01 words : 140.38 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 7/11 V129 | L1 size = 15.50 +- 0.00 pds : 81.98 +- 0.01 words : 141.69 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 8/ 2 V129 | L1 size = 14.67 +- 0.00 pds : 83.72 +- 0.01 words : 151.42 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 9/ 1 V129 | L1 size = 16.18 +- 0.00 pds : 75.30 +- 0.01 words : 122.89 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 10/13 V129 | L1 size = 16.46 +- 0.00 pds : 83.95 +- 0.01 words : 143.61 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 11/ 4 V129 | L1 size = 14.29 +- 0.00 pds : 73.66 +- 0.01 words : 123.75 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 12/ 5 V129 | L1 size = 16.24 +- 0.00 pds : 79.16 +- 0.01 words : 129.41 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 13/ 2 V129 | L1 size = 9.73 +- 0.00 pds : 65.94 +- 0.01 words : 142.41 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 14/ 3 V129 | L1 size = 12.51 +- 0.00 pds : 86.53 +- 0.01 words : 176.48 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 15/10 V129 | L1 size = 9.14 +- 0.00 pds : 76.20 +- 0.01 words : 208.81 +- 0.02 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 16/ 4 V129 | L1 size = 10.67 +- 0.00 pds : 78.17 +- 0.01 words : 161.68 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 17/ 5 V129 | L1 size = 11.30 +- 0.00 pds : 75.74 +- 0.01 words : 165.67 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 18/ 6 V129 | L1 size = 10.00 +- 0.00 pds : 75.19 +- 0.01 words : 171.38 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 19/ 9 V129 | L1 size = 12.52 +- 0.00 pds : 83.62 +- 0.01 words : 167.44 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 20/ 7 V129 | L1 size = 12.64 +- 0.00 pds : 62.53 +- 0.01 words : 105.93 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 22/ 9 V129 | L1 size = 15.80 +- 0.00 pds : 79.55 +- 0.01 words : 132.32 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 23/ 8 V129 | L1 size = 12.57 +- 0.00 pds : 72.88 +- 0.01 words : 133.11 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 24/10 V129 | L1 size = 15.78 +- 0.00 pds : 82.87 +- 0.01 words : 142.28 +- 0.01 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 27/11 V129 | L1 size = 6.46 +- 0.00 pds : 77.18 +- 0.01 words : 205.51 +- 0.02 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ +ToolSvc.RichSmartIDDecoder.... INFO Rich1 Average | L1 size = 114.34 +- 0.01 pds : 828.86 +- 0.03 words : 1865.90 +- 0.05 hits / event +ToolSvc.RichSmartIDDecoder.... INFO Rich2 Average | L1 size = 205.14 +- 0.02 pds : 1041.11 +- 0.03 words : 1755.74 +- 0.05 hits / event +ToolSvc.RichSmartIDDecoder.... INFO ======================================================================================================================== +TimingAuditor.TIMER INFO -------------------------------------------------------------------------------------------------- +TimingAuditor.TIMER INFO This machine has a speed about 3.06 times the speed of a 2.8 GHz Xeon. +TimingAuditor.TIMER INFO Algorithm (millisec) | <user> | <clock> | min max sigma | entries | total (s) | +TimingAuditor.TIMER INFO -------------------------------------------------------------------------------------------------- +TimingAuditor.TIMER INFO EVENT LOOP | 2.738 | 2.837 | 0.277 9703.6 10.59 | 1033663 | 2933.505 | +TimingAuditor.TIMER INFO RichMoni | 1.932 | 1.990 | 0.252 9703.5 9.62 | 1033663 | 2057.240 | +TimingAuditor.TIMER INFO PhysicsFilter | 0.002 | 0.003 | 0.002 4.5 0.01 | 1033663 | 3.827 | +TimingAuditor.TIMER INFO RichDAQ | 1.921 | 1.976 | 0.240 9703.5 9.62 | 1033663 | 2043.519 | +TimingAuditor.TIMER INFO DAQSeq | 0.875 | 0.946 | 0.187 65.3 0.49 | 1033663 | 978.068 | +TimingAuditor.TIMER INFO RichRawDataDBCheck | 0.319 | 0.382 | 0.005 10.7 0.25 | 1033663 | 395.244 | +TimingAuditor.TIMER INFO RichRawDataDecodeCheck | 0.140 | 0.145 | 0.002 13.2 0.08 | 1033663 | 150.381 | +TimingAuditor.TIMER INFO RichRawDataSizeCheck | 0.278 | 0.283 | 0.153 8.5 0.07 | 1033663 | 292.570 | +TimingAuditor.TIMER INFO RichMissingHPDCheck | 0.023 | 0.024 | 0.002 62.4 0.07 | 1033663 | 25.055 | +TimingAuditor.TIMER INFO RichHotPixels | 0.021 | 0.021 | 0.000 8.6 0.18 | 1033663 | 21.904 | +TimingAuditor.TIMER INFO DAQMonitorCentralEventSeq | 0.073 | 0.074 | 0.005 7.7 0.06 | 1033663 | 76.805 | +TimingAuditor.TIMER INFO DAQMonitorCentral | 0.068 | 0.069 | 0.001 7.7 0.06 | 1033663 | 72.097 | +TimingAuditor.TIMER INFO DAQMonitorCentralEvtSnaps| 0.000 | 0.000 | 0.000 0.0 0.00 | 0 | 0.000 | +TimingAuditor.TIMER INFO NHitSeq | 0.726 | 0.710 | 0.044 9700.1 9.55 | 1033663 | 734.207 | +TimingAuditor.TIMER INFO CombinedNHitMonitorSeq | 0.459 | 0.457 | 0.006 9699.5 9.55 | 1033663 | 473.120 | +TimingAuditor.TIMER INFO CombinedNHitMonitor | 0.452 | 0.443 | 0.002 87.5 0.37 | 1033663 | 458.062 | +TimingAuditor.TIMER INFO CombinedNHitMonitorEvtSna| 22.295 | 118.643 | 0.003 9654.3 1034.26 | 87 | 10.322 | +TimingAuditor.TIMER INFO CentralTrigger0NHitMonitor| 0.226 | 0.214 | 0.005 13.0 0.14 | 1033663 | 221.209 | +TimingAuditor.TIMER INFO CentralTrigger0NHitMonito| 0.220 | 0.209 | 0.001 13.0 0.14 | 1033663 | 216.522 | +TimingAuditor.TIMER INFO CentralTrigger1NHitMonitor| 0.007 | 0.007 | 0.005 5.9 0.01 | 1033663 | 7.423 | +TimingAuditor.TIMER INFO CentralTrigger1NHitMonito| 0.002 | 0.003 | 0.001 5.8 0.01 | 1033663 | 3.347 | +TimingAuditor.TIMER INFO CentralTrigger3NHitMonitor| 0.005 | 0.006 | 0.005 2.4 0.01 | 1033663 | 6.377 | +TimingAuditor.TIMER INFO CentralTrigger3NHitMonito| 0.001 | 0.002 | 0.001 1.3 0.00 | 1033663 | 2.360 | +TimingAuditor.TIMER INFO CentralTrigger6NHitMonitor| 0.005 | 0.006 | 0.005 4.1 0.01 | 1033663 | 6.302 | +TimingAuditor.TIMER INFO CentralTrigger6NHitMonito| 0.001 | 0.002 | 0.001 1.7 0.00 | 1033663 | 2.336 | +TimingAuditor.TIMER INFO CentralTrigger7NHitMonitor| 0.005 | 0.006 | 0.005 4.6 0.01 | 1033663 | 6.311 | +TimingAuditor.TIMER INFO CentralTrigger7NHitMonito| 0.001 | 0.002 | 0.001 4.0 0.00 | 1033663 | 2.280 | +TimingAuditor.TIMER INFO HitMapMon | 0.311 | 0.312 | 0.001 12.9 0.29 | 1033663 | 322.953 | +TimingAuditor.TIMER INFO CameraRunFolder | 0.000 | 0.001 | 0.000 3.2 0.00 | 1033663 | 1.258 | +TimingAuditor.TIMER INFO -------------------------------------------------------------------------------------------------- +ApplicationMgr INFO Application Manager Finalized successfully +ApplicationMgr INFO Application Manager Terminated successfully -- GitLab From 63b695bf3db5879295b149fbc2332632475a6acc Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 14 Jun 2016 11:41:53 +0100 Subject: [PATCH 06/37] remove log file --- Rich/Panoptes/options/daq-before.log | 874 --------------------------- 1 file changed, 874 deletions(-) delete mode 100644 Rich/Panoptes/options/daq-before.log diff --git a/Rich/Panoptes/options/daq-before.log b/Rich/Panoptes/options/daq-before.log deleted file mode 100644 index 37a69e5d3..000000000 --- a/Rich/Panoptes/options/daq-before.log +++ /dev/null @@ -1,874 +0,0 @@ -# setting LC_ALL to "C" -# Restarting with LD_PRELOAD='libtcmalloc.so' -# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon_Offline.py' -# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon-Common.py' -CondDBTag = cond-20160517 DDDBTag = dddb-20150724 -# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon-Common.py' -# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/RichDAQMon_Offline.py' -# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/OfflineDataFiles.py' -# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/PanoptesDevNightly/Rich/Panoptes/options/OfflineDataFiles.py' -# applying configuration of RichPixelCreatorConfig -# /***** User RichPixelCreatorConfig/RichPixelCreatorConfig ****************************************** -# |-UseClustersAsPixels = [False, False] (default: [False, False]) -# |-PixelCleaning = 'None' (default: 'HotHPDs') -# |-OutputLevel = 3 -# |-MaxHPDOccupancy = [200, 200] (default: [200, 200]) -# |-DataType = '' -# |-FindClusters = True -# |-Detectors = [True, True] (default: [True, True]) -# |-MaxPixels = 30000 -# |-HPDOccScaleFactor = [9999, 9999] (default: [9999, 9999]) -# |-Context = 'Offline' -# |-MaxHotPixelClusterSize = [10, 8] (default: [10, 8]) -# |-SpecialData = [] (default: []) -# |-BookKeeping = False -# \----- (End of User RichPixelCreatorConfig/RichPixelCreatorConfig) --------------------------------- -# applying configuration of Panoptes -# --> Including file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/LHCbDevNightly/GaudiConf/options/RawDataIO.opts' -# EventPersistencySvc.CnvServices += { "LHCb::RawDataCnvSvc" }; -# <-- End of file '/var/clus/usera/jonesc/LHCbCMake/lhcb-head/LHCbDevNightly/GaudiConf/options/RawDataIO.opts' -['pciy.hep.phy.cam.ac.uk:45123'] -# /***** User Panoptes/Panoptes ********************************************************************** -# |-MonitorReconstructedEvents = False -# |-UseOnlineCondDBtag = False (default: False) -# |-SaverCycle = 6000000 (default: 900) -# |-SkipEvents = 0 -# |-WriteOutSelectedEvents = False -# |-UsePrivateTracking = False (default: False) -# |-MonName = 'RichDAQMon' (default: 'RichDAQMon') -# |-SuppressDecodingWarningsErrors = False -# |-DDDBtag = 'dddb-20150724' (default: '') -# |-MonitorRawEvents = True -# |-VeloOpen = False -# |-SaveHistograms = 1 -# |-UseOracle = False -# |-MessageSvcOutputLevel = 3 -# |-UseConditionsMap = False (default: False) -# |-Partition = '' (default: None) -# |-EvtMax = -1 (default: -1) -# |-TriggerMask = [48, 55, 57, 96] (default: [48, 55, 57, 96]) -# |-MonitorExpressEvents = False -# |-IgnoreEventIDMisMatches = False -# |-FieldOff = False -# |-Mode = 'Offline' (default: 'Offline') -# |-Simulation = False -# |-SelectedEventsDataFile = 'SelectedEvents.raw' -# |-UseIncidentSvc = True -# |-DisableUpdateAndReset = False -# |-DataType = '2016' (default: '2016') -# |-ResetHistogramsAfterSave = 1 -# |-CondDBtag = 'cond-20160517' (default: '') -# |-RawEventLocations = [''] (default: ['']) -# |-VetoMask = [100, 104, 105, 106] (default: [100, 104, 105, 106]) -# |-UseMonitorSvc = False -# |-msgSvc = ServiceHandle('MessageSvc') (default: None) -# \----- (End of User Panoptes/Panoptes) ------------------------------------------------------------- -# applying configuration of LHCbApp -# /***** User LHCbApp/LHCbApp ************************************************************************ -# |-Persistency = None -# |-OutputLevel = 3 -# |-DataType = '2016' (default: '2012') -# |-TimeStamp = False -# |-SkipEvents = 0 -# |-EvtMax = -1 (default: -1) -# |-CondDBtag = 'cond-20160517' (default: '') -# |-DQFLAGStag = '' -# |-IgnoreDQFlags = True -# |-Monitors = [] (default: []) -# |-Detectors = [] (default: []) -# |-LocalDataTypes = [] (default: []) -# |-XMLSummary = None -# |-Simulation = False -# |-DDDBtag = 'dddb-20150724' (default: '') -# |-OnlineMode = False -# \----- (End of User LHCbApp/LHCbApp) --------------------------------------------------------------- -# applying configuration of DDDBConf -# WARNING: Using default tag dq-20150717 for partition DQFLAGS -# WARNING: Using default tag head-2015604 for partition CALIBOFF -# /***** User DDDBConf/DDDBConf ********************************************************************** -# |-DataType = '2016' (default: '2012') -# |-InitialTime = 'Safe' -# |-Simulation = False -# |-AutoTags = False -# |-DbRoot = 'conddb:/lhcb.xml' -# |-OnlineMode = False -# \----- (End of User DDDBConf/DDDBConf) ------------------------------------------------------------- -# applying configuration of Camera -# /***** User Camera/Camera ************************************************************************** -# |-CameraServers = ['pciy.hep.phy.cam.ac.uk:45123'] (default: []) -# \----- (End of User Camera/Camera) ----------------------------------------------------------------- -# applying configuration of RichMonitoringSysConf -# /***** User RichMonitoringSysConf/RichMonitoringSysConf ******************************************** -# |-DaqMon_SendAlertDirect = False -# |-NHitMon_IndividualTriggerMonitors = True (default: True) -# |-SendNHitEventSnapshots = True (default: True) -# |-NHitMon_FillHistograms = True -# |-DaqMon_MaxErrorMessages = 10000 (default: 500) -# |-SnapshotNBins = 200 (default: 200) -# |-MonitorHitMaps = True (default: True) -# |-HPDImageMovement_UseCutBasedMethod = False -# |-HPDDisable_AlwaysDisable = False (default: False) -# |-HPDDisable_BufferSize = 1000 (default: 1000) -# |-OutputLevelNhits = 3 -# |-NHitMon_HitThreshold = 50 (default: 50) -# |-MonitorIFB = False (default: True) -# |-MonitorCalibration = False (default: True) -# |-HPDDisable_HistoryTime = 30 (default: 600) -# |-NHitMon_MovingAverageSlow = 500 (default: 500) -# |-NHitMon_ExtendedVerbose = False -# |-NHitMon_UpdateTimerInterval = 30 (default: 900) -# |-UsePhysicsEvents = True -# |-MonitorMirrorAlign = False (default: False) -# |-HitMapsMon_HighResHitMaps = False -# |-RandomTestHPDDisableRate = -1.0 -# |-MonitorPhoton = False (default: False) -# |-NHitMon_TriggerTypes = [0, 1, 3, 6, 7] (default: [0]) -# |-HPDDisable_DisableCheckHeartBeat = 3 (default: 2) -# |-RandomTestHPDErrorBurstSize = 1100 -# |-DaqMon_SendAlertMessages = True -# |-SnapshotRingType = 'Isolated' (default: 'Isolated') -# |-NHitMon_PullThreshold = 5 -# |-HPDImageMovement_DisplaySmartIDWarnings = False -# |-HPDDisable = False (default: True) -# |-RandomTestHPDErrorInterval = 5000 -# |-RawDataDBCheck = True (default: False) -# |-MissingHPDCheck = True (default: False) -# |-DaqMon_PrintMessages = True (default: False) -# |-Partition = '' (default: '') -# |-HotPixelCheck = True (default: False) -# |-HPDDisable_DisableCheckInterval = 999999 (default: 100) -# |-MonitorDarkIFB = False -# |-DaqMon_Plot2DHisto = False (default: False) -# |-OutputLevelHitmaps = 3 -# |-RichRecInitPhotons = False (default: False) -# |-MonitorRaw = False (default: True) -# |-MonitorTracks = True -# |-HPDDisable_FailureRateThreshold = 0.01 -# |-DaqMon_MonitorBXID = True (default: True) -# |-HitMapsMon_HPDCountEnabled = False (default: True) -# |-OutputLevelHPDImageMovement = 3 -# |-HitMapsMon_HotPixEnabled = False (default: True) -# |-SendEventSnapshots = True (default: True) -# |-RichRecInitPixels = False (default: True) -# |-MonitorDAQ = True (default: True) -# |-OutputLevelDisable = 3 -# |-TestPattern = '' -# |-HPDDisable_UpdateTimerInterval = 30 (default: 30) -# |-RichRecCheckProcStatus = False (default: False) -# |-DaqMon_RemoveFaultyHPD = False (default: True) -# |-NHitMon_HistoNHitMax = 10000 (default: 10000) -# |-RandomTestHPDErrorRate = -1.0 -# |-NHitMon_HistoNHitMin = 0 -# |-MonitorTracklessRing = False (default: False) -# |-NHitMon_MovingAverageFast = 20 (default: 20) -# |-OutputLevelDAQMon = 3 -# |-OutputLevelCalibration = 3 -# |-SendDaqEventSnapshots = True (default: True) -# |-RawEventLocations = [''] (default: ['']) -# |-EnableCameraRunFolder = True -# |-RawDataDecodingCheck = True (default: False) -# |-HitMapsMon_ScaleFactor = -1 -# |-OutputLevelIFB = 3 -# |-DaqMon_UpdateTimerInterval = 30 (default: 900) -# |-MonitorPixels = False (default: True) -# |-RichRecPidConfig = 'None' (default: 'None') -# |-HitMapsMon_HitsPerHPDMaps = False -# |-MonitorReconstruction = False (default: True) -# |-AssociateRingsToTracks = False -# |-RichRecTracklessRingAlgs = [''] (default: ['']) -# |-HPDDisable_2DHisto = True (default: False) -# |-HPDImageMovement_UpdateFrequency = 1000 -# |-MonitorNhits = True (default: True) -# |-HPDImageMovement_CutThreshold = 0.1 -# |-HPDImageMovement_HistoUpdateFrequency = 1000 -# |-SnapshotUpdateInterval = 99999 (default: 300) -# |-HPDImageMovement_MakeHistos = False -# |-MonitorImageMovements = False (default: True) -# |-RandomTestHPDDResetInterval = 10000 -# |-RichRecInitTracks = False (default: False) -# |-HitMapsMon_LowResHitMaps = True (default: False) -# |-Mode = 'Offline' (default: 'Offline') -# |-Context = 'Offline' -# |-RawDataSizeCheck = True (default: False) -# |-CalibMon_UpdateTimerInterval = 900 -# |-HitMapsMon_IndividualMaps = False -# |-MonitorPID = False (default: False) -# |-NHitMon_RemoveFaultyHPD = False (default: False) -# |-HPDDisable_CameraSummaryInterval = 40 (default: 300) -# |-OutputLevelCameraRunFolder = 3 -# |-OutputLevelTestPattern = 3 -# \----- (End of User RichMonitoringSysConf/RichMonitoringSysConf) ----------------------------------- -# skipping configuration of XMLSummary -# skipping configuration of RichEventSnapshotConf -# skipping configuration of RichRecSysConf -# skipping configuration of RichRecSysConf_RichPixelCreatorConfig -# applying configuration of RichHitMapMonitorConf -# /***** User RichHitMapMonitorConf/RichHitMapMonitorConf ******************************************** -# |-HitMapMon_HotPixEventInterval = 10000 -# |-OutputLevelHitmaps = 3 -# |-HitMapsMon_HighResHitMaps = False -# |-HitMapsMon_HPDCountEnabled = False (default: True) -# |-HitMapsMon_IndividualMaps = False -# |-HitMapsMon_MonFreq = 1 -# |-HitMapMonSequencer = <GaudiSequencer/RichDAQ at 0x86d6da0> -# | (default: <GaudiSequencer/HitMapMonDefaultSequencer at 0x18ea6e0>) -# |-HitMapsMon_HitsPerHPDMaps = False -# |-HitMapsMon_LowResHitMaps = True (default: False) -# |-Context = 'Offline' -# |-HitMapsMon_ScaleFactor = -1 -# |-HitMapsMon_HotPixEnabled = False (default: True) -# \----- (End of User RichHitMapMonitorConf/RichHitMapMonitorConf) ----------------------------------- -# skipping configuration of RichRecSysConf_RichPhotonCreatorConfig -# skipping configuration of RichRecSysConf_RichENNRingFinderConf -# applying configuration of CondDB -# /***** User CondDB/CondDB ************************************************************************** -# |-Upgrade = False -# |-EnableRunStampCheck = True -# |-DBSnapshotDirectory = '/group/online/hlt/conditions' -# |-LatestLocalTagsByDataType = [] (default: []) -# |-Online = False -# |-LogFile = '' -# |-SQLiteLocalCopiesDir = '' -# |-EnableRunChangeHandler = False -# |-RunChangeHandlerConditions = {'online_%d.xml': ['Conditions/Online/LHCb/Magnet/Set', 'Conditions/Online/Velo/MotionSystem', 'Conditions/Online/LHCb/Lumi/LumiSettings', 'Conditions/Online/LHCb/LHCFillingScheme', 'Conditions/Online/LHCb/RunParameters', 'Conditions/Online/Rich1/R1HltGasParameters', 'Conditions/Online/Rich2/R2HltGasParameters']} -# | (default: {'online_%d.xml': ['Conditions/Online/LHCb/Magnet/Set', 'Conditions/Online/Velo/MotionSystem', 'Conditions/Online/LHCb/Lumi/LumiSettings', 'Conditions/Online/LHCb/LHCFillingScheme', 'Conditions/Online/LHCb/RunParameters', 'Conditions/Online/Rich1/R1HltGasParameters', 'Conditions/Online/Rich2/R2HltGasParameters']}) -# |-Tags = {} (default: {}) -# |-LoadCALIBDB = 'OFFLINE' -# |-AllLocalTagsByDataType = [] (default: []) -# |-UseOracle = False -# |-RunStampCondition = '' -# |-PartitionConnectionString = {} (default: {}) -# |-LocalTags = {} (default: {}) -# |-IgnoreHeartBeat = True (default: False) -# |-Overrides = [] (default: []) -# |-Simulation = False -# |-QueryGranularity = 0 -# |-LatestGlobalTagByDataType = '' -# |-UseDBSnapshot = False -# |-DisableLFC = False -# |-HeartBeatCondition = '/Conditions/Online/LHCb/Tick' -# |-LatestGlobalTagByDataTypes = [] (default: []) -# |-UseLatestTags = [] (default: []) -# |-OverwriteSQLiteLocalCopy = False -# \----- (End of User CondDB/CondDB) ----------------------------------------------------------------- -# skipping configuration of RichRecSysConf_RichTemplateRingFinderConf -# skipping configuration of RichRecQCConf -# skipping configuration of RichRecSysConf_CKThetaResolutionConfig -# skipping configuration of RichRecSysConf_RichTrackCreatorConfig -# skipping configuration of RichRecSysConf_RichGlobalPIDConfig -# skipping configuration of RichRecSysConf_RichTrackCreatorConfig_RichSegmentCreatorConf -# skipping configuration of RichRecQCConf_RichAlignmentConf -# skipping configuration of RichOfflineRec -# skipping configuration of RichOfflineRec_RichGlobalPIDConfig -# skipping configuration of RichOfflineRec_RichENNRingFinderConf -# skipping configuration of RichOfflineRec_RichPixelCreatorConfig -# skipping configuration of RichOfflineRec_RichTemplateRingFinderConf -# skipping configuration of RichOfflineRec_CKThetaResolutionConfig -# skipping configuration of RichOfflineRec_RichTrackCreatorConfig -# skipping configuration of RichOfflineRec_RichPhotonCreatorConfig -# skipping configuration of RichOfflineRec_RichTrackCreatorConfig_RichSegmentCreatorConf -ApplicationMgr SUCCESS -==================================================================================================================================== - Welcome to PanoptesDevNightly version HEAD - running on pciy on Fri Jun 3 16:43:48 2016 -==================================================================================================================================== -ApplicationMgr INFO Application Manager Configured successfully -DetectorPersistencySvc INFO Added successfully Conversion service:XmlCnvSvc -DetectorDataSvc SUCCESS Detector description database: conddb:/lhcb.xml -RndmGenSvc.Engine INFO Generator engine type:CLHEP::RanluxEngine -RndmGenSvc.Engine INFO Current Seed:1234567 Luxury:3 -RndmGenSvc INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine> -TimingAuditor.TIMER INFO This machine has a speed about 3.06 times the speed of a 2.8 GHz Xeon. -RichMoni INFO Member list: HltRoutingBitsFilter/PhysicsFilter, GaudiSequencer/RichDAQ, Rich::Mon::CameraRunFolder/CameraRunFolder, with context 'Offline' -RichDAQ INFO Member list: GaudiSequencer/DAQSeq, GaudiSequencer/NHitSeq, Rich::Mon::HitMapsMonitor/HitMapMon, with context 'Offline' -DAQSeq INFO Member list: Rich::DAQ::DataDBCheck/RichRawDataDBCheck, Rich::DAQ::DataDecodingErrorMoni/RichRawDataDecodeCheck, Rich::DAQ::RawDataSize/RichRawDataSizeCheck, Rich::Mon::MissingHPDMonitor/RichMissingHPDCheck, Rich::Mon::HPDAnalysisAlg/RichHotPixels, GaudiSequencer/DAQMonitorCentralEventSeq, with context 'Offline' -RootHistSvc INFO Writing ROOT histograms to: PanoptesOfflineHistos.root -HistogramPersistencySvc INFO Added successfully Conversion service:RootHistSvc -COOLConfSvc INFO CORAL Connection Retrial Period set to 60s -COOLConfSvc INFO CORAL Connection Retrial Time-Out set to 900s -DDDB INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/DDDB.db/DDDB" -DDDB INFO Using TAG "dddb-20150724" -LHCBCOND INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/LHCBCOND.db/LHCBCOND" -LHCBCOND INFO Using TAG "cond-20160517" -CALIBOFF INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/CALIBOFF.db/CALIBOFF" -CALIBOFF INFO Using TAG "head-2015604" -ONLINE_2016 INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/ONLINE-2016.db/ONLINE" -ONLINE_2016 INFO Using TAG "" -ToolSvc.CameraTool INFO Publish to DIM P057428/RICH_MONITORING/MESSAGES -RichHotPixels INFO Loading HPD Analysis tools : [RichHotPixelFinder] -DAQMonitorCentralEventSeq INFO Member list: Rich::Mon::DAQMonitor/DAQMonitorCentral, Rich::Mon::SingleEventSnapshot/DAQMonitorCentralEvtSnapshot, with context 'Offline' -DAQMonitorCentral INFO sent alerts at 30 seconds interval or when 10000 are reached -DAQMonitorCentral INFO alert-level for BxID warnings 3 -DAQMonitorCentral INFO check with ODIN bank 1 -DAQMonitorCentral INFO monitor BxIDs 1 -DAQMonitorCentral INFO Plot 2D histograms 0 -DAQMonitorCentral INFO TAE location ( = central) -DAQMonitorCentral INFO Print Messages 1 -DAQMonitorCentral INFO number of currently active HPDs (from ConditionDB) 447 -ToolSvc.RichUKL1Disable INFO FailureRateThreshold 0.01 -ToolSvc.RichUKL1Disable INFO Plot2DHisto 1 -ToolSvc.RichUKL1Disable INFO SendDisableCommands 0 -ToolSvc.RichUKL1Disable INFO HistoryTime 30 -ToolSvc.RichUKL1Disable INFO ClearListAtNewRun 1 -ToolSvc.RichUKL1Disable INFO BufferSize 1000 -ToolSvc.RichUKL1Disable INFO DisableCheckInterval 999999 -ToolSvc.RichUKL1Disable INFO DisableCheckHeartBeat 3 -ToolSvc.RichUKL1Disable INFO CamSummaryInterval 40 -ToolSvc.RichUKL1Disable INFO AlwaysDisable 0 -NHitSeq INFO Member list: GaudiSequencer/CombinedNHitMonitorSeq, GaudiSequencer/CentralTrigger0NHitMonitorSeq, GaudiSequencer/CentralTrigger1NHitMonitorSeq, GaudiSequencer/CentralTrigger3NHitMonitorSeq, GaudiSequencer/CentralTrigger6NHitMonitorSeq, GaudiSequencer/CentralTrigger7NHitMonitorSeq, with context 'Offline' -CombinedNHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CombinedNHitMonitor, Rich::Mon::SingleEventSnapshot/CombinedNHitMonitorEvtSnapshot, with context 'Offline' -CombinedNHitMonitor INFO Fill histograms 1 -CombinedNHitMonitor INFO Threshold for too many hits 50 -CombinedNHitMonitor INFO Send diable command to UKL1 0 -CombinedNHitMonitor INFO Moving average over 500 events -CombinedNHitMonitor INFO Using TAE events [] -CombinedNHitMonitor INFO Send alerts every 30 s -CombinedNHitMonitor INFO Add camera snapshot messages 1 -CombinedNHitMonitor INFO Monitor event with Trigger types : PhysicsTrigger BeamGasTrigger TechnicalTrigger TimingTrigger CalibrationTrigger -CombinedNHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 -CentralTrigger0NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger0NHitMonitor, with context 'Offline' -CentralTrigger0NHitMonitor INFO Fill histograms 1 -CentralTrigger0NHitMonitor INFO Threshold for too many hits 50 -CentralTrigger0NHitMonitor INFO Send diable command to UKL1 0 -CentralTrigger0NHitMonitor INFO Moving average over 500 events -CentralTrigger0NHitMonitor INFO Using TAE events [] -CentralTrigger0NHitMonitor INFO Send alerts every 30 s -CentralTrigger0NHitMonitor INFO Add camera snapshot messages 0 -CentralTrigger0NHitMonitor INFO Monitor event with Trigger types : PhysicsTrigger -CentralTrigger0NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 -CentralTrigger1NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger1NHitMonitor, with context 'Offline' -CentralTrigger1NHitMonitor INFO Fill histograms 1 -CentralTrigger1NHitMonitor INFO Threshold for too many hits 50 -CentralTrigger1NHitMonitor INFO Send diable command to UKL1 0 -CentralTrigger1NHitMonitor INFO Moving average over 500 events -CentralTrigger1NHitMonitor INFO Using TAE events [] -CentralTrigger1NHitMonitor INFO Send alerts every 30 s -CentralTrigger1NHitMonitor INFO Add camera snapshot messages 0 -CentralTrigger1NHitMonitor INFO Monitor event with Trigger types : BeamGasTrigger -CentralTrigger1NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 -CentralTrigger3NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger3NHitMonitor, with context 'Offline' -CentralTrigger3NHitMonitor INFO Fill histograms 1 -CentralTrigger3NHitMonitor INFO Threshold for too many hits 50 -CentralTrigger3NHitMonitor INFO Send diable command to UKL1 0 -CentralTrigger3NHitMonitor INFO Moving average over 500 events -CentralTrigger3NHitMonitor INFO Using TAE events [] -CentralTrigger3NHitMonitor INFO Send alerts every 30 s -CentralTrigger3NHitMonitor INFO Add camera snapshot messages 0 -CentralTrigger3NHitMonitor INFO Monitor event with Trigger types : TechnicalTrigger -CentralTrigger3NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 -CentralTrigger6NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger6NHitMonitor, with context 'Offline' -CentralTrigger6NHitMonitor INFO Fill histograms 1 -CentralTrigger6NHitMonitor INFO Threshold for too many hits 50 -CentralTrigger6NHitMonitor INFO Send diable command to UKL1 0 -CentralTrigger6NHitMonitor INFO Moving average over 500 events -CentralTrigger6NHitMonitor INFO Using TAE events [] -CentralTrigger6NHitMonitor INFO Send alerts every 30 s -CentralTrigger6NHitMonitor INFO Add camera snapshot messages 0 -CentralTrigger6NHitMonitor INFO Monitor event with Trigger types : TimingTrigger -CentralTrigger6NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 -CentralTrigger7NHitMonitorSeq INFO Member list: Rich::Mon::HPDNHitMonitor/CentralTrigger7NHitMonitor, with context 'Offline' -CentralTrigger7NHitMonitor INFO Fill histograms 1 -CentralTrigger7NHitMonitor INFO Threshold for too many hits 50 -CentralTrigger7NHitMonitor INFO Send diable command to UKL1 0 -CentralTrigger7NHitMonitor INFO Moving average over 500 events -CentralTrigger7NHitMonitor INFO Using TAE events [] -CentralTrigger7NHitMonitor INFO Send alerts every 30 s -CentralTrigger7NHitMonitor INFO Add camera snapshot messages 0 -CentralTrigger7NHitMonitor INFO Monitor event with Trigger types : CalibrationTrigger -CentralTrigger7NHitMonitor INFO Histogram for inclusive nHit counter between 0 and 10000 -HitMapMon INFO MonFreq 1 -HitMapMon INFO HotPixEventInterval 10000 -HitMapMon INFO HotPixelEnabled 0 -HitMapMon INFO HPDCountEnabled 0 -HitMapMon INFO HitsPerHPDMaps 0 -HitMapMon INFO LowResolutionHitMaps 1 -HitMapMon INFO HighResolutionHitMaps 0 -HitMapMon INFO IndividualHpdMaps 0 -HitMapMon INFO LowResolutionScaleFactor 2 -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160817/160817_0000000093.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_1 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160817/160817_0000000093.raw' SVC='LHCb::MDFSelector' -ApplicationMgr INFO Application Manager Initialized successfully -ApplicationMgr INFO Application Manager Started successfully -EventSelector.DataStreamTool_1 INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 1. Record number within stream 1: 1 -EventPersistencySvc INFO Added successfully Conversion service:LHCb::RawDataCnvSvc -ONLINE_2015 INFO Connected to database "sqlite_file:/afs/cern.ch/lhcb/software/DEV/nightlies/DBASE/Det/SQLDDDB/v7r999/db/ONLINE-2015.db/ONLINE" -ONLINE_2015 INFO Using TAG "" -RichMissingHPDCheck INFO First event seen -DAQMonitorCentral INFO First event seen -DAQMonitorCentral INFO =============> New Run 160817 <============= -CombinedNHitMonitor INFO First event seen -CentralTrigger0NHitMonitor INFO First event seen -CentralTrigger1NHitMonitor INFO First event seen -CentralTrigger3NHitMonitor INFO First event seen -CentralTrigger6NHitMonitor INFO First event seen -CentralTrigger7NHitMonitor INFO First event seen -ToolSvc.RichUKL1Disable INFO State : LHC '' LHCb 'NO DIM SERVICE' -ToolSvc.RichUKL1Disable INFO HPD SOFTWARE disabling now INACTIVE -EventSelector SUCCESS Reading Event record 5001. Record number within stream 1: 5001 -EventSelector SUCCESS Reading Event record 10001. Record number within stream 1: 10001 -EventSelector SUCCESS Reading Event record 15001. Record number within stream 1: 15001 -EventSelector SUCCESS Reading Event record 20001. Record number within stream 1: 20001 -EventSelector SUCCESS Reading Event record 25001. Record number within stream 1: 25001 -EventSelector SUCCESS Reading Event record 30001. Record number within stream 1: 30001 -EventSelector SUCCESS Reading Event record 35001. Record number within stream 1: 35001 -ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -LHCBCOND.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 40001. Record number within stream 1: 40001 -EventSelector SUCCESS Reading Event record 45001. Record number within stream 1: 45001 -EventSelector SUCCESS Reading Event record 50001. Record number within stream 1: 50001 -EventSelector SUCCESS Reading Event record 55001. Record number within stream 1: 55001 -EventSelector SUCCESS Reading Event record 60001. Record number within stream 1: 60001 -EventSelector SUCCESS Reading Event record 65001. Record number within stream 1: 65001 -EventSelector SUCCESS Reading Event record 70001. Record number within stream 1: 70001 -EventSelector SUCCESS Reading Event record 75001. Record number within stream 1: 75001 -EventSelector SUCCESS Reading Event record 80001. Record number within stream 1: 80001 -CALIBOFF.DataBaseOperationLock INFO Connecting to database -ONLINE_2015.DataBaseOperati... INFO Connecting to database -DDDB.DataBaseOperationLock INFO Connecting to database -LHCBCOND.DataBaseOperationLock INFO Connecting to database -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c1.up.cdf -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c2.up.cdf -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c3.up.cdf -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c4.up.cdf -MagneticFieldSvc INFO Map scaled by factor 1 with polarity internally used: 1 signed relative current: 1 -EventSelector.DataStreamTool_1 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160821/160821_0000000045.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_2 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160821/160821_0000000045.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_2 INFO Compression:0 Checksum:1 -DAQMonitorCentral INFO =============> New Run 160821 <============= -EventSelector SUCCESS Reading Event record 85001. Record number within stream 2: 1429 -EventSelector SUCCESS Reading Event record 90001. Record number within stream 2: 6429 -EventSelector.DataStreamTool_2 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160831/160831_0000000167.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_3 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160831/160831_0000000167.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_3 INFO Compression:0 Checksum:1 -DAQMonitorCentral INFO =============> New Run 160831 <============= -EventSelector SUCCESS Reading Event record 95001. Record number within stream 3: 4344 -EventSelector SUCCESS Reading Event record 100001. Record number within stream 3: 9344 -EventSelector SUCCESS Reading Event record 105001. Record number within stream 3: 14344 -EventSelector SUCCESS Reading Event record 110001. Record number within stream 3: 19344 -LHCBCOND.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 115001. Record number within stream 3: 24344 -EventSelector SUCCESS Reading Event record 120001. Record number within stream 3: 29344 -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 125001. Record number within stream 3: 34344 -EventSelector SUCCESS Reading Event record 130001. Record number within stream 3: 39344 -EventSelector SUCCESS Reading Event record 135001. Record number within stream 3: 44344 -EventSelector SUCCESS Reading Event record 140001. Record number within stream 3: 49344 -EventSelector SUCCESS Reading Event record 145001. Record number within stream 3: 54344 -EventSelector SUCCESS Reading Event record 150001. Record number within stream 3: 59344 -EventSelector SUCCESS Reading Event record 155001. Record number within stream 3: 64344 -EventSelector SUCCESS Reading Event record 160001. Record number within stream 3: 69344 -EventSelector SUCCESS Reading Event record 165001. Record number within stream 3: 74344 -EventSelector SUCCESS Reading Event record 170001. Record number within stream 3: 79344 -EventSelector.DataStreamTool_3 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160834/160834_0000000307.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_4 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160834/160834_0000000307.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_4 INFO Compression:0 Checksum:1 -CALIBOFF.DataBaseOperationLock INFO Connecting to database -ONLINE_2015.DataBaseOperati... INFO Connecting to database -DDDB.DataBaseOperationLock INFO Connecting to database -DAQMonitorCentral INFO =============> New Run 160834 <============= -EventSelector SUCCESS Reading Event record 175001. Record number within stream 4: 1671 -EventSelector SUCCESS Reading Event record 180001. Record number within stream 4: 6671 -EventSelector SUCCESS Reading Event record 185001. Record number within stream 4: 11671 -EventSelector SUCCESS Reading Event record 190001. Record number within stream 4: 16671 -EventSelector SUCCESS Reading Event record 195001. Record number within stream 4: 21671 -EventSelector SUCCESS Reading Event record 200001. Record number within stream 4: 26671 -EventSelector SUCCESS Reading Event record 205001. Record number within stream 4: 31671 -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 210001. Record number within stream 4: 36671 -EventSelector SUCCESS Reading Event record 215001. Record number within stream 4: 41671 -EventSelector SUCCESS Reading Event record 220001. Record number within stream 4: 46671 -EventSelector SUCCESS Reading Event record 225001. Record number within stream 4: 51671 -EventSelector SUCCESS Reading Event record 230001. Record number within stream 4: 56671 -EventSelector SUCCESS Reading Event record 235001. Record number within stream 4: 61671 -EventSelector SUCCESS Reading Event record 240001. Record number within stream 4: 66671 -EventSelector SUCCESS Reading Event record 245001. Record number within stream 4: 71671 -EventSelector SUCCESS Reading Event record 250001. Record number within stream 4: 76671 -EventSelector SUCCESS Reading Event record 255001. Record number within stream 4: 81671 -EventSelector.DataStreamTool_4 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision15/LHCb/Raw/160836/160836_0000000211.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_5 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision15/LHCb/Raw/160836/160836_0000000211.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_5 INFO Compression:0 Checksum:1 -CALIBOFF.DataBaseOperationLock INFO Connecting to database -ONLINE_2015.DataBaseOperati... INFO Connecting to database -DDDB.DataBaseOperationLock INFO Connecting to database -DAQMonitorCentral INFO =============> New Run 160836 <============= -EventSelector SUCCESS Reading Event record 260001. Record number within stream 5: 4726 -EventSelector SUCCESS Reading Event record 265001. Record number within stream 5: 9726 -EventSelector SUCCESS Reading Event record 270001. Record number within stream 5: 14726 -EventSelector SUCCESS Reading Event record 275001. Record number within stream 5: 19726 -EventSelector SUCCESS Reading Event record 280001. Record number within stream 5: 24726 -EventSelector SUCCESS Reading Event record 285001. Record number within stream 5: 29726 -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 290001. Record number within stream 5: 34726 -EventSelector SUCCESS Reading Event record 295001. Record number within stream 5: 39726 -EventSelector SUCCESS Reading Event record 300001. Record number within stream 5: 44726 -EventSelector SUCCESS Reading Event record 305001. Record number within stream 5: 49726 -EventSelector SUCCESS Reading Event record 310001. Record number within stream 5: 54726 -EventSelector SUCCESS Reading Event record 315001. Record number within stream 5: 59726 -EventSelector SUCCESS Reading Event record 320001. Record number within stream 5: 64726 -EventSelector SUCCESS Reading Event record 325001. Record number within stream 5: 69726 -EventSelector SUCCESS Reading Event record 330001. Record number within stream 5: 74726 -EventSelector SUCCESS Reading Event record 335001. Record number within stream 5: 79726 -EventSelector.DataStreamTool_5 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174362/174362_0000000074.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_6 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174362/174362_0000000074.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_6 INFO Compression:0 Checksum:1 -CALIBOFF.DataBaseOperationLock INFO Connecting to database -ONLINE_2015.DataBaseOperati... INFO Connecting to database -ONLINE_2016.DataBaseOperati... INFO Connecting to database -DDDB.DataBaseOperationLock INFO Connecting to database -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c1.down.cdf -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c2.down.cdf -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c3.down.cdf -MagneticFieldSvc INFO Opened magnetic field file : /afs/cern.ch/lhcb/software/releases/DBASE/FieldMap/v5r7/cdf/field.v5r0.c4.down.cdf -MagneticFieldSvc INFO Map scaled by factor 1 with polarity internally used: -1 signed relative current: -1 -DAQMonitorCentral INFO =============> New Run 174362 <============= -EventSelector SUCCESS Reading Event record 340001. Record number within stream 6: 2843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 345001. Record number within stream 6: 7843 -EventSelector SUCCESS Reading Event record 350001. Record number within stream 6: 12843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 355001. Record number within stream 6: 17843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 360001. Record number within stream 6: 22843 -EventSelector SUCCESS Reading Event record 365001. Record number within stream 6: 27843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -ONLINE_2015.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 370001. Record number within stream 6: 32843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 375001. Record number within stream 6: 37843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 380001. Record number within stream 6: 42843 -EventSelector SUCCESS Reading Event record 385001. Record number within stream 6: 47843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 390001. Record number within stream 6: 52843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 395001. Record number within stream 6: 57843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector SUCCESS Reading Event record 400001. Record number within stream 6: 62843 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -EventSelector.DataStreamTool_6 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000124.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_7 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000124.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_7 INFO Compression:0 Checksum:1 -ToolSvc.RichUKL1Disable INFO Summary : 124 active HPD report(s) -ToolSvc.RichUKL1Disable INFO Clearing list of 124 HPD report(s) -CALIBOFF.DataBaseOperationLock INFO Connecting to database -ONLINE_2016.DataBaseOperati... INFO Connecting to database -DDDB.DataBaseOperationLock INFO Connecting to database -DAQMonitorCentral INFO =============> New Run 174430 <============= -EventSelector SUCCESS Reading Event record 405001. Record number within stream 7: 383 -EventSelector SUCCESS Reading Event record 410001. Record number within stream 7: 5383 -EventSelector SUCCESS Reading Event record 415001. Record number within stream 7: 10383 -EventSelector SUCCESS Reading Event record 420001. Record number within stream 7: 15383 -EventSelector SUCCESS Reading Event record 425001. Record number within stream 7: 20383 -EventSelector SUCCESS Reading Event record 430001. Record number within stream 7: 25383 -EventSelector SUCCESS Reading Event record 435001. Record number within stream 7: 30383 -EventSelector SUCCESS Reading Event record 440001. Record number within stream 7: 35383 -EventSelector SUCCESS Reading Event record 445001. Record number within stream 7: 40383 -EventSelector SUCCESS Reading Event record 450001. Record number within stream 7: 45383 -EventSelector SUCCESS Reading Event record 455001. Record number within stream 7: 50383 -EventSelector SUCCESS Reading Event record 460001. Record number within stream 7: 55383 -EventSelector SUCCESS Reading Event record 465001. Record number within stream 7: 60383 -EventSelector.DataStreamTool_7 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000125.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_8 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000125.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_8 INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 470001. Record number within stream 8: 1371 -EventSelector SUCCESS Reading Event record 475001. Record number within stream 8: 6371 -EventSelector SUCCESS Reading Event record 480001. Record number within stream 8: 11371 -EventSelector SUCCESS Reading Event record 485001. Record number within stream 8: 16371 -EventSelector SUCCESS Reading Event record 490001. Record number within stream 8: 21371 -EventSelector SUCCESS Reading Event record 495001. Record number within stream 8: 26371 -EventSelector SUCCESS Reading Event record 500001. Record number within stream 8: 31371 -EventSelector SUCCESS Reading Event record 505001. Record number within stream 8: 36371 -EventSelector SUCCESS Reading Event record 510001. Record number within stream 8: 41371 -EventSelector SUCCESS Reading Event record 515001. Record number within stream 8: 46371 -EventSelector SUCCESS Reading Event record 520001. Record number within stream 8: 51371 -EventSelector SUCCESS Reading Event record 525001. Record number within stream 8: 56371 -EventSelector SUCCESS Reading Event record 530001. Record number within stream 8: 61371 -EventSelector.DataStreamTool_8 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000126.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_9 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000126.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamTool_9 INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 535001. Record number within stream 9: 2328 -EventSelector SUCCESS Reading Event record 540001. Record number within stream 9: 7328 -EventSelector SUCCESS Reading Event record 545001. Record number within stream 9: 12328 -EventSelector SUCCESS Reading Event record 550001. Record number within stream 9: 17328 -EventSelector SUCCESS Reading Event record 555001. Record number within stream 9: 22328 -EventSelector SUCCESS Reading Event record 560001. Record number within stream 9: 27328 -EventSelector SUCCESS Reading Event record 565001. Record number within stream 9: 32328 -EventSelector SUCCESS Reading Event record 570001. Record number within stream 9: 37328 -EventSelector SUCCESS Reading Event record 575001. Record number within stream 9: 42328 -EventSelector SUCCESS Reading Event record 580001. Record number within stream 9: 47328 -EventSelector SUCCESS Reading Event record 585001. Record number within stream 9: 52328 -EventSelector SUCCESS Reading Event record 590001. Record number within stream 9: 57328 -EventSelector SUCCESS Reading Event record 595001. Record number within stream 9: 62328 -EventSelector.DataStreamTool_9 INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000129.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_10 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000129.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 600001. Record number within stream 10: 3071 -EventSelector SUCCESS Reading Event record 605001. Record number within stream 10: 8071 -EventSelector SUCCESS Reading Event record 610001. Record number within stream 10: 13071 -EventSelector SUCCESS Reading Event record 615001. Record number within stream 10: 18071 -EventSelector SUCCESS Reading Event record 620001. Record number within stream 10: 23071 -EventSelector SUCCESS Reading Event record 625001. Record number within stream 10: 28071 -EventSelector SUCCESS Reading Event record 630001. Record number within stream 10: 33071 -EventSelector SUCCESS Reading Event record 635001. Record number within stream 10: 38071 -EventSelector SUCCESS Reading Event record 640001. Record number within stream 10: 43071 -EventSelector SUCCESS Reading Event record 645001. Record number within stream 10: 48071 -EventSelector SUCCESS Reading Event record 650001. Record number within stream 10: 53071 -EventSelector SUCCESS Reading Event record 655001. Record number within stream 10: 58071 -EventSelector SUCCESS Reading Event record 660001. Record number within stream 10: 63071 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000137.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_11 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174430/174430_0000000137.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 665001. Record number within stream 11: 4037 -EventSelector SUCCESS Reading Event record 670001. Record number within stream 11: 9037 -EventSelector SUCCESS Reading Event record 675001. Record number within stream 11: 14037 -EventSelector SUCCESS Reading Event record 680001. Record number within stream 11: 19037 -EventSelector SUCCESS Reading Event record 685001. Record number within stream 11: 24037 -ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 690001. Record number within stream 11: 29037 -EventSelector SUCCESS Reading Event record 695001. Record number within stream 11: 34037 -EventSelector SUCCESS Reading Event record 700001. Record number within stream 11: 39037 -EventSelector SUCCESS Reading Event record 705001. Record number within stream 11: 44037 -EventSelector SUCCESS Reading Event record 710001. Record number within stream 11: 49037 -EventSelector SUCCESS Reading Event record 715001. Record number within stream 11: 54037 -EventSelector SUCCESS Reading Event record 720001. Record number within stream 11: 59037 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000132.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_12 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000132.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -CALIBOFF.DataBaseOperationLock INFO Connecting to database -ONLINE_2016.DataBaseOperati... INFO Connecting to database -DDDB.DataBaseOperationLock INFO Connecting to database -LHCBCOND.DataBaseOperationLock INFO Connecting to database -DAQMonitorCentral INFO =============> New Run 174824 <============= -EventSelector SUCCESS Reading Event record 725001. Record number within stream 12: 9 -EventSelector SUCCESS Reading Event record 730001. Record number within stream 12: 5009 -EventSelector SUCCESS Reading Event record 735001. Record number within stream 12: 10009 -EventSelector SUCCESS Reading Event record 740001. Record number within stream 12: 15009 -EventSelector SUCCESS Reading Event record 745001. Record number within stream 12: 20009 -EventSelector SUCCESS Reading Event record 750001. Record number within stream 12: 25009 -LHCBCOND.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 755001. Record number within stream 12: 30009 -EventSelector SUCCESS Reading Event record 760001. Record number within stream 12: 35009 -EventSelector SUCCESS Reading Event record 765001. Record number within stream 12: 40009 -EventSelector SUCCESS Reading Event record 770001. Record number within stream 12: 45009 -CombinedNHitMonitor INFO Seen 3 'unusual' events in past 30 secs ( 0.1 Evt/s ) -EventSelector SUCCESS Reading Event record 775001. Record number within stream 12: 50009 -EventSelector SUCCESS Reading Event record 780001. Record number within stream 12: 55009 -EventSelector SUCCESS Reading Event record 785001. Record number within stream 12: 60009 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000138.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_13 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000138.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 790001. Record number within stream 13: 3548 -EventSelector SUCCESS Reading Event record 795001. Record number within stream 13: 8548 -EventSelector SUCCESS Reading Event record 800001. Record number within stream 13: 13548 -EventSelector SUCCESS Reading Event record 805001. Record number within stream 13: 18548 -EventSelector SUCCESS Reading Event record 810001. Record number within stream 13: 23548 -EventSelector SUCCESS Reading Event record 815001. Record number within stream 13: 28548 -EventSelector SUCCESS Reading Event record 820001. Record number within stream 13: 33548 -EventSelector SUCCESS Reading Event record 825001. Record number within stream 13: 38548 -EventSelector SUCCESS Reading Event record 830001. Record number within stream 13: 43548 -EventSelector SUCCESS Reading Event record 835001. Record number within stream 13: 48548 -EventSelector SUCCESS Reading Event record 840001. Record number within stream 13: 53548 -EventSelector SUCCESS Reading Event record 845001. Record number within stream 13: 58548 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000143.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_14 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000143.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 850001. Record number within stream 14: 1789 -EventSelector SUCCESS Reading Event record 855001. Record number within stream 14: 6789 -EventSelector SUCCESS Reading Event record 860001. Record number within stream 14: 11789 -EventSelector SUCCESS Reading Event record 865001. Record number within stream 14: 16789 -EventSelector SUCCESS Reading Event record 870001. Record number within stream 14: 21789 -ONLINE_2016.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -CALIBOFF.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -DDDB.TimeOutChecker INFO Disconnect from database after being idle for 120s (will reconnect if needed) -EventSelector SUCCESS Reading Event record 875001. Record number within stream 14: 26789 -EventSelector SUCCESS Reading Event record 880001. Record number within stream 14: 31789 -EventSelector SUCCESS Reading Event record 885001. Record number within stream 14: 36789 -EventSelector SUCCESS Reading Event record 890001. Record number within stream 14: 41789 -EventSelector SUCCESS Reading Event record 895001. Record number within stream 14: 46789 -EventSelector SUCCESS Reading Event record 900001. Record number within stream 14: 51789 -EventSelector SUCCESS Reading Event record 905001. Record number within stream 14: 56789 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000144.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_15 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000144.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 910001. Record number within stream 15: 170 -EventSelector SUCCESS Reading Event record 915001. Record number within stream 15: 5170 -EventSelector SUCCESS Reading Event record 920001. Record number within stream 15: 10170 -EventSelector SUCCESS Reading Event record 925001. Record number within stream 15: 15170 -EventSelector SUCCESS Reading Event record 930001. Record number within stream 15: 20170 -EventSelector SUCCESS Reading Event record 935001. Record number within stream 15: 25170 -EventSelector SUCCESS Reading Event record 940001. Record number within stream 15: 30170 -EventSelector SUCCESS Reading Event record 945001. Record number within stream 15: 35170 -EventSelector SUCCESS Reading Event record 950001. Record number within stream 15: 40170 -EventSelector SUCCESS Reading Event record 955001. Record number within stream 15: 45170 -EventSelector SUCCESS Reading Event record 960001. Record number within stream 15: 50170 -EventSelector SUCCESS Reading Event record 965001. Record number within stream 15: 55170 -EventSelector SUCCESS Reading Event record 970001. Record number within stream 15: 60170 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -IODataManager ERROR Referring to existing dataset /usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000145.raw by its physical name. -IODataManager ERROR You may not be able to navigate back to the input file -- processing continues -EventSelector INFO Stream:EventSelector.DataStreamTool_16 Def:DATAFILE='PFN:/usera/jonesc/NFS/data/Collision16/LHCb/Raw/174824/174824_0000000145.raw' SVC='LHCb::MDFSelector' -EventSelector.DataStreamToo... INFO Compression:0 Checksum:1 -EventSelector SUCCESS Reading Event record 975001. Record number within stream 16: 3222 -EventSelector SUCCESS Reading Event record 980001. Record number within stream 16: 8222 -EventSelector SUCCESS Reading Event record 985001. Record number within stream 16: 13222 -EventSelector SUCCESS Reading Event record 990001. Record number within stream 16: 18222 -EventSelector SUCCESS Reading Event record 995001. Record number within stream 16: 23222 -EventSelector SUCCESS Reading Event record 1000001. Record number within stream 16: 28222 -EventSelector SUCCESS Reading Event record 1005001. Record number within stream 16: 33222 -EventSelector SUCCESS Reading Event record 1010001. Record number within stream 16: 38222 -EventSelector SUCCESS Reading Event record 1015001. Record number within stream 16: 43222 -EventSelector SUCCESS Reading Event record 1020001. Record number within stream 16: 48222 -EventSelector SUCCESS Reading Event record 1025001. Record number within stream 16: 53222 -EventSelector SUCCESS Reading Event record 1030001. Record number within stream 16: 58222 -EventSelector.DataStreamToo... INFO Cannot read more data (Header). End-of-File reached. -EventLoopMgr INFO No more events in event selection -ApplicationMgr INFO Application Manager Stopped successfully -PhysicsFilter SUCCESS Number of counters : 1 - | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - |*"#accept" | 1033663 | 2.49e+05 |( 24.0890 +- 0.0420603)%| ------- | ------- | -RichRawDataDecodeCheck SUCCESS Booked 26 Histogram(s) : 2D=1 1DProf=25 -RichRawDataSizeCheck SUCCESS Booked 28 Histogram(s) : 1D=24 1DProf=4 -DAQMonitorCentral SUCCESS Booked 5 Histogram(s) : 1D=5 -DAQMonitorCentral SUCCESS Number of counters : 12 - | Counter | # | sum | mean/eff^* | rms/err^* | min | max | - | "AlertActiveHPDs" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertBxID" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertEmptyEvent" | 180362 | 180362 | 1.0000 | 0.0000 | 1.0000 | 1.0000 | - | "AlertEmptyHPD" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertEventID" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertExtendedHeader" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertHPDInhibit" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertHPDNotInhibitInvalidSmartRef" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertHPDSuppressed" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertInvalidOdinTime" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertL0ID" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | - | "AlertParityFooter" | 0 | 0 | 0.0000 | 0.0000 | 1.7977e+308 |-1.7977e+308 | -CombinedNHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 -CombinedNHitMonitorEvtSnapshotSUCCESS Booked 74 Histogram(s) : 2D=74 -CentralTrigger0NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 -CentralTrigger1NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 -CentralTrigger3NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 -CentralTrigger6NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 -CentralTrigger7NHitMonitor SUCCESS Booked 24 Histogram(s) : 1D=10 2D=9 1DProf=5 -HitMapMon SUCCESS Booked 8 Histogram(s) : 2D=8 -EventLoopMgr INFO Histograms converted successfully according to request. -ToolSvc INFO Removing all tools created by ToolSvc -ToolSvc.RichUKL1Disable SUCCESS Booked 4 Histogram(s) : 2D=4 -ToolSvc.RichSmartIDDecoder.... INFO ======================================================================================================================== -ToolSvc.RichSmartIDDecoder.... INFO RICH Level 1 : Decoding Summary : 1033663 events -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 1/ 8 V129 | L1 size = 17.03 +- 0.00 pds : 81.54 +- 0.01 words : 131.46 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 2/12 V129 | L1 size = 16.26 +- 0.00 pds : 85.34 +- 0.01 words : 148.88 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 3/ 1 V129 | L1 size = 6.80 +- 0.00 pds : 74.86 +- 0.01 words : 227.47 +- 0.02 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 4/ 6 V129 | L1 size = 15.60 +- 0.00 pds : 78.79 +- 0.01 words : 128.69 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 5/ 7 V129 | L1 size = 17.69 +- 0.00 pds : 77.44 +- 0.01 words : 118.96 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 6/ 3 V129 | L1 size = 13.64 +- 0.00 pds : 77.81 +- 0.01 words : 140.38 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 7/11 V129 | L1 size = 15.50 +- 0.00 pds : 81.98 +- 0.01 words : 141.69 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 8/ 2 V129 | L1 size = 14.67 +- 0.00 pds : 83.72 +- 0.01 words : 151.42 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 9/ 1 V129 | L1 size = 16.18 +- 0.00 pds : 75.30 +- 0.01 words : 122.89 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 10/13 V129 | L1 size = 16.46 +- 0.00 pds : 83.95 +- 0.01 words : 143.61 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 11/ 4 V129 | L1 size = 14.29 +- 0.00 pds : 73.66 +- 0.01 words : 123.75 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 12/ 5 V129 | L1 size = 16.24 +- 0.00 pds : 79.16 +- 0.01 words : 129.41 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 13/ 2 V129 | L1 size = 9.73 +- 0.00 pds : 65.94 +- 0.01 words : 142.41 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 14/ 3 V129 | L1 size = 12.51 +- 0.00 pds : 86.53 +- 0.01 words : 176.48 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 15/10 V129 | L1 size = 9.14 +- 0.00 pds : 76.20 +- 0.01 words : 208.81 +- 0.02 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 16/ 4 V129 | L1 size = 10.67 +- 0.00 pds : 78.17 +- 0.01 words : 161.68 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 17/ 5 V129 | L1 size = 11.30 +- 0.00 pds : 75.74 +- 0.01 words : 165.67 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 18/ 6 V129 | L1 size = 10.00 +- 0.00 pds : 75.19 +- 0.01 words : 171.38 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 19/ 9 V129 | L1 size = 12.52 +- 0.00 pds : 83.62 +- 0.01 words : 167.44 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 20/ 7 V129 | L1 size = 12.64 +- 0.00 pds : 62.53 +- 0.01 words : 105.93 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 22/ 9 V129 | L1 size = 15.80 +- 0.00 pds : 79.55 +- 0.01 words : 132.32 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 23/ 8 V129 | L1 size = 12.57 +- 0.00 pds : 72.88 +- 0.01 words : 133.11 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich2 L1ID(hard/log) 24/10 V129 | L1 size = 15.78 +- 0.00 pds : 82.87 +- 0.01 words : 142.28 +- 0.01 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich1 L1ID(hard/log) 27/11 V129 | L1 size = 6.46 +- 0.00 pds : 77.18 +- 0.01 words : 205.51 +- 0.02 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ------------------------------------------------------------------------------------------------------------------------ -ToolSvc.RichSmartIDDecoder.... INFO Rich1 Average | L1 size = 114.34 +- 0.01 pds : 828.86 +- 0.03 words : 1865.90 +- 0.05 hits / event -ToolSvc.RichSmartIDDecoder.... INFO Rich2 Average | L1 size = 205.14 +- 0.02 pds : 1041.11 +- 0.03 words : 1755.74 +- 0.05 hits / event -ToolSvc.RichSmartIDDecoder.... INFO ======================================================================================================================== -TimingAuditor.TIMER INFO -------------------------------------------------------------------------------------------------- -TimingAuditor.TIMER INFO This machine has a speed about 3.06 times the speed of a 2.8 GHz Xeon. -TimingAuditor.TIMER INFO Algorithm (millisec) | <user> | <clock> | min max sigma | entries | total (s) | -TimingAuditor.TIMER INFO -------------------------------------------------------------------------------------------------- -TimingAuditor.TIMER INFO EVENT LOOP | 2.738 | 2.837 | 0.277 9703.6 10.59 | 1033663 | 2933.505 | -TimingAuditor.TIMER INFO RichMoni | 1.932 | 1.990 | 0.252 9703.5 9.62 | 1033663 | 2057.240 | -TimingAuditor.TIMER INFO PhysicsFilter | 0.002 | 0.003 | 0.002 4.5 0.01 | 1033663 | 3.827 | -TimingAuditor.TIMER INFO RichDAQ | 1.921 | 1.976 | 0.240 9703.5 9.62 | 1033663 | 2043.519 | -TimingAuditor.TIMER INFO DAQSeq | 0.875 | 0.946 | 0.187 65.3 0.49 | 1033663 | 978.068 | -TimingAuditor.TIMER INFO RichRawDataDBCheck | 0.319 | 0.382 | 0.005 10.7 0.25 | 1033663 | 395.244 | -TimingAuditor.TIMER INFO RichRawDataDecodeCheck | 0.140 | 0.145 | 0.002 13.2 0.08 | 1033663 | 150.381 | -TimingAuditor.TIMER INFO RichRawDataSizeCheck | 0.278 | 0.283 | 0.153 8.5 0.07 | 1033663 | 292.570 | -TimingAuditor.TIMER INFO RichMissingHPDCheck | 0.023 | 0.024 | 0.002 62.4 0.07 | 1033663 | 25.055 | -TimingAuditor.TIMER INFO RichHotPixels | 0.021 | 0.021 | 0.000 8.6 0.18 | 1033663 | 21.904 | -TimingAuditor.TIMER INFO DAQMonitorCentralEventSeq | 0.073 | 0.074 | 0.005 7.7 0.06 | 1033663 | 76.805 | -TimingAuditor.TIMER INFO DAQMonitorCentral | 0.068 | 0.069 | 0.001 7.7 0.06 | 1033663 | 72.097 | -TimingAuditor.TIMER INFO DAQMonitorCentralEvtSnaps| 0.000 | 0.000 | 0.000 0.0 0.00 | 0 | 0.000 | -TimingAuditor.TIMER INFO NHitSeq | 0.726 | 0.710 | 0.044 9700.1 9.55 | 1033663 | 734.207 | -TimingAuditor.TIMER INFO CombinedNHitMonitorSeq | 0.459 | 0.457 | 0.006 9699.5 9.55 | 1033663 | 473.120 | -TimingAuditor.TIMER INFO CombinedNHitMonitor | 0.452 | 0.443 | 0.002 87.5 0.37 | 1033663 | 458.062 | -TimingAuditor.TIMER INFO CombinedNHitMonitorEvtSna| 22.295 | 118.643 | 0.003 9654.3 1034.26 | 87 | 10.322 | -TimingAuditor.TIMER INFO CentralTrigger0NHitMonitor| 0.226 | 0.214 | 0.005 13.0 0.14 | 1033663 | 221.209 | -TimingAuditor.TIMER INFO CentralTrigger0NHitMonito| 0.220 | 0.209 | 0.001 13.0 0.14 | 1033663 | 216.522 | -TimingAuditor.TIMER INFO CentralTrigger1NHitMonitor| 0.007 | 0.007 | 0.005 5.9 0.01 | 1033663 | 7.423 | -TimingAuditor.TIMER INFO CentralTrigger1NHitMonito| 0.002 | 0.003 | 0.001 5.8 0.01 | 1033663 | 3.347 | -TimingAuditor.TIMER INFO CentralTrigger3NHitMonitor| 0.005 | 0.006 | 0.005 2.4 0.01 | 1033663 | 6.377 | -TimingAuditor.TIMER INFO CentralTrigger3NHitMonito| 0.001 | 0.002 | 0.001 1.3 0.00 | 1033663 | 2.360 | -TimingAuditor.TIMER INFO CentralTrigger6NHitMonitor| 0.005 | 0.006 | 0.005 4.1 0.01 | 1033663 | 6.302 | -TimingAuditor.TIMER INFO CentralTrigger6NHitMonito| 0.001 | 0.002 | 0.001 1.7 0.00 | 1033663 | 2.336 | -TimingAuditor.TIMER INFO CentralTrigger7NHitMonitor| 0.005 | 0.006 | 0.005 4.6 0.01 | 1033663 | 6.311 | -TimingAuditor.TIMER INFO CentralTrigger7NHitMonito| 0.001 | 0.002 | 0.001 4.0 0.00 | 1033663 | 2.280 | -TimingAuditor.TIMER INFO HitMapMon | 0.311 | 0.312 | 0.001 12.9 0.29 | 1033663 | 322.953 | -TimingAuditor.TIMER INFO CameraRunFolder | 0.000 | 0.001 | 0.000 3.2 0.00 | 1033663 | 1.258 | -TimingAuditor.TIMER INFO -------------------------------------------------------------------------------------------------- -ApplicationMgr INFO Application Manager Finalized successfully -ApplicationMgr INFO Application Manager Terminated successfully -- GitLab From 626577885f5e5b5f2dd400b694dfd7bf5c9259b3 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 14 Jun 2016 11:42:24 +0100 Subject: [PATCH 07/37] fix typo in hot pixel check flag --- .../RichMonitoringSys/python/RichMonitoringSys/Configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rich/RichMonitoringSys/python/RichMonitoringSys/Configuration.py b/Rich/RichMonitoringSys/python/RichMonitoringSys/Configuration.py index a849f03fa..27b766a54 100755 --- a/Rich/RichMonitoringSys/python/RichMonitoringSys/Configuration.py +++ b/Rich/RichMonitoringSys/python/RichMonitoringSys/Configuration.py @@ -375,7 +375,7 @@ class RichMonitoringSysConf(RichConfigurableUser): seq.Members += [Rich__Mon__MissingHPDMonitor("RichMissingHPDCheck")] # Hot pixels - if self.getProp("MissingHPDCheck"): + if self.getProp("HotPixelCheck"): from Configurables import Rich__Mon__HPDAnalysisAlg, Rich__HPDHotPixelFinder hotpix = Rich__Mon__HPDAnalysisAlg("RichHotPixels") hotpix.HPDAnalysisTools = ["RichHotPixelFinder"] -- GitLab From c91c36f375452f99cd92e78f5f8473da72405bb3 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 13:53:03 +0100 Subject: [PATCH 08/37] Add CK resolution summary log + small fix to new run printout for HPD calibration task --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 72 +++++++++++++++++-- Rich/RichOnlineCalib/src/OMARichRefIndex.h | 43 ++++++++++- .../src/RichOnlineHPDImageSummary.cpp | 31 ++++---- 3 files changed, 122 insertions(+), 24 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 3d0e8b865..978fe9786 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -17,7 +17,7 @@ //============================================================================= OMARichRefIndex::OMARichRefIndex( const std::string& name, ISvcLocator* pSvcLocator ) - : AnalysisTask ( name , pSvcLocator ), + : AnalysisTask ( name, pSvcLocator ), m_CamTool ( nullptr ), m_Name ( name ), m_mergedRun ( 0, "" ), @@ -60,6 +60,7 @@ OMARichRefIndex::OMARichRefIndex( const std::string& name, declareProperty("RefIndexSFLog" , m_RefIndexSFLog = "refIndexSF.txt" ); declareProperty("DIMSummaryFile", m_dimSummaryFile = "DIMUpdateSummary.txt" ); + declareProperty("CKThetaResLog", m_CKThetaResLog = "CKThetaResolutions.txt" ); declareProperty("DisableDIMPublish", m_disableDIMpublish = false ); @@ -200,7 +201,10 @@ StatusCode OMARichRefIndex::analyze (std::string& SaveSet, const std::string fileName = boost::filesystem::path(SaveSet).stem().string(); // Extract the run number - const unsigned int runNumber = getRunNumber( fileName ); + const auto runNumber = getRunNumber( fileName ); + + // Extract the timestamp + m_fileTime = getTimeStamp( fileName ); // start the camera message std::ostringstream mess1, mess2; @@ -296,6 +300,9 @@ OMARichRefIndex::runCalibration( const std::string& type, if ( m_createPDFsummary ) { printCanvas("["); } bool keepPDF = false; + // Is this a final calibration ? + const bool isFinal = ( type == "Final EOR" || type == "Final" ); + // Loop over radiators for ( const auto& rad : m_rads ) { @@ -324,6 +331,12 @@ OMARichRefIndex::runCalibration( const std::string& type, // Draw to canvas draw( radHist ); + // Is the fit ok + bool fitOK = false; + + // save fitted CK resolution + double ckRes = 0; + double scale = 1.0 ; if ( checkCKThetaStats(radHist) ) { @@ -331,12 +344,14 @@ OMARichRefIndex::runCalibration( const std::string& type, keepPDF = true; // run the fit const auto fitresult = fitCKThetaHistogram( radHist, rad, m_nPolFull ); - if ( fitresult.first ) + if ( fitresult.fitOK ) { + fitOK = true; + ckRes = fitresult.ckResolution; m_cachedCalibCount[rad] = 0; // Normal calibration, so reset count to 0 - scale = nScaleFromShift( fitresult.second, rad ); + scale = nScaleFromShift( fitresult.ckShift, rad ); std::ostringstream mess; - mess << rad << " n-1 shift = " << fitresult.second << " scale = " << scale; + mess << rad << " n-1 shift = " << fitresult.ckShift << " scale = " << scale; cameraTool()->Append("TEXT",mess.str()); } else @@ -376,6 +391,9 @@ OMARichRefIndex::runCalibration( const std::string& type, debug() << mess.str() << endmsg; } + // if a final OK calibration, write to CK resolution summary + if ( fitOK && isFinal ) { writeCKThetaLog( rad, ckRes, runNumber ); } + // publish results. Only if histogram did not have 0 entries if ( 0 != radHist->GetEntries() && ( publishCalib || betterHistStats ) ) @@ -487,7 +505,7 @@ StatusCode OMARichRefIndex::finalize() //============================================================================= // Fitting histogram //============================================================================= -std::pair<bool,double> +OMARichRefIndex::FitResult OMARichRefIndex::fitCKThetaHistogram( TH1* hist, const std::string& rad, const unsigned int nPolFull ) @@ -665,7 +683,9 @@ OMARichRefIndex::fitCKThetaHistogram( TH1* hist, fitOK &= finalCheck; // return final fit parameter for shift - return std::make_pair( fitOK, fitOK ? bestFitF.GetParameter(1) : 0.0 ); + return FitResult( fitOK, + fitOK ? bestFitF.GetParameter(1) : 0.0, + fitOK ? bestFitF.GetParameter(2) : 0.0 ); } //============================================================================= @@ -979,6 +999,44 @@ bool OMARichRefIndex::writeToDimSummaryFile( const std::string & mess ) const //============================================================================= +bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, + const double ckThetaRes, + const unsigned int runNumber ) const +{ + bool ok = true; + + // Path to the summary file + const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : + "Rich2Gas" == rad ? m_Rich2TaskName : + "UNKNOWN" ); + const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ) ; + const boost::filesystem::path filename( m_CKThetaResLog ); + const boost::filesystem::path full_path = dir/filename ; + createDir( dir ); + + // open the file in append mode + std::ofstream file( full_path.string().c_str(), std::ios_base::app ); + if ( file.is_open() ) + { + // write out the result for this run + file << runNumber << " " << m_fileTime << " " << ckThetaRes << std::endl; + // close the file + file.close(); + } + else + { + std::ostringstream m; + m << "Problem writing CK resolution summary file " << full_path; + warning() << m.str() << endmsg; + cameraTool()->Append("TEXT",m.str()); + ok = false; + } + + return ok; +} + +//============================================================================= + std::pair<bool,unsigned long long> OMARichRefIndex::setVersion( const unsigned int runNumber, const std::string& rad ) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.h b/Rich/RichOnlineCalib/src/OMARichRefIndex.h index ffc61b8bb..93b165892 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.h +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.h @@ -20,6 +20,7 @@ // Boost #include <boost/filesystem.hpp> +#include "boost/algorithm/string.hpp" // STL #include <fstream> @@ -62,6 +63,22 @@ public: virtual StatusCode analyze( std::string& SaveSet, std::string Task ); ///< Algorithm analyze + +private: + + class FitResult + { + public: + FitResult( const bool ok, + const double shift, + const double res ) + : fitOK(ok), ckShift(shift), ckResolution(res) { } + public: + bool fitOK{false}; + double ckShift{0}; + double ckResolution{0}; + }; + private: //============================================================================= @@ -84,9 +101,9 @@ private: //============================================================================= /// Fit the histogram //============================================================================= - std::pair<bool,double> fitCKThetaHistogram( TH1* hist, - const std::string& rad, - const unsigned int nPolFull ); + FitResult fitCKThetaHistogram( TH1* hist, + const std::string& rad, + const unsigned int nPolFull ); //============================================================================= // Check histogram fit result @@ -105,6 +122,15 @@ private: return atoi( runString.c_str() ); } + // Function to get time stamp from the file name + inline std::string getTimeStamp( const std::string& fileName ) + { + const std::string tmp1 = fileName.substr(fileName.find_first_of("-")+1); + std::string tmp2 = tmp1.substr(tmp1.find_first_of("-")+1); + boost::erase_all(tmp2,"-EOR"); + return tmp2; + } + //============================================================================= /// Function to check whether enough entries //============================================================================= @@ -290,6 +316,11 @@ private: /// Write a message to the DIM summary file bool writeToDimSummaryFile( const std::string & mess ) const; + /// Write to the CK theta resolution summary log + bool writeCKThetaLog( const std::string& rad, + const double ckThetaRes, + const unsigned int runNumber ) const; + private: /// CAMERA reporting tool @@ -361,6 +392,12 @@ private: /// log file for previous scale factors std::string m_RefIndexSFLog; + /// log file for fitted CK theta resolutions + std::string m_CKThetaResLog; + + /// Cache the timestampe from the saveset name + std::string m_fileTime; + /// DIM Summary file name std::string m_dimSummaryFile; diff --git a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp index 1585e6683..41c0b299a 100644 --- a/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp +++ b/Rich/RichOnlineCalib/src/RichOnlineHPDImageSummary.cpp @@ -1093,11 +1093,14 @@ StatusCode OnlineSummary::execute() // Monitor for new runs if ( UNLIKELY( RunNumber != m_lastRunNumberCamera ) ) { - m_lastRunNumberCamera = RunNumber; - std::ostringstream m; - m << "=============> New Run " << RunNumber << " <============="; - info() << m.str() << endmsg; - cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,m.str()); + if ( UNLIKELY( m_processedRuns.find(RunNumber) != m_processedRuns.end() ) ) + { + m_lastRunNumberCamera = RunNumber; + std::ostringstream m; + m << "=============> New Run " << RunNumber << " <============="; + info() << m.str() << endmsg; + cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,m.str()); + } } // Check to see if a calibration should be run due to a new run being detected @@ -1138,15 +1141,15 @@ StatusCode OnlineSummary::execute() { // Print message on the number of events seen and the rate struct tm * timeinfo = localtime ( &deltaT ); - std::ostringstream messageString; - messageString << "Seen " << m_nEventsSinceCalib << " events in past "; - if ( timeinfo->tm_hour-1 > 0 ) { messageString << timeinfo->tm_hour-1 << " hours "; } - if ( timeinfo->tm_min > 0 ) { messageString << timeinfo->tm_min << " mins "; } - if ( timeinfo->tm_sec > 0 ) { messageString << timeinfo->tm_sec << " secs "; } - messageString << "( " << (double)(m_nEventsSinceCalib) / (double)(deltaT) - << " Evt/s )"; - cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, messageString.str() ); - info() << messageString.str() << endmsg; + std::ostringstream messageS; + messageS << "Seen " << m_nEventsSinceCalib << " events in past "; + if ( timeinfo->tm_hour-1 > 0 ) { messageS << timeinfo->tm_hour-1 << " hours "; } + if ( timeinfo->tm_min > 0 ) { messageS << timeinfo->tm_min << " mins "; } + if ( timeinfo->tm_sec > 0 ) { messageS << timeinfo->tm_sec << " secs "; } + messageS << "( " << (double)(m_nEventsSinceCalib) / (double)(deltaT) + << " Evt/s )"; + cameraTool()->SendAndClearTS( ICameraTool::INFO, m_Name, messageS.str() ); + info() << messageS.str() << endmsg; // run periodic calibration, no histogram reset... runCalibration("Periodic"); -- GitLab From 20522d467a0d7252bfd294ab2323dd4f4784bacb Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 13:53:30 +0100 Subject: [PATCH 09/37] small monitor cleanup --- .../src/RichMissingHPDMonitor.cpp | 96 +++++++------------ .../src/RichMissingHPDMonitor.h | 17 +++- 2 files changed, 47 insertions(+), 66 deletions(-) diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp index 0168d1223..3d423ac36 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp @@ -1,16 +1,7 @@ -// $Id: RichMissingHPDMonitor.cpp,v 1.33 2010-02-04 12:17:30 ukerzel Exp $ -// Include files - -// from Gaudi -#include "GaudiKernel/AlgFactory.h" // local #include "RichMissingHPDMonitor.h" -// RICH -#include "RichKernel/RichDAQDefinitions.h" -#include "RichKernel/RichSmartIDCnv.h" - //----------------------------------------------------------------------------- using namespace Rich::Mon; @@ -22,17 +13,27 @@ DECLARE_ALGORITHM_FACTORY( MissingHPDMonitor ) // Standard constructor, initializes variables //============================================================================= MissingHPDMonitor::MissingHPDMonitor( const std::string& name, - ISvcLocator* pSvcLocator) - : Rich::HistoAlgBase ( name , pSvcLocator ), - m_taeEvents ( 1, "" ), - m_Name ( name ) + ISvcLocator* pSvcLocator ) + : Rich::HistoAlgBase ( name , pSvcLocator ), + m_taeEvents ( 1, "" ), + m_Name ( name ) { - m_activeRICH[Rich::Rich1] = true; - m_activeRICH[Rich::Rich2] = true; declareProperty( "RawEventLocations", m_taeEvents ); declareProperty( "HPDCheckFreq", m_checkFreq = 1000 ); declareProperty( "MaxMissingEvents", m_maxMissingEvents = 100000 ); declareProperty( "VetoNoBias" , m_vetoNoBias = true ); + + // Partition + const char* partitionName = getenv("PARTITION"); + m_activeRICH[Rich::Rich1] = true; + m_activeRICH[Rich::Rich2] = true; + if ( partitionName ) + { + const std::string sPartition(partitionName); + m_Name += sPartition; + if ( "RICH1" == sPartition ) { m_activeRICH[Rich::Rich2] = false; } + else if ( "RICH2" == sPartition ) { m_activeRICH[Rich::Rich1] = false; } + } } //============================================================================= @@ -48,20 +49,8 @@ StatusCode MissingHPDMonitor::initialize() const StatusCode sc = Rich::HistoAlgBase::initialize(); if ( sc.isFailure() ) return sc; - // Partition - const char* partitionName = getenv("PARTITION"); - m_Name = name(); - if ( partitionName ) - { - const std::string sPartition(partitionName); - m_Name += sPartition; - if ( sPartition == "RICH1" ) m_activeRICH[Rich::Rich2] = false; - if ( sPartition == "RICH2" ) m_activeRICH[Rich::Rich1] = false; - } - // talk to camera - if ( msgLevel(MSG::VERBOSE) ) - verbose() << "send message to CAMERA" << endmsg; + _ri_verbo << "send message to CAMERA" << endmsg; cameraTool()->Append("TEXT",m_Name.c_str()); cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,"Initialized"); @@ -77,7 +66,7 @@ StatusCode MissingHPDMonitor::execute() StatusCode sc = StatusCode::SUCCESS; // load the ODIN - const LHCb::ODIN * odin = getIfExists<LHCb::ODIN>( LHCb::ODINLocation::Default ); + const auto * odin = getIfExists<LHCb::ODIN>( LHCb::ODINLocation::Default ); if ( !odin ) return sc; // Veto NoBias @@ -99,33 +88,22 @@ StatusCode MissingHPDMonitor::execute() // main loop over HPDs in the data const auto & l1Map = smartIDDecoder()->allRichSmartIDs(m_taeEvents); - if ( msgLevel(MSG::VERBOSE) ) - verbose() << "L1 map has size " << l1Map.size() << endmsg; + _ri_verbo << "L1 map has size " << l1Map.size() << endmsg; - for ( Rich::DAQ::L1Map::const_iterator iL1Map = l1Map.begin(); - iL1Map != l1Map.end(); ++iL1Map ) + for ( const auto & L1 : l1Map ) { - //const Rich::DAQ::Level1HardwareID l1HardID = iL1Map->first; - const Rich::DAQ::IngressMap &ingressMap = iL1Map->second; - - for ( Rich::DAQ::IngressMap::const_iterator iIngressMap = ingressMap.begin(); - iIngressMap != ingressMap.end(); ++iIngressMap ) + for ( const auto & ingress : L1.second ) { - - const Rich::DAQ::IngressInfo & ingressInfo = iIngressMap->second; - const Rich::DAQ::HPDMap & hpdMap = ingressInfo.hpdData(); - for ( Rich::DAQ::HPDMap::const_iterator iHPDMap = hpdMap.begin(); - iHPDMap != hpdMap.end(); ++iHPDMap ) + for ( const auto & HPD : ingress.second.hpdData() ) { - const Rich::DAQ::HPDInfo &hpdInfo = iHPDMap->second; - const LHCb::RichSmartID &smartIDHPD = hpdInfo.hpdID(); + // HPD smart ID + const auto & smartIDHPD = HPD.second.hpdID(); // check for valid HPD if ( !smartIDHPD.isValid() ) { continue; } // Flag this HPD as having been seen in the data, with the event count number m_hpdCount[ smartIDHPD ] = m_nEvts; - } } } @@ -136,41 +114,37 @@ StatusCode MissingHPDMonitor::execute() { // Loop over HPDs expected to be present and flag those missing - const LHCb::RichSmartID::Vector & activeHpds = deRichSys()->activePDRichSmartIDs(); - for ( LHCb::RichSmartID::Vector::const_iterator iHPD = activeHpds.begin(); - iHPD != activeHpds.end(); ++iHPD ) + for ( const auto & HPD : deRichSys()->activePDRichSmartIDs() ) { // Is this RICH active. - if ( m_activeRICH[(*iHPD).rich()] ) + if ( m_activeRICH[HPD.rich()] ) { - if ( ( m_nEvts - m_hpdCount[*iHPD] ) > m_maxMissingEvents ) + if ( UNLIKELY( ( m_nEvts - m_hpdCount[HPD] ) > m_maxMissingEvents ) ) { // it is missing std::ostringstream mess; mess << "HPD active but no data seen for " << m_maxMissingEvents << " events or more"; - //hpdDisableTool() -> ReportHPD( *iHPD, mess.str() ); - hpdDisableTool() -> DisableHPD( *iHPD, mess.str() ); - //info() << mess.str() << endmsg; + //hpdDisableTool() -> ReportHPD( HPD, mess.str() ); + hpdDisableTool() -> DisableHPD( HPD, mess.str() ); + //warning() << mess.str() << endmsg; } } } // Now, loop over those expected to be missing and flag those present - const LHCb::RichSmartID::Vector & inactiveHpds = deRichSys()->inactivePDRichSmartIDs(); - for ( LHCb::RichSmartID::Vector::const_iterator iHPD = inactiveHpds.begin(); - iHPD != inactiveHpds.end(); ++iHPD ) + for ( const auto & HPD : deRichSys()->inactivePDRichSmartIDs() ) { // Is this RICH active. - if ( m_activeRICH[(*iHPD).rich()] ) + if ( m_activeRICH[HPD.rich()] ) { - if ( ( m_nEvts - m_hpdCount[*iHPD] ) < m_maxMissingEvents ) + if ( UNLIKELY( ( m_nEvts - m_hpdCount[HPD] ) < m_maxMissingEvents ) ) { // This HPD is present in the data ... std::ostringstream mess; mess << "HPD inactive but present in the data during the last " << m_maxMissingEvents << " events"; - hpdDisableTool() -> ReportHPD( *iHPD, mess.str() ); - //info() << mess.str() << endmsg; + hpdDisableTool() -> ReportHPD( HPD, mess.str() ); + //warning() << mess.str() << endmsg; } } } diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h index 97ca2da87..8ea76ea30 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h @@ -1,7 +1,10 @@ -// $Id: RichMissingHPDMonitor.h,v 1.18 2010-02-04 12:17:30 ukerzel Exp $ + #ifndef RichMissingHPDMonitor_H #define RichMissingHPDMonitor_H 1 +// from Gaudi +#include "GaudiKernel/AlgFactory.h" + // base class #include "RichKernel/RichHistoAlgBase.h" @@ -19,6 +22,10 @@ // RichDet #include "RichDet/DeRichSystem.h" +// RichKernel +#include "RichKernel/RichDAQDefinitions.h" +#include "RichKernel/RichSmartIDCnv.h" + // Monitoring tools #include "RichMonitoringTools/IHpdUkL1DisableTool.h" @@ -121,10 +128,10 @@ namespace Rich std::vector<std::string> m_taeEvents; ///< The TAE location(s) to monitor - unsigned long int m_checkFreq; ///< The rate, in number of events, to check for missing HPDs - unsigned long long m_lastEventCheck; ///< The last event checked - unsigned long int m_maxMissingEvents; ///< Maximum allowed number of events an HPD can be missing for - bool m_vetoNoBias; ///< Veto no bias events + unsigned long int m_checkFreq; ///< The rate, in number of events, to check for missing HPDs + unsigned long long m_lastEventCheck{0}; ///< The last event checked + unsigned long int m_maxMissingEvents; ///< Maximum allowed #events an HPD can be missing for + bool m_vetoNoBias; ///< Veto no bias events /// Count events unsigned long long m_nEvts{0}; -- GitLab From 2f21a48c9cbef05f0e0c3c29b680bf75380fa0c5 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 15:04:05 +0100 Subject: [PATCH 10/37] temporary file copy code --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 978fe9786..faa093d2a 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -123,6 +123,11 @@ StatusCode OMARichRefIndex::initialize() } } + boost::filesystem::copy_file( "/group/online/alignment/Rich1/Calib/CKThetaResolutions.txt", + "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); + boost::filesystem::copy_file( "/group/online/alignment/Rich2/Calib/CKThetaResolutions.txt", + "/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt" ); + // reset the cached histogram stats m_histStats.clear(); @@ -1009,8 +1014,8 @@ bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : "Rich2Gas" == rad ? m_Rich2TaskName : "UNKNOWN" ); - const boost::filesystem::path dir( m_xmlFilePath + "/" + subDet ) ; - const boost::filesystem::path filename( m_CKThetaResLog ); + const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" ) ; + const boost::filesystem::path filename( rad + m_CKThetaResLog ); const boost::filesystem::path full_path = dir/filename ; createDir( dir ); -- GitLab From 939cb4c7b975f3769d01c681f1c69b4988beb432 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 15:05:40 +0100 Subject: [PATCH 11/37] remove temporary file copy code --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index faa093d2a..d6c6add77 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -123,11 +123,6 @@ StatusCode OMARichRefIndex::initialize() } } - boost::filesystem::copy_file( "/group/online/alignment/Rich1/Calib/CKThetaResolutions.txt", - "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); - boost::filesystem::copy_file( "/group/online/alignment/Rich2/Calib/CKThetaResolutions.txt", - "/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt" ); - // reset the cached histogram stats m_histStats.clear(); -- GitLab From bdcab4e32f69a8c6110806697ce456f592c3f81c Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 15:08:19 +0100 Subject: [PATCH 12/37] remove unused variable --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index d6c6add77..d7b574f02 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -1006,9 +1006,6 @@ bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, bool ok = true; // Path to the summary file - const std::string subDet = ( "Rich1Gas" == rad ? m_Rich1TaskName : - "Rich2Gas" == rad ? m_Rich2TaskName : - "UNKNOWN" ); const boost::filesystem::path dir( m_xmlFilePath + "/RichCalibSummaries/" ) ; const boost::filesystem::path filename( rad + m_CKThetaResLog ); const boost::filesystem::path full_path = dir/filename ; -- GitLab From 178ebbca49b2ee3022edec3cd32cd65e69158313 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 15:54:17 +0100 Subject: [PATCH 13/37] add fit errors to CK theta summary file --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 28 ++++++++++++-------- Rich/RichOnlineCalib/src/OMARichRefIndex.h | 13 ++++++--- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index d7b574f02..679a72906 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -129,6 +129,11 @@ StatusCode OMARichRefIndex::initialize() // send a message to camera to say we are ready cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,"Initialized"); + boost::filesystem::copy_file( "/home/jonesc/Rich1GasCKThetaResolutions.txt", + "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); + boost::filesystem::copy_file( "/home/jonesc/Rich2GasCKThetaResolutions.txt", + "/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt" ); + m_inInit = false; return sc; } @@ -331,11 +336,8 @@ OMARichRefIndex::runCalibration( const std::string& type, // Draw to canvas draw( radHist ); - // Is the fit ok - bool fitOK = false; - - // save fitted CK resolution - double ckRes = 0; + // save fit result; + FitResult savedFitResult; double scale = 1.0 ; if ( checkCKThetaStats(radHist) ) @@ -346,8 +348,7 @@ OMARichRefIndex::runCalibration( const std::string& type, const auto fitresult = fitCKThetaHistogram( radHist, rad, m_nPolFull ); if ( fitresult.fitOK ) { - fitOK = true; - ckRes = fitresult.ckResolution; + savedFitResult = fitresult; m_cachedCalibCount[rad] = 0; // Normal calibration, so reset count to 0 scale = nScaleFromShift( fitresult.ckShift, rad ); std::ostringstream mess; @@ -392,7 +393,8 @@ OMARichRefIndex::runCalibration( const std::string& type, } // if a final OK calibration, write to CK resolution summary - if ( fitOK && isFinal ) { writeCKThetaLog( rad, ckRes, runNumber ); } + if ( savedFitResult.fitOK && isFinal ) + { writeCKThetaLog( rad, savedFitResult, runNumber ); } // publish results. Only if histogram did not have 0 entries if ( 0 != radHist->GetEntries() && @@ -685,7 +687,9 @@ OMARichRefIndex::fitCKThetaHistogram( TH1* hist, // return final fit parameter for shift return FitResult( fitOK, fitOK ? bestFitF.GetParameter(1) : 0.0, - fitOK ? bestFitF.GetParameter(2) : 0.0 ); + fitOK ? bestFitF.GetParError(1) : 0.0, + fitOK ? bestFitF.GetParameter(2) : 0.0, + fitOK ? bestFitF.GetParError(2) : 0.0 ); } //============================================================================= @@ -1000,7 +1004,7 @@ bool OMARichRefIndex::writeToDimSummaryFile( const std::string & mess ) const //============================================================================= bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, - const double ckThetaRes, + const FitResult& fitResult, const unsigned int runNumber ) const { bool ok = true; @@ -1016,7 +1020,9 @@ bool OMARichRefIndex::writeCKThetaLog( const std::string& rad, if ( file.is_open() ) { // write out the result for this run - file << runNumber << " " << m_fileTime << " " << ckThetaRes << std::endl; + file << runNumber << " " << m_fileTime << " " + << fitResult.ckResolution << " " << fitResult.ckResolutionErr + << std::endl; // close the file file.close(); } diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.h b/Rich/RichOnlineCalib/src/OMARichRefIndex.h index 93b165892..62cfb0023 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.h +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.h @@ -69,14 +69,21 @@ private: class FitResult { public: + FitResult() = default; FitResult( const bool ok, const double shift, - const double res ) - : fitOK(ok), ckShift(shift), ckResolution(res) { } + const double shifterr, + const double res, + const double reserr ) + : fitOK(ok), + ckShift(shift), ckShiftErr(shifterr), + ckResolution(res), ckResolutionErr(reserr) { } public: bool fitOK{false}; double ckShift{0}; + double ckShiftErr{0}; double ckResolution{0}; + double ckResolutionErr{0}; }; private: @@ -318,7 +325,7 @@ private: /// Write to the CK theta resolution summary log bool writeCKThetaLog( const std::string& rad, - const double ckThetaRes, + const FitResult& fitResult, const unsigned int runNumber ) const; private: -- GitLab From de9c38836343be9cb0f61feed7cadd70a3a31571 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 15:56:42 +0100 Subject: [PATCH 14/37] add fit errors to CK theta summary file --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 679a72906..070310846 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -129,6 +129,8 @@ StatusCode OMARichRefIndex::initialize() // send a message to camera to say we are ready cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,"Initialized"); + removeFile("/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt"); + removeFile("/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt"); boost::filesystem::copy_file( "/home/jonesc/Rich1GasCKThetaResolutions.txt", "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); boost::filesystem::copy_file( "/home/jonesc/Rich2GasCKThetaResolutions.txt", -- GitLab From 47e5df31f7dde07808d9ac8b0e55d3f0449a2442 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Wed, 15 Jun 2016 16:02:56 +0100 Subject: [PATCH 15/37] remove temporary file copy lines --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 070310846..185d140d5 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -129,12 +129,12 @@ StatusCode OMARichRefIndex::initialize() // send a message to camera to say we are ready cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,"Initialized"); - removeFile("/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt"); - removeFile("/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt"); - boost::filesystem::copy_file( "/home/jonesc/Rich1GasCKThetaResolutions.txt", - "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); - boost::filesystem::copy_file( "/home/jonesc/Rich2GasCKThetaResolutions.txt", - "/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt" ); + // removeFile("/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt"); + // removeFile("/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt"); + // boost::filesystem::copy_file( "/home/jonesc/Rich1GasCKThetaResolutions.txt", + // "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); + // boost::filesystem::copy_file( "/home/jonesc/Rich2GasCKThetaResolutions.txt", + // "/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt" ); m_inInit = false; return sc; -- GitLab From 7b57f9ce9b3fe45934d6b81bf79d276b73fd9321 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Thu, 16 Jun 2016 09:07:00 +0100 Subject: [PATCH 16/37] clean up initialize() --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 185d140d5..1ae59c088 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -86,6 +86,7 @@ OMARichRefIndex::~OMARichRefIndex() {} //============================================================================= StatusCode OMARichRefIndex::initialize() { + // Set the flag to indicate we are in the initalize() call m_inInit = true; // ROOT style for PDFs @@ -94,10 +95,14 @@ StatusCode OMARichRefIndex::initialize() StatusCode sc = AnalysisTask::initialize(); if ( sc.isFailure() ) return sc; - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + // Sometimes its neccessary to perform some file system operations + // Do them here as then they run as Online and have full file permissions... + // Keep lines ehre just as future examples ... + // removeFile("/group/online/alignment/ABC.txt"); + // boost::filesystem::copy_file( "/home/jonesc/ABC.txt", + // "/group/online/alignment/ABC.txt" ); - // write to summary file - writeToDimSummaryFile( m_Name + " Initialized" ); + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; // Fix file permissions ... //fixFilePermissions(); @@ -115,28 +120,27 @@ StatusCode OMARichRefIndex::initialize() sc = serviceLocator()->service("LHCb::PublishSvc",m_pPublishSvc,false); if ( sc.isSuccess() && m_pPublishSvc ) { - info() << "PublishSvc initialized" << endmsg; m_pPublishSvc->declarePubItem( m_Rich1TaskName, m_Rich1PubString ); m_pPublishSvc->declarePubItem( m_Rich2TaskName, m_Rich2PubString ); m_pPublishSvc->declarePubItem( m_Rich1ScaleTaskName, m_Rich1RefIndex ); m_pPublishSvc->declarePubItem( m_Rich2ScaleTaskName, m_Rich2RefIndex ); + info() << "PublishSvc initialized" << endmsg; } } // reset the cached histogram stats m_histStats.clear(); + // write to summary file + writeToDimSummaryFile( m_Name + " Initialized" ); + // send a message to camera to say we are ready cameraTool()->SendAndClearTS(ICameraTool::INFO,m_Name,"Initialized"); - // removeFile("/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt"); - // removeFile("/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt"); - // boost::filesystem::copy_file( "/home/jonesc/Rich1GasCKThetaResolutions.txt", - // "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); - // boost::filesystem::copy_file( "/home/jonesc/Rich2GasCKThetaResolutions.txt", - // "/group/online/alignment/RichCalibSummaries/Rich2GasCKThetaResolutions.txt" ); - + // turn off the initialize flag m_inInit = false; + + // return return sc; } -- GitLab From d92b80ace4677f5783cd1019d5c63ed4c3fdcb4c Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Fri, 17 Jun 2016 11:38:30 +0100 Subject: [PATCH 17/37] options update --- Rich/Panoptes/options/RichDAQMon.py | 13 ++++++++----- Rich/Panoptes/options/RichOnlineCalib_Offline.py | 11 ++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Rich/Panoptes/options/RichDAQMon.py b/Rich/Panoptes/options/RichDAQMon.py index e598d35a4..8ffd1cc4b 100644 --- a/Rich/Panoptes/options/RichDAQMon.py +++ b/Rich/Panoptes/options/RichDAQMon.py @@ -4,14 +4,18 @@ @author M.Frank """ __version__ = "$Id: RichDAQMon.py,v 1.25 2009-11-27 11:21:21 ukerzel Exp $" -__author__ = "Markus Frank <Markus.Frank@cern.ch>" +__author__ = "Chris Jones <christopher.rob.jones@cern.ch" import os, sys from Panoptes.Configuration import * +# What partition partition = os.getenv('PARTITION','') + +# Online conditions path importpath = "/group/online/dataflow/options/"+partition+"/RECONSTRUCTION" Panoptes().UseConditionsMap = False +# ... if it exists, use it... if os.path.exists(importpath) : sys.path.insert(0,importpath) Panoptes().UseConditionsMap = True @@ -25,8 +29,7 @@ import glob def start(mode='Online'): """ Finish configuration and configure Gaudi application manager - - @author M.Frank + @author C.Jones """ print "Mode %s" % mode @@ -48,10 +51,10 @@ def start(mode='Online'): # override CondDBTag with the one provided by the Online environment? # -> n.b. only works in "online" or "calibration" mode, setting ignored otherwise - Panoptes().UseOnlineCondDBtag = False + Panoptes().UseOnlineCondDBtag = False # connect to ORACLE conditionsDB - Panoptes().UseOracle = False + Panoptes().UseOracle = False # Ignore the heart beat when not using oracle. if not Panoptes().UseOracle: diff --git a/Rich/Panoptes/options/RichOnlineCalib_Offline.py b/Rich/Panoptes/options/RichOnlineCalib_Offline.py index 058b70e9d..2e269dcae 100644 --- a/Rich/Panoptes/options/RichOnlineCalib_Offline.py +++ b/Rich/Panoptes/options/RichOnlineCalib_Offline.py @@ -19,12 +19,13 @@ def setup(): # Input files. Check what is available... searchPaths = [ - "/hist/Savesets/2015/LHCb/Brunel/09/15/", # At the pit - "/usera/jonesc/NFS/data/Savesets/", # Cambridge - "/mnt/shared/chris/LHCb/Savesets/" # CRJ CernVM + "/hist/Savesets/2016/LHCb/Brunel/", # At the pit + "/usera/jonesc/NFS/data/Savesets/", # Cambridge + "/mnt/shared/chris/LHCb/Savesets/" # CRJ CernVM ] for path in searchPaths : - RefIndexAlg.InputFiles += sorted(glob.glob(path+"*EOR.root")) + RefIndexAlg.InputFiles += sorted(glob.glob(path+"*/*/*EOR.root")) + #print RefIndexAlg.InputFiles RefIndexAlg.xmlFilePath = "/tmp/HPDCalib" RefIndexAlg.DisableDIMPublish = True @@ -36,7 +37,7 @@ def setup(): RichOnCalibSeq.IgnoreFilterPassed = True # Output Level of both - RefIndexAlg.OutputLevel = 2 + #RefIndexAlg.OutputLevel = 2 #HPDImageAlg.OutputLevel = 3 # Camera setup -- GitLab From db2079ac3e14d10b158492694efc18f864dec6c2 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Fri, 17 Jun 2016 20:05:35 +0200 Subject: [PATCH 18/37] Add file copy method --- Rich/RichOnlineCalib/src/OMARichRefIndex.cpp | 7 +++---- Rich/RichOnlineCalib/src/OMARichRefIndex.h | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp index 6a20663b1..46bfa2a3f 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.cpp @@ -86,10 +86,9 @@ StatusCode OMARichRefIndex::initialize() // Sometimes its neccessary to perform some file system operations // Do them here as then they run as Online and have full file permissions... - // Keep lines ehre just as future examples ... - // removeFile("/group/online/alignment/ABC.txt"); - // boost::filesystem::copy_file( "/home/jonesc/ABC.txt", - // "/group/online/alignment/ABC.txt" ); + // Keep lines here just as future examples ... + //copyFile( "/home/jonesc/Rich1GasCKThetaResolutions.txt", + // "/group/online/alignment/RichCalibSummaries/Rich1GasCKThetaResolutions.txt" ); if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; diff --git a/Rich/RichOnlineCalib/src/OMARichRefIndex.h b/Rich/RichOnlineCalib/src/OMARichRefIndex.h index 94d891b7f..ec02a5ff6 100644 --- a/Rich/RichOnlineCalib/src/OMARichRefIndex.h +++ b/Rich/RichOnlineCalib/src/OMARichRefIndex.h @@ -294,6 +294,22 @@ private: boost::filesystem::remove(file); } } + + /// Copy a file + template < class FILEFROM, class FILETO > + inline void copyFile( const FILEFROM & from, + const FILETO & to ) const + { + if ( boost::filesystem::exists(from) ) + { + std::ostringstream mess; + mess << "Copying " << from << " ->" << to; + info() << mess.str() << endmsg; + cameraTool()->Append("TEXT",mess.str()); + removeFile(to); + boost::filesystem::copy_file(from,to); + } + } /// Create directory template < class DIR > -- GitLab From 147722239573a0198f9bc0e7d016bbdc9445f478 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Mon, 20 Jun 2016 15:50:43 +0200 Subject: [PATCH 19/37] Add info message to HPD disable tool whenever the DIM string changes --- .../src/component/HpdUkL1DisableTool.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp index ce2af6af4..b136b6ca4 100755 --- a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp +++ b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp @@ -5,7 +5,7 @@ //----------------------------------------------------------------------------- // Implementation file for class : HpdUkL1DisableTool // -// 2008-06-30 : Ulrich Kerzelh +// 2008-06-30 : Ulrich Kerzel //----------------------------------------------------------------------------- using namespace Rich::Mon; @@ -306,7 +306,10 @@ void HpdUkL1DisableTool::ResetAll() m_zeroWeightHPDsV.clear(); if ( m_HPDDisableDimService ) - { m_HPDDisableDimService->updateService( (char*)"" ); } + { + info() << "Reset HPD Disable DIM string to empty" << endmsg; + m_HPDDisableDimService->updateService( (char*)"" ); + } ResetDIMStrings(); @@ -488,9 +491,11 @@ void HpdUkL1DisableTool::DisableAndPublish() m_CamTool->SendAndClearTS( ICameraTool::ERROR , m_Name, mess.str(), ICameraTool::ERROR_PVSS, m_Name, "HPD automatically disabled" ); - _ri_verbo << "Update DIM service with " << m_DisabledHpdString << endmsg; if ( m_HPDDisableDimService ) - { m_HPDDisableDimService->updateService( (char*) m_DisabledHpdString.c_str() ); } + { + info() << "Update HPD Disable DIM service with '" << m_DisabledHpdString << "'" << endmsg; + m_HPDDisableDimService->updateService( (char*) m_DisabledHpdString.c_str() ); + } } else { @@ -1033,7 +1038,10 @@ void HpdUkL1DisableTool::RemoveOldDisables() // Update the DIM string if ( m_HPDDisableDimService ) - { m_HPDDisableDimService->updateService( (char*) m_DisabledHpdString.c_str() ); } + { + info() << "Update HPD Disable DIM service with '" << m_DisabledHpdString << "'" << endmsg; + m_HPDDisableDimService->updateService( (char*) m_DisabledHpdString.c_str() ); + } } -- GitLab From c3b386de48127ddf3f818a41b6c043589b8a1ee7 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Mon, 20 Jun 2016 15:51:26 +0200 Subject: [PATCH 20/37] reduce missing HPD check time period from 100k to 20k events --- Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp index 8253eb972..ce0867c9d 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp @@ -17,8 +17,8 @@ MissingHPDMonitor::MissingHPDMonitor( const std::string& name, { declareProperty( "RawEventLocations", m_taeEvents ); declareProperty( "HPDCheckFreq", m_checkFreq = 1000 ); - declareProperty( "MaxMissingEvents", m_maxMissingEvents = 100000 ); - declareProperty( "VetoNoBias" , m_vetoNoBias = true ); + declareProperty( "MaxMissingEvents", m_maxMissingEvents = 20000 ); + declareProperty( "VetoNoBias" , m_vetoNoBias = true ); // Partition const char* partitionName = getenv("PARTITION"); -- GitLab From 721c7e0b5fb1843b2adcfcda60ae6e4f2174f83f Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 01:55:47 +0200 Subject: [PATCH 21/37] added Det/DetCond from LHCb (LHCb/2016-patches) --- .git-lb-checkout | 3 + Det/DetCond/CMakeLists.txt | 37 + Det/DetCond/DetCond/CondDBGenericCnv.h | 126 ++ Det/DetCond/DetCond/ICOOLConfSvc.h | 36 + Det/DetCond/DetCond/ICondDBAccessSvc.h | 108 ++ Det/DetCond/DetCond/ICondDBEditor.h | 75 + Det/DetCond/DetCond/ICondDBReader.h | 110 ++ Det/DetCond/cmt/requirements | 79 + Det/DetCond/doc/release.notes | 1247 ++++++++++++++ Det/DetCond/options/UseOracle.py | 3 + Det/DetCond/python/DetCond/Configuration.py | 788 +++++++++ Det/DetCond/python/DetCond/HistoCond.py | 104 ++ Det/DetCond/python/DetCond/__init__.py | 0 Det/DetCond/src/Lib/CondDBGenericCnv.cpp | 139 ++ Det/DetCond/src/component/COOLConfSvc.cpp | 281 ++++ Det/DetCond/src/component/COOLConfSvc.h | 94 ++ Det/DetCond/src/component/CondDBAccessSvc.cpp | 1492 +++++++++++++++++ Det/DetCond/src/component/CondDBAccessSvc.h | 506 ++++++ Det/DetCond/src/component/CondDBCache.cpp | 444 +++++ Det/DetCond/src/component/CondDBCache.h | 279 +++ Det/DetCond/src/component/CondDBCnvSvc.cpp | 197 +++ Det/DetCond/src/component/CondDBCnvSvc.h | 123 ++ Det/DetCond/src/component/CondDBCommon.cpp | 90 + Det/DetCond/src/component/CondDBCommon.h | 29 + Det/DetCond/src/component/CondDBDQScanner.cpp | 147 ++ Det/DetCond/src/component/CondDBDQScanner.h | 56 + .../src/component/CondDBDispatcherSvc.cpp | 294 ++++ .../src/component/CondDBDispatcherSvc.h | 109 ++ .../src/component/CondDBLayeringSvc.cpp | 288 ++++ Det/DetCond/src/component/CondDBLayeringSvc.h | 103 ++ Det/DetCond/src/component/CondDBLogger.cpp | 250 +++ Det/DetCond/src/component/CondDBLogger.h | 147 ++ Det/DetCond/src/component/CondDBReplayAlg.cpp | 162 ++ Det/DetCond/src/component/CondDBReplayAlg.h | 60 + .../src/component/CondDBSQLiteCopyAccSvc.cpp | 135 ++ .../src/component/CondDBSQLiteCopyAccSvc.h | 55 + .../src/component/CondDBTimeSwitchSvc.cpp | 363 ++++ .../src/component/CondDBTimeSwitchSvc.h | 198 +++ Det/DetCond/src/component/IOVListHelpers.cpp | 23 + Det/DetCond/src/component/IOVListHelpers.h | 10 + Det/DetCond/src/component/LoadDDDB.cpp | 101 ++ Det/DetCond/src/component/LoadDDDB.h | 35 + Det/DetCond/src/component/RelyConverter.cpp | 479 ++++++ Det/DetCond/src/component/RelyConverter.h | 148 ++ Det/DetCond/src/component/RunStampCheck.cpp | 140 ++ Det/DetCond/src/dict/DetCondDict.h | 38 + Det/DetCond/src/dict/DetCondDict.xml | 14 + Det/DetCond/tests/data/DQFLAGS.db | Bin 0 -> 48128 bytes Det/DetCond/tests/data/HBTEST.db | Bin 0 -> 76800 bytes Det/DetCond/tests/data/RSTEST.db | Bin 0 -> 48128 bytes Det/DetCond/tests/data/TESTDB0.db | Bin 0 -> 183296 bytes Det/DetCond/tests/data/TESTDB1.db | Bin 0 -> 79872 bytes Det/DetCond/tests/data/TESTDB2.db | Bin 0 -> 79872 bytes Det/DetCond/tests/data/TESTDB3.db | Bin 0 -> 183296 bytes Det/DetCond/tests/data/genDQFLAGS.py | 39 + Det/DetCond/tests/data/genHBTEST.py | 48 + Det/DetCond/tests/data/genRSTEST.py | 32 + .../tests/qmtest/detcond.qms/bug_80076.qmt | 60 + .../qmtest/detcond.qms/check_db_reading.qmt | 4 + .../detcond.qms/configuration_module.qmt | 4 + .../qmtest/detcond.qms/connection_timeout.qmt | 11 + .../detcond.qms/direct_mapping_altern1.qmt | 22 + .../detcond.qms/direct_mapping_altern2.qmt | 25 + .../detcond.qms/direct_mapping_altern3.qmt | 23 + .../detcond.qms/direct_mapping_base.qmt | 19 + .../detcond.qms/direct_mapping_layers.qmt | 27 + .../detcond.qms/dqscanner.qms/basic.qmt | 63 + .../qmtest/detcond.qms/force_disconnect.qmt | 20 + .../qmtest/detcond.qms/get_iovs.qms/basic.qmt | 4 + .../tests/qmtest/detcond.qms/granularity.qmt | 79 + .../tests/qmtest/detcond.qms/heart_beat.qmt | 105 ++ .../qmtest/detcond.qms/missing_condition.qmt | 35 + .../tests/qmtest/detcond.qms/run_stamp.qmt | 59 + .../tests/qmtest/detcond.qms/time_switch.qmt | 71 + .../qmtest/detcond.qms/update_in_finalize.qmt | 82 + Det/DetCond/tests/scripts/check_db_reading.py | 40 + .../scripts/configuration_module_test.py | 231 +++ .../tests/scripts/connection_timeout.py | 22 + .../tests/scripts/direct_mapping_test.py | 86 + Det/DetCond/tests/scripts/force_disconnect.py | 28 + Det/DetCond/tests/scripts/getIOVs.py | 96 ++ Det/DetCond/tests/src/DQScanTest.cpp | 106 ++ Det/DetCond/tests/src/DQScanTest.h | 51 + Det/DetCond/tests/src/TestConditionAlg.cpp | 287 ++++ 84 files changed, 11524 insertions(+) create mode 100644 .git-lb-checkout create mode 100644 Det/DetCond/CMakeLists.txt create mode 100755 Det/DetCond/DetCond/CondDBGenericCnv.h create mode 100755 Det/DetCond/DetCond/ICOOLConfSvc.h create mode 100755 Det/DetCond/DetCond/ICondDBAccessSvc.h create mode 100755 Det/DetCond/DetCond/ICondDBEditor.h create mode 100755 Det/DetCond/DetCond/ICondDBReader.h create mode 100755 Det/DetCond/cmt/requirements create mode 100755 Det/DetCond/doc/release.notes create mode 100644 Det/DetCond/options/UseOracle.py create mode 100755 Det/DetCond/python/DetCond/Configuration.py create mode 100644 Det/DetCond/python/DetCond/HistoCond.py create mode 100644 Det/DetCond/python/DetCond/__init__.py create mode 100755 Det/DetCond/src/Lib/CondDBGenericCnv.cpp create mode 100755 Det/DetCond/src/component/COOLConfSvc.cpp create mode 100755 Det/DetCond/src/component/COOLConfSvc.h create mode 100755 Det/DetCond/src/component/CondDBAccessSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBAccessSvc.h create mode 100755 Det/DetCond/src/component/CondDBCache.cpp create mode 100755 Det/DetCond/src/component/CondDBCache.h create mode 100755 Det/DetCond/src/component/CondDBCnvSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBCnvSvc.h create mode 100755 Det/DetCond/src/component/CondDBCommon.cpp create mode 100755 Det/DetCond/src/component/CondDBCommon.h create mode 100644 Det/DetCond/src/component/CondDBDQScanner.cpp create mode 100644 Det/DetCond/src/component/CondDBDQScanner.h create mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.h create mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.h create mode 100755 Det/DetCond/src/component/CondDBLogger.cpp create mode 100755 Det/DetCond/src/component/CondDBLogger.h create mode 100755 Det/DetCond/src/component/CondDBReplayAlg.cpp create mode 100755 Det/DetCond/src/component/CondDBReplayAlg.h create mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h create mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.h create mode 100644 Det/DetCond/src/component/IOVListHelpers.cpp create mode 100644 Det/DetCond/src/component/IOVListHelpers.h create mode 100755 Det/DetCond/src/component/LoadDDDB.cpp create mode 100755 Det/DetCond/src/component/LoadDDDB.h create mode 100755 Det/DetCond/src/component/RelyConverter.cpp create mode 100755 Det/DetCond/src/component/RelyConverter.h create mode 100644 Det/DetCond/src/component/RunStampCheck.cpp create mode 100755 Det/DetCond/src/dict/DetCondDict.h create mode 100755 Det/DetCond/src/dict/DetCondDict.xml create mode 100644 Det/DetCond/tests/data/DQFLAGS.db create mode 100644 Det/DetCond/tests/data/HBTEST.db create mode 100644 Det/DetCond/tests/data/RSTEST.db create mode 100755 Det/DetCond/tests/data/TESTDB0.db create mode 100755 Det/DetCond/tests/data/TESTDB1.db create mode 100755 Det/DetCond/tests/data/TESTDB2.db create mode 100755 Det/DetCond/tests/data/TESTDB3.db create mode 100644 Det/DetCond/tests/data/genDQFLAGS.py create mode 100644 Det/DetCond/tests/data/genHBTEST.py create mode 100755 Det/DetCond/tests/data/genRSTEST.py create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt create mode 100755 Det/DetCond/tests/scripts/check_db_reading.py create mode 100755 Det/DetCond/tests/scripts/configuration_module_test.py create mode 100644 Det/DetCond/tests/scripts/connection_timeout.py create mode 100755 Det/DetCond/tests/scripts/direct_mapping_test.py create mode 100644 Det/DetCond/tests/scripts/force_disconnect.py create mode 100755 Det/DetCond/tests/scripts/getIOVs.py create mode 100644 Det/DetCond/tests/src/DQScanTest.cpp create mode 100644 Det/DetCond/tests/src/DQScanTest.h create mode 100755 Det/DetCond/tests/src/TestConditionAlg.cpp diff --git a/.git-lb-checkout b/.git-lb-checkout new file mode 100644 index 000000000..5acc14dc1 --- /dev/null +++ b/.git-lb-checkout @@ -0,0 +1,3 @@ +[lb-checkout "LHCb.Det/DetCond"] + base = c3b386de48127ddf3f818a41b6c043589b8a1ee7 + imported = 00b37002d748170a320ef743cb30b53f871a898a diff --git a/Det/DetCond/CMakeLists.txt b/Det/DetCond/CMakeLists.txt new file mode 100644 index 000000000..4f314aebe --- /dev/null +++ b/Det/DetCond/CMakeLists.txt @@ -0,0 +1,37 @@ +################################################################################ +# Package: DetCond +################################################################################ +gaudi_subdir(DetCond v12r47) + +gaudi_depends_on_subdirs(Det/DetDesc + GaudiAlg + GaudiKernel + Kernel/LHCbKernel) + +find_package(Boost COMPONENTS system thread filesystem) +find_package(COOL COMPONENTS CoolKernel CoolApplication) +find_package(CORAL COMPONENTS CoralBase CoralKernel RelationalAccess) + +gaudi_add_library(DetCondLib + src/Lib/*.cpp + PUBLIC_HEADERS DetCond + INCLUDE_DIRS Boost COOL CORAL + LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel) + +gaudi_add_module(DetCond + src/component/*.cpp + tests/src/*.cpp + INCLUDE_DIRS Boost COOL CORAL + LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib) + +gaudi_add_dictionary(DetCond + src/dict/DetCondDict.h + src/dict/DetCondDict.xml + INCLUDE_DIRS Boost COOL CORAL + LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib + OPTIONS "-U__MINGW32__") + +gaudi_install_python_modules() + + +gaudi_add_test(QMTest QMTEST) diff --git a/Det/DetCond/DetCond/CondDBGenericCnv.h b/Det/DetCond/DetCond/CondDBGenericCnv.h new file mode 100755 index 000000000..08f112058 --- /dev/null +++ b/Det/DetCond/DetCond/CondDBGenericCnv.h @@ -0,0 +1,126 @@ +#ifndef DETCOND_CONDDBGENERICCNV_H +#define DETCOND_CONDDBGENERICCNV_H 1 + +// Include files +#include <string> +#include <functional> + +#include "GaudiKernel/Converter.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +#include "DetCond/ICondDBReader.h" + +#include "CoolKernel/types.h" + +// Forward and external declarations +class ISvcLocator; +class IDetDataSvc; +class DataObject; + +template <class TYPE> class CnvFactory; + +/** @class CondDBGenericCnv CondDBGenericCnv.h DetCond/CondDBGenericCnv.h + * + * Generic converter for the CondDBCnvSvc. This generic converter + * provides common functions to access the CondDB in order to make it + * easier to write specific converters. + * + * @author Marco CLEMENCIC + * @date December 2004 + */ +class CondDBGenericCnv: public Converter { +public: + /** + * Initializes the converter. + * Here the pointers to common services are taken: + * <ul> + * <li> CondDBCnvSvc + * <li> DetectorDataSvc + * </ul> + * @return status depending on the completion of the call + */ + virtual StatusCode initialize(); + + /** + * Finalizes the converter. + * It releases the pointers to the taken services. + * @return status depending on the completion of the call + */ + virtual StatusCode finalize(); + + /** + * Accessor to the StorageType value + * @return the storage type for this object + */ + static long storageType() { + return CONDDB_StorageType; + } + + /** + * Accessor to the StorageType value + * @return the storage type for this object + */ + virtual long repSvcType() const { + return CONDDB_StorageType; + } + +protected: + + /// Standard constructor + CondDBGenericCnv(ISvcLocator* svc,const CLID& clid); + + virtual ~CondDBGenericCnv( ); ///< Destructor + + /** + * Ask to the DetectorDataSvc the curren event time. + * @return StatusCode::SUCCESS if the event time was defined. + */ + StatusCode eventTime(Gaudi::Time &time) const; + + /** + * Set the validity of the DataObject if it inherits from IValidity. + */ + void setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject); + + /// Pointer to the DetectorDataService. + SmartIF<IDetDataSvc> m_detDataSvc; + /// Pointer to the ICondDBReader interface; + SmartIF<ICondDBReader> m_condDBReader; + + /** + * Get an object from the Conditions DB. It tries all the CondDBReaders + * known by CondDBCnvSvc before returing a failure code. + * @param[in] path the path inside the CondDB + * @param[in] channel CondDB channel id + * @param[out] obj shared pointer to the COOL object + * @param[out] descr folder description string (used to know the storage type by RelyConverter) + * @param[out] since start of the IOV + * @param[out] until end of the IOV + * The IOV is inside the object itself as two cool::ValidityKey, the since and until are + * used to avoid the conversion outside this method.<BR> + * If the path point to a FolderSet, channel is ignored and the boost::shared_ptr obj is + * set to NULL. + */ + StatusCode getObject(const std::string &path, const cool::ChannelId &channel, + ICondDBReader::DataPtr &obj, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until); + + /// Method kept for backward compatibility + inline StatusCode getObject(const std::string &path, + ICondDBReader::DataPtr &obj, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until) + { + return getObject(path,0,obj,descr,since,until); + } + + /// Find the children nodes of a given FolderSet path. + /// When using multiple databases, only the first one which contains + /// this folderset is used, so it must have at least dummy entries for each sub-node + /// (to be changed in the future). + StatusCode getChildNodes(const std::string &path,std::vector<std::string> &node_names); + +private: + +}; +#endif // DETCOND_CONDDBGENERICCNV_H diff --git a/Det/DetCond/DetCond/ICOOLConfSvc.h b/Det/DetCond/DetCond/ICOOLConfSvc.h new file mode 100755 index 000000000..5636805cf --- /dev/null +++ b/Det/DetCond/DetCond/ICOOLConfSvc.h @@ -0,0 +1,36 @@ +#ifndef DETCOND_ICOOLCONFSVC_H +#define DETCOND_ICOOLCONFSVC_H 1 + +// Include files +#include <GaudiKernel/IInterface.h> + +// Forward declarations +namespace coral { + class IConnectionService; +} +namespace cool { + class IDatabaseSvc; +} + +/** @class ICOOLConfSvc ICOOLConfSvc.h DetCond/ICOOLConfSvc.h + * + * Class used as interface to instantiate a COOL application and configure it + * (and CORAL). + * + * @author Marco CLEMENCIC + * @date 2007-12-07 + */ +class ICOOLConfSvc : virtual public IInterface { +public: + /// InterfaceID + DeclareInterfaceID(ICOOLConfSvc, 3, 0); + + /// Access to the CORAL connection service used by COOL (if needed). + virtual coral::IConnectionService& connectionSvc() = 0; + + /// Get the COOL Database service (used to connect to the databases). + virtual cool::IDatabaseSvc& databaseSvc() = 0; + +}; + +#endif // DETCOND_ICOOLCONFSVC_H diff --git a/Det/DetCond/DetCond/ICondDBAccessSvc.h b/Det/DetCond/DetCond/ICondDBAccessSvc.h new file mode 100755 index 000000000..85ae8d611 --- /dev/null +++ b/Det/DetCond/DetCond/ICondDBAccessSvc.h @@ -0,0 +1,108 @@ +#ifndef DETCOND_ICONDDBACCESSSVC_H +#define DETCOND_ICONDDBACCESSSVC_H 1 + +// Include files +// from STL +#include <string> +#include <vector> +#include <set> +#include <map> + +// from Gaudi +#include <GaudiKernel/IInterface.h> + +// from COOL +#include "CoolKernel/types.h" +#include "CoolKernel/ChannelId.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/ValidityKey.h" + +// Forward declarations +namespace Gaudi { + class Time; +} +namespace cool { + class IRecord; + class IRecordSpecification; +} + +/** @class ICondDBAccessSvc ICondDBAccessSvc.h DetCond/ICondDBAccessSvc.h + * + * Class used as interface to LCG COOL library API. It should expose as less as + * possible COOL internal details. + * + * CondDBAccessSvc can be operated with only an in-memory CondDB, setting both the options NoBD and useCache to true. The memory + * database can be populated using cacheAddFolder and cacheAddObject (or their XML counter parts). The CondDB folders of the + * memory db are equivalent to COOL single-version folders (see COOL documentation for details). + * + * @author Marco CLEMENCIC + * @date 2005-01-11 + */ +class ICondDBAccessSvc : virtual public IInterface { +public: + /// InterfaceID + DeclareInterfaceID(ICondDBAccessSvc, 2, 0); + + /// Used to obtain direct access to the database. + virtual cool::IDatabasePtr& database() = 0; + + /// Convert from Gaudi::Time class to cool::ValidityKey. + virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const = 0; + + /// Convert from cool::ValidityKey to Gaudi::Time class. + virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const = 0; + + /// Return the currently set TAG to use. + virtual const std::string &tag() const = 0; + + /// Set the TAG to use. + virtual StatusCode setTag(const std::string &_tag) = 0; + + /// Return the connection string used to connect to the database. + virtual const std::string &connectionString() const = 0; + + /// Add a folder to the cache (bypass the DB) + virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec) = 0; + + /// Add a folder-set to the cache (bypass the DB) + virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr) = 0; + + /// Add an XML folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path) = 0; + + /// Add an XML folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) = 0; + + /// Add an object to the cache (bypass the DB) + virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const cool::IRecord &payload, cool::ChannelId channel = 0) = 0; + + /// Deprecated: use ICondDBAccessSvc::cacheAddXMLData instead + inline StatusCode cacheAddXMLObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string &data, cool::ChannelId channel = 0) + { + return cacheAddXMLData(path, since, until, data, channel); + } + + + /// Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string &data, cool::ChannelId channel = 0) = 0; + + /// Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::map<std::string,std::string> &data, cool::ChannelId channel = 0) = 0; + + /// Clear the cache + virtual void clearCache() = 0; + + /// Dump the cache (debug) + virtual void dumpCache() const = 0; + +protected: + +private: + +}; +#endif // DETCOND_ICONDDBACCESSSVC_H diff --git a/Det/DetCond/DetCond/ICondDBEditor.h b/Det/DetCond/DetCond/ICondDBEditor.h new file mode 100755 index 000000000..0edce1b8b --- /dev/null +++ b/Det/DetCond/DetCond/ICondDBEditor.h @@ -0,0 +1,75 @@ +#ifndef DETCOND_ICONDDBEDITOR_H +#define DETCOND_ICONDDBEDITOR_H 1 + +// Include files +// from STL +#include <string> +#include <map> +#include <set> + +// from Gaudi +#include "GaudiKernel/IInterface.h" + +// from COOL +#include "CoolKernel/types.h" +#include "CoolKernel/ChannelId.h" + +/** @class ICondDBEditor ICondDBEditor.h DetCond/ICondDBEditor.h + * + * + * @author Marco CLEMENCIC + * @date 2006-07-10 + */ +class ICondDBEditor : virtual public IInterface { +public: + /// InterfaceID + DeclareInterfaceID(ICondDBEditor, 2, 0); + + /// Possible recognized node types. + enum StorageType { FOLDERSET, XML, Native }; + /// Known types of leaf nodes (aka Folders). + enum VersionMode { SINGLE, MULTI }; + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + StorageType storage = XML, + VersionMode vers = MULTI) const = 0; + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + const std::set<std::string> &fields, + StorageType storage = XML, + VersionMode vers = MULTI) const = 0; + + /// Deprecated: use ICondDBEditor::storeXMLData instead. + inline StatusCode storeXMLString(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const + { + return storeXMLData(path, data, since, until, channel); + } + + /// Utility function that simplifies the storage of an XML string. + virtual StatusCode storeXMLData(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; + + /// Utility function that simplifies the storage of a set of XML strings. + virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; + + /// Tag the given leaf node with the given tag-name. + virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, + const std::string &description = "") = 0; + + /// Tag the given middle node with the given tag-name, recursively tagging the head + /// of child nodes with automatically generated tag-names. + virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, + const std::string &description = "") = 0; + +protected: + +private: + +}; +#endif // DETCOND_ICONDDBEDITOR_H diff --git a/Det/DetCond/DetCond/ICondDBReader.h b/Det/DetCond/DetCond/ICondDBReader.h new file mode 100755 index 000000000..0131d2e01 --- /dev/null +++ b/Det/DetCond/DetCond/ICondDBReader.h @@ -0,0 +1,110 @@ +#ifndef DETCOND_ICONDDBREADER_H +#define DETCOND_ICONDDBREADER_H 1 + +// Include files +// from STL +#include <string> + +// from Gaudi +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/Time.h" + +// from LHCb +#include "Kernel/ICondDBInfo.h" + +// from COOL +#include "CoolKernel/types.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/ChannelId.h" + +// Forward declarations +namespace cool { + class IRecord; +} + +/** @class ICondDBReader ICondDBReader.h DetCond/ICondDBReader.h + * + * Interface to retrieve data from the conditions database. + * + * @author Marco Clemencic + * @date 2006-07-10 + */ +class ICondDBReader : virtual public ICondDBInfo { +public: + /// InterfaceID + DeclareInterfaceID(ICondDBReader, 2, 1); + + /// virtual destructor + virtual ~ICondDBReader() {} + +#ifdef COOL_HAS_CPP11 + typedef std::shared_ptr<const cool::IRecord> DataPtr; +#else + typedef boost::shared_ptr<const cool::IRecord> DataPtr; +#endif + + /// Helper class to easily manage an interval of validity as a pair of Gaudi::Time + /// instances. + struct IOV { + /// Constructor + IOV(Gaudi::Time _since = Gaudi::Time::epoch(), + Gaudi::Time _until = Gaudi::Time::max()): + since(_since), until(_until) + {} + /// Boundaries of the interval. + Gaudi::Time since, until; + /// Define a simple order between two IOV instances. + inline bool operator<(const IOV& rhs) const { + return since < rhs.since; + } + }; + + /// List of IOV instances. + typedef std::vector<IOV> IOVList; + + /// Retrieve data from the condition database. + /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0) = 0; + + /// Retrieve data from the condition database. + /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. + /// (Version with alphanumeric channel id) + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) = 0; + + /// @{ + /// Return the list of occupied IOVs in the given path and channel, for the given IOV. + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0) = 0; + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel) = 0; + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names) = 0; + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) = 0; + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path) = 0; + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path) = 0; + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path) = 0; + + /// Disconnect from the database. + virtual void disconnect() = 0; + +protected: + +private: + +}; + +#endif // DETCOND_ICONDDBREADER_H diff --git a/Det/DetCond/cmt/requirements b/Det/DetCond/cmt/requirements new file mode 100755 index 000000000..2770d40a8 --- /dev/null +++ b/Det/DetCond/cmt/requirements @@ -0,0 +1,79 @@ +# ==================================================================== +package DetCond +version v12r47 + +# =========== structure =================================================== +branches DetCond doc cmt src + +# =========== dependencies ================================================ +use GaudiKernel v* +use GaudiAlg v* +use COOL v* LCG_Interfaces +use CORAL v* LCG_Interfaces +use Boost v* LCG_Interfaces +use DetDesc v* Det + +# This one is for the interface ICondDBInfo and IDQScanner +use LHCbKernel v* Kernel + +macro_append Boost_linkopts " $(Boost_linkopts_system) " + + +# =========== own includes ================================================ +apply_pattern install_more_includes more=DetCond + +#===================================================================== +# Needed to resolve external symbols +apply_tag NEEDS_COOL_FACTORY +apply_tag NEEDS_CORAL_RELATIONAL_ACCESS +# Work-around for a problem in COOL/CORAL requirements files (after fix to bug #41579) +macro CORAL_linkopts ' $(CORAL_libs) $(CORAL_relacc_libs) ' + +# =============== LCG Dictionary =========================================== +apply_pattern reflex_dictionary \ + dictionary=DetCond \ + headerfiles=$(DETCONDROOT)/src/dict/DetCondDict.h \ + selectionfile=$(DETCONDROOT)/src/dict/DetCondDict.xml \ + options="-U__MINGW32__" +# Disable some compiler warnings in the automatically generated dict code +macro_append DetCondDict_cppflags "" \ + target-icc " -wd2259" + +# =========== constituents ================================================= +library DetCondLib Lib/*.cpp +library DetCond component/*.cpp ../tests/src/*.cpp + +# =========== standard patterns (the order is essential!) ====================== +apply_pattern component_library library=DetCond +apply_pattern linker_library library=DetCondLib + +private +# DetCond Configurable uses the generated configurables +macro_append DetCondGenConfUser_dependencies DetCondConfDbMerge +# Have to look in local DetCondConf.py, install_python has to come later +path_prepend PYTHONPATH ${DETCONDROOT}/genConf +end_private +apply_pattern install_python_modules + +# ==================================================================== +private + +macro_append DetCond_use_linkopts " $(Boost_linkopts_thread) $(Boost_linkopts_filesystem_mt) $(Boost_linkopts_date_time) " + +apply_pattern QMTest +# ===================================== +# Packages needed for tests +macro DetCond_use_CondDBUI "" QMTest "CondDBUI v* Tools" +use $(DetCond_use_CondDBUI) + +macro DetCond_use_DDDB "" QMTest "DDDB v* Det" +use $(DetCond_use_DDDB) + +macro DetCond_use_DetDescSvc "" QMTest "DetDescSvc v* Det" +use $(DetCond_use_DetDescSvc) + +macro DetCond_use_DetDescCnv "" QMTest "DetDescCnv v* Det" +use $(DetCond_use_DetDescCnv) +# ===================================== + +end_private diff --git a/Det/DetCond/doc/release.notes b/Det/DetCond/doc/release.notes new file mode 100755 index 000000000..71d560ebc --- /dev/null +++ b/Det/DetCond/doc/release.notes @@ -0,0 +1,1247 @@ +!----------------------------------------------------------------------------- +! Package : Det/DetCond +! Responsible : Marco Clemencic +! Purpose : Interface between LHCb and LGC/COOL project +!----------------------------------------------------------------------------- + +! 2016-03-31 - Roel Aaij + - Fix CondDB configuration. The online snapshots were configured even if + UseDBSnapshot was set to True. + +!========================= DetCond v12r47 2016-03-18 ========================= +! 2016-03-18 - Roel Aaij + - Remove configuration of environment variables meant to setup access to the + LHCb online oracle instance. This should be done online as part of the + environment. + +!========================= DetCond v12r46 2016-01-27 ========================= +! 2016-01-06 - Gerhard Raven + - prefer SmartIF over raw pointer to interface + +! 2015-12-17 - Christopher Burr + - Prevent CondDBCache from logging " FOUND" as a warning + +!========================= DetCond v12r45 2015-11-23 ========================= +! 2015-11-02 - Gerhard Raven + - pass sink arguments by value, and std::move them + - replace deprecated std::auto_ptr with std::unique_ptr + - prefer range-based for loops + - prefer emplace_back over push_back + +!========================= DetCond v12r44 2015-10-12 ========================= +! 2015-09-25 - Liang Sun + - Remove references to SQLDDDB*.py option files + - If UseOracle & Online options are both set to True, the Oracle ONLINE db is used, instead of sqlite db files + +! 2015-08-03 - Gerhard Raven + - remove #include of obsolete Gaudi headers + +!========================= DetCond v12r43 2015-07-20 ========================= +! 2015-06-30 - Marco Clemencic + - Fixed LHCBPS-1425: ensure that the "InitialTime" is stable. + +! 2015-06-25 - Eduardo Rodrigues + - Undid the reference update from yesterday as the difference is in fact + *not* expected nor understood, see https://its.cern.ch/jira/browse/LHCBPS-1425. + +! 2015-06-24 - Eduardo Rodrigues + - Updated expected reference block for test force_disconnect. + +!========================= DetCond v12r42 2015-06-17 ========================= +! 2015-06-16 - Marco Clemencic + - LHCBPS-1421: Modified RunStampCheck to instantiate EventClockSvc. + To ensure that it does get a "current event time", RunStampCheck triggers + the instantiation of EventClockSvc, so that it is not needed to explicitly + do it in the configuration. + +! 2015-06-16 - Marco Clemencic + - LHCBPS-1421: Updated CondDB configurable to enable/disable RunStampCheck + The RunStampCheck is enabled by default for "Offline" (i.e. not Online + nor Simulation). + +! 2015-06-11 - Marco Clemencic + - LHCBPS-1421: added a first implementation of RunStampCheck + The optional service RunStampCheck can be instantiated (via + ApplicationManager::ExtSvc) to check if a special "run stamp" + condition exist for the current run. + +! 2015-06-05 - Liang Sun + - Set LoadCALIBDB default value to HLT1 for Simulation option + +! 2015-06-05 - Liang Sun + - Set LoadCALIBDB default value to HLT1 for Online and Upgrade options + - Change in detcond.configuration_module to avoid checking layered ONLINE partition + +! 2015-06-04 - Liang Sun + - Finalized support for CALIBOFF by loading the partition as an additional layer only above every ONLINE snapshot no earlier than 2015 + - Bug fix for mistakenly loading CALIBOFF for upgrade CondDB + +!========================= DetCond v12r41 2015-04-20 ========================= +! 2015-04-16 - Liang Sun + - Further support for loading CALIBOFF.db file as an additional layer above all partitions, for testing purpose only + +! 2015-03-18 - Liang Sun + - Fix the nightlies after the last commit. The XML extensions of the condition files within TESTDB?.db are now removed. + +! 2015-03-12 - Marco Clemencic + - Changed the policy of CondDB::generateXMLCatalog to exclude folders with + names ending with ".xml" from the generated catalog. + This is required to allow mixed content in the Online CondDB partition for + the split Hlt, where the files with ".xml" are not meant to be automatically + mapped. + +!========================= DetCond v12r40p1 2015-01-14 ========================= +! 2015-01-07 - Marco Cattaneo + - Fix gcc49 unused function warning in DQScanTest.cpp + +!========================= DetCond v12r40 2014-12-11 ========================= +! 2014-12-03 - Liang Sun + - In Configuration.py: Fixing the cases without valid DQFLAGS tags + +! 2014-12-02 - Liang Sun + - In Configuration.py: Adding option LatestGlobalTagByDataTypes to allow for multiple datatypes. + - In Configuration.py: Inclusion of DQFLAGS to assign the most recent tag for a given datatype + +!========================= DetCond v12r39 2014-10-14 ========================= +! 2014-10-07 - Gerhard Raven + - DetCond configurable: remove explicit paritition name and defer this to the + keys (i.e. filename) in the RunChangeHandlerCondiions map. + +!========================= DetCond v12r38 2014-09-30 ========================= +! 2014-09-30 - Gerhard Raven + - DetCond configurable: combine the RunChangeHandlerConditions and XMLFilename + properties into a single dictioary of filename -> list of conditions so that + the RunChangeHandler can be configured to use multiple <subsystem>_<runnr>.xml + files. + - avoid a spurios warning about ONLINE tag + +!========================= DetCond v12r37 2014-09-08 ========================= +! 2014-09-02 - Liang Sun + - In Configuration.py: Keep the lines related to the import of SQLDDDB-Oracle.py for the UseOracle option, in order not to fail the nightlies + +! 2014-09-01 - Liang Sun + - Changes in Configuration.py: + - Removal of the support for Oracle by commenting out the lines related to the option "UseOracle" + - Added a layer of CALIBOFF above LHCBCOND when LoadCALIBDB option is OFFLINE + +! 2014-07-24 - Liang Sun + - Added qmtest module "detcond.check_db_reading" to check the db reading functionality in Tools/CondDBUI + + +!========================= DetCond v12r36 2014-05-12 ========================= +! 2014-05-05 - Gerhard Raven + - do not truncate partitionname + +!========================= DetCond v12r35 2014-04-29 ========================= + +!========================= DetCond v12r34 2014-04-29 ========================= + +! 2014-04-28 - Gerhard Raven + - make the conditions which the RunChangeHanderSvc updates a property + - make the (last part of the) filename used by the RunChangeHandlerSvc a property + +! 2014-03-26 - Liang Sun + - CondDB preparation for 2015 in Configuration.py: new CondDB partitions 'CALIB' + and 'CALIBOFF' as additional layers above 'ONLINE' partition. New options for + 'LoadCALIBDB' to enable/disable loading the new layers. The default option is + to add the new layers from $SQLITEDBPATH/CALIB-[YEAR].db and $SQLITEDBPATH/CALIBOFF.db + files automatically if exist. + +!========================= DetCond v12r33 2014-02-17 ========================= +! 2013-12-05 - Marco Clemencic + - Fixed the use of boost::shared_ptr according to the macro COOL_HAS_CPP11 (the + one used in COOL headers). + +! 2013-12-05 - Marco Clemencic + - Do not explicitly use boost::shared_ptr. + See https://sft.its.cern.ch/jira/browse/ROOT-5806 + +! 2013-07-18 - Marco Clemencic + - Minor change. + +!========================= DetCond v12r32 2013-07-17 ========================= +! 2013-06-12 - Marco Cattaneo + - Add virtual destructor to ICondDBReader interface class. Fixes gcc48 warning + virtual-move-assign, see explanation in https://sft.its.cern.ch/jira/CFHEP-87 + +!========================= DetCond v12r31 2013-06-03 ========================= +! 2013-05-07 - Marco Clemencic + - Moved the class CondDBCompression to Tools/CondDBEntityResolver, including + dictionary and tests. + +! 2013-05-02 - Liang Sun + - Removed one defunct line to please Coverity. Added in GaudiException() to handle LZMA errors + +!========================= DetCond v12r30 2013-04-29 ========================= +! 2013-04-26 - Liang Sun + - Removed all references to BZip2. We still need 32Bit machines + +! 2013-04-26 - Marco Clemencic + - Removed the temporary hack used for C++11 (it was needed only because Boost + was not yet built with C++11 enabled). + +! 2013-04-25 - Marco Clemencic + - Fixed an issue with the previous change (the environment variable expansion + was prevented in too many places). + +! 2013-04-24 - Illya Shapoval + - A bug fix: an expansion of the SQLITEUPGRADEDBPATH env. variable is prevented. + +! 2013-04-18 - Liang Sun + - Two redundant variables removed to quell the warning messages. + +! 2013-04-17 - Liang Sun + - Added the compression method of LZMA from ROOT with the assigned method number at 0, the method number for BZip2 now changed to 1. + +! 2013-04-02 - Marco Cattaneo + - Fix UNINIT_CTOR defects + +! 2013-03-21 - Liang Sun + - Minor fix on a few potential memory leaks + - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45083&defectInstanceId=156348385&fileInstanceId=111518946 + - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45084&defectInstanceId=156348386&fileInstanceId=111518946 + +! 2013-03-18 - Vanya Belyaev + + - comment usage of python module from removed package HistoStrings + +! 2013-03-12 - Marco Clemencic + - Added hints to Coverity to fix a few flas positives: + - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45071&defectInstanceId=156278261&fileInstanceId=111423297 + - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45070&defectInstanceId=156277446&fileInstanceId=111423297 + - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45069&defectInstanceId=156277445&fileInstanceId=111423297 + +! 2013-03-12 - Liang Sun + - Minor fix on coverity defects (0&i++) + +! 2013-03-11 - Liang Sun + - Set up prototype to allow multiple compression methods, with an additional byte identifying the method prepended to the compressed string + +! 2013-03-08 - Marco Clemencic + - Fixed compilation on 32 bits with a hack (the 32 bits dev version of bz2 + cannot be installed on lxbuild because of missing templates). + +! 2013-02-27 - Liang Sun + - Fix the type conversions to quell the -pedantic warnings + +! 2013-02-23 - Marco Clemencic + - Forgot to add -lbz2 after removing the 'use' statement. + +! 2013-02-22 - Marco Clemencic + - Added use of BZip2 in CMakeLists.txt and removed the use of LCG_Interfaces/bz2lib + from the requirements (we must pick up the system version because the one in + lcg/externals is obsolete and deprecated). + +! 2013-02-21 - Liang Sun + - Added functionalities of compression and decompression on CondDB with new class CondDBCompression + +!========================= DetCond v12r29 2013-02-04 ========================= +! 2012-12-20 - Marco Clemencic + - Stop the TimeOutChecker thread when explicitly disconnected. The thread is + restarted automatically when we reconnect. + +!========================= DetCond v12r28 2012-11-26 ========================= +! 2012-11-21 - Marco Clemencic + - Modified the ICondDBReader interface to allow explicit disconnection from + databases (useful after a fork). + +! 2012-11-15 - Marco Clemencic + - Added CMake configuration file. + +!========================= DetCond v12r27 2012-09-28 ========================= +! 2012-09-26 - Marco Clemencic + - Removed comments from __init__.py + +! 2012-09-21 - Marco Clemencic + - Temporary hack to compile with -std=c++11 (-std=c++0x). + +! 2012-08-09 - Marco Clemencic + - Workaround for bug #96673. + +! 2012-08-08 - Marco Clemencic + - Added python/DetCond/__init__.py. + +!========================= DetCond v12r26 2012-07-24 ========================= +! 2012-07-10 - Patrick Koppenburg + - Bug: https://savannah.cern.ch/bugs/?94454 + . Allow _configureDBSnapshot to work without UseOracle = True statement + . Remove MagneticFieldSvc().UseSetCurrent = True that should be set + in the application's configuration. + +!========================= DetCond v12r25 2012-06-25 ========================= +! 2012-06-12 - Illya Shapoval + - Configuration.py: + + new property is added. "CondDB().Upgrade = True" will switch the CondDB + machinery to talk to the Upgrade database. + + three new properties are added: + CondDB().LatestGlobalTagByDataType = "DataType0" + CondDB().LatestLocalTagsbyDataType = ["DataType1","DataType2",...] + CondDB().AllLocalTagsbyDataType = ["DataType1","DataType2",...] + Setting this will launch the SAX machinery to fetch and set the latest + global tags, latest locals tags, and all local tags, respectively, marked + with requested DataType(s). This is an extension to the previous configuration + machinery (CondDB().UseLatestTags = ["DataType"]) which is still supported. + +!========================= DetCond v12r24 2012-05-02 ========================= +! 2012-04-26 - Patrick Koppenburg + - Configuration: add properties allowing to configure from online_RunNumber.xml + snapshots. For Online Brunel. This is stolen from Moore. + +!========================= DetCond v12r23 2012-02-01 ========================= +! 2012-02-01 - Marco Clemencic + - Modified DQScanTest to work around a small problem in the configuration on + 32 bits builds. + +! 2012-01-31 - Marco Clemencic + - Implemented CondDBDQScanner: a tool to collect (merge) the DQ flags from the + Conditions Database in a given IOV. + - Added a test to validate the output of CondDBDQScanner. + +! 2012-01-31 - Marco Clemencic + - Fixed a couple of compilation warnings. + +! 2012-01-30 - Marco Clemencic + - Added new methods to the ICondDBReader interface (getIOVs), to retrieve the + list of IOVs in a folder for an IOV. + - Added a test for the implementation of getIOVs in CondDBAccessSvc, and fixes. + +! 2012-01-06 - Marco Clemencic + - Modified LoadDDDB to trigger the initialization of the UpdateManagerSvc in + the initialize (to avoid that is gets triggered in the middle of an event). + +! 2012-01-05 - Marco Clemencic + - Fixed ICC warning (Boost 1.48). + +!========================= DetCond v12r22 2011-12-14 ========================= +! 2011-12-09 - Marco Cattaneo + - Add explicit Boost_linkopts for compatibility with Gaudi v23 + +!========================= DetCond v12r21 2011-08-30 ========================= +! 2011-08-26 - Alexander Mazurov + - Update of parser function in CondDBTimeSwitchSvc. This version works only with + Gaudi version > v22r2 (where the new parser model is provided) + +!========================= DetCond v12r20 2011-07-25 ========================= +! 2011-07-20 - Marco Cattaneo + - Create MSG::VERBOSE and MSG::DEBUG messages only when output level requires + it, also using UNLIKELY macro + +!========================= DetCond v12r19 2011-06-14 ========================= +! 2011-06-06 - Illya Shapoval + - Another minor add-on for the 'UseLatestTags' warning output case. + +! 2011-06-03 - Illya Shapoval + - Added a missing configuration bit for the case of per-year-made ONLINE + snapshots: if per-year scheme is met 'CondDBAccessSvc' services are also + created per-year (before they were created per-month but pointing to a single + per-year ONLINE snapshot). SQLDDDB needs a minor change to enable this + configuration change. + - Warnings about latest tags usage are made more meaningful. + +!========================= DetCond v12r18 2011-04-04 ========================= + **** requires LHCbKernel > v12r8 **** +! 2011-03-31 - Marco Clemencic + - Modified the interfaces to use the pattern of Gaudi v21. + - Fixed a few Eclipse warnings. + - Removed CVS keywords. + - Added the possibility to fetch condition for a range of times instead of + only for the current event time. The CondDBAccessSvc property QueryGranularity + can be used to define the width of the time range (around the event time) to + use. The boundaries are rounded so that the requested range is stable. For + example, with a granularity of one hour, the event times 19:10:00, 19:23:15, + 19:56:10 will all fetch the same range 19:00:00-20:00:00. + The set the QueryGranularity property in a standard configuration: + + import GaudiKernel.SystemOfUnits as Units + Units.hours = Units.s * 3600 + + from Configurables import CondDB + CondDB(QueryGranularity = 2 * Units.hours) + +! 2011-03-28 - Marco Clemencic + - Added a test to expose bug #80076 (wrong condition used on first event). + +!========================= DetCond v12r17 2011-01-31 ========================= +! 2011-01-28 - Illya Shapoval + - Configuration machinery is upgraded to load DQFLAGS partition (implemeted in + standalone SQLite file in SQLDDDB) to populate '/Conditions/DQ/Flags' + condition of LHCBCOND partition. SIMCOND has a placeholder for this condition + too but remains empty (there is no need in DQ flags in simulations). + +! 2011-01-10 - Marco Cattaneo + - Fix icc warnings and remarks + +!========================= DetCond v12r16 2010-10-28 ========================= + +! 2010-10-28 - Marco Clemencic + - Fixed a 32bit compilation problem in some new test code. + +! 2010-10-25 - Marco Clemencic + - Added a test to expose bug #74255 + (fake event loop during finalize doesn't work). + +! 2010-10-17 - Illya Shapoval + - CondDBAccessSvc method getChildNodes is modified to load only those Online + folders in SIMCOND which are tagged with a tag being set to load db. + Modification is done in a binary backwards compatible way. + +!===================== Det/DetCond v12r15 2010-09-28 ========================= +! 2010-09-28 - Marco Clemencic + - Updated tests to expect the return codes of Gaudi (v21r11). + +! 2010-09-24 - Marco Clemencic + - Added a test to verify that a failure to load a condition in the + UpdateManagerSvc is properly reported. + +!===================== Det/DetCond v12r14 2010-08-25 ========================= +! 2010-08-06 - Marco Clemencic + - Improved DetCondTest::TestConditionAlg to allow testing artificial + dependencies between conditions. + - Modified test detcond.heart_beat to expose bug #66497 (velo motor positions + updated several times). + +!===================== Det/DetCond v12r13 2010-05-21 ========================= +! 2010-05-18 - Marco Clemencic + - Fixed few Windows warnings. + +! 2010-05-12 - Marco Clemencic + - Modified the message printed in case of a failure of the heart-beat check to + show the time in human-readable format (UTC). + +!===================== Det/DetCond v12r12 2010-04-09 ========================= +! 2010-03-27 - Illya Shapoval + - CondDB configurable is tuned to override all default and user tags settings + by the latest tags for defined DataType if the 'UseLatestTags' property is + set (before an exception was thrown if found multiple definitions). + +! 2010-03-26 - Illya Shapoval + - Added new CondDB().UseLatestTags = [DataType,OnlyGlobalTags=False] property. + Previous CondDB().useLatestTags(DataType,OnlyGlobalTags=False) method is + preserved. Now it is possible to set the latest tags also for the simulation + case. + +!===================== Det/DetCond v12r11 2010-03-17 ========================= +! 2010-03-17 - Marco Clemencic + - Changes to the CondDB configurable + - in the online environment (Online == True) the IgnoreHeartBeat property is + defaulted to True + - added the property HeartBeatCondition to set the location of the heart-beat + condition + +! 2010-03-05 - Marco Clemencic + - Fixed a problem in the CondDB configurable for the usage of Oracle in the + PIT. + +! 2010-02-25 - Marco Clemencic + - Removed the dependency on rx (obsolete). + +!===================== Det/DetCond v12r10 2010-02-12 ========================= +! 2010-02-12 - Illya Shapoval + - Minor change to the CondDB.useLatestTags(DataType) function. Added the + mode for it to find and set only the latest global tag for a + particular DataType, dropping the latest local tags on top of it. + New syntax: CondDB.useLatestTags(DataType,OnlyGlobalTags = False). + +! 2010-02-05 - Marco Clemencic + - Added the function CondDB.useLatestTags(DataType) to automatically select + the latest local and global tags for a given data type from the SQLDDDB + release notes. + +!===================== Det/DetCond v12r9 2010-01-20 ========================== +! 2010-01-19 - Marco Clemencic + - Fixes to the first implementation of task #13270. + - Handle properly cool and coral exceptions when retrieving the heart beat + condition to be able to issue a meaningful error. + - Modified the automatic setting of the HeartBeatCondition property for the + readers of CondDBTimeSwitchSvc. The property is added only to the last + reader because the other readers are (by construction) accessing limited + partitions. + +! 2010-01-12 - Marco Clemencic + - Completed task #13270: Block access to conditions in ONLINE partition if + validity interval is not closed + - Modified CondDBAccessSvc to accept a new property (HeartBeatCondition). The + property specified the path in the database to be used as heart beat, i.e. + the partition is considered not up-to-date if the latest update of that + condition is less recent than the event time being processed. + Since the test is done only when actually accessing the CondDBAccessSvc, + to ensure that we get there when the event exceeds the validity of the + database, the returned validities are artificially cut at the latest heart + beat. + - Modified the ConfigurableUser CondDB to set the HeartBeatCondition for the + Online partition and snapshots (can be disabled with the property + IgnoreHeartBeat). + - Removed the OnlineDBValidatorSvc because it is not needed anymore. + - Adapted the TestCondition algorithm to test the new feature and added the + relative test. + NOTE: In the special case when there are conditions with initial validity + after the latest heart beat, there may be problem during the initialize + if exposed validity (artificially cut) is checked (the UpdateManagerSvc + and the DetectorDataSvc are not doing it). + - Added the properties "DisableLFC" and "Online" to the ConfigurableUser CondDB + to be able to ignore the LFC when using Oracle and enable special + configuration for the Online environment (Oracle). + +!===================== Det/DetCond v12r8 2009-12-11 ========================== +! 2009-12-11 - Marco Cattaneo + - Remove obsolete file DetCond_dll.cpp + +! 2009-12-05 - Dmitry GOLUBKOV + - python/DetCond/HistoCond.py: new python module to decorate the Condition + object with functions which extract the histograms from the parameters and to + define functions which convert histograms to Condition parameter xml strings. + - cmt/requirements: version increment to v12r8 + +!===================== Det/DetCond v12r7 2009-06-16 ========================== +! 2009-06-03 - Marco Clemencic + - Changes in the CondDB ConfigurableUser: + - Fixed a bug causing a failure when using SQLite local copies and + CondDBTimeSwitchSvc. + - Changed the policy when both UseOracle and SQLiteLocalCopiesDir are active: + issue a warning and ignores SQLiteLocalCopiesDir instead of raising an + exception. + +!===================== Det/DetCond v12r6 2009-05-28 ========================== +! 2009-04-28 - Marco Cattaneo + - In Configurable, do not access MessageSvc() directly, use instead + getConfigurable("MessageSvc"), allow to replace MessageSvc instance online + +! 2009-05-27 - Marco Clemencic + - Modified the way CondDBAccessSvc::finalize() synchronizes with the second + thread. + - Updated the usage of the Boost Thread module (use more recent classes). + - Added a test triggering the connection time-out. + +!===================== Det/DetCond v12r5p3 2009-05-06 ======================== +! 2009-04-17 - Marco Cattaneo + - Replace endreq by endmsg + +!===================== Det/DetCond v12r5p2 2009-03-09 ======================== +! 2009-03-09 - Marco Cattaneo + - Add options/UseOracle.py: additional options for gaudirun.py command line + to get conditions from Oracle DB + +!===================== Det/DetCond v12r5p1 2009-02-18 ======================== +! 2009-01-29 - Marco Cattaneo + - Fix compilation warning from Boost 1.38 + +!===================== Det/DetCond v12r5 2009-01-08 ========================== +! 2009-01-07 - Marco Clemencic + - Improvements to the CondDB configurable: + - added the possibility to use local copies of the SQLite databases (through + CondDBSQLiteCopyAccSvc) + - added the possibility of specifying alternatives and layers with only the + connection string or the SQLite filename + +!===================== Det/DetCond v12r4 2008-11-17 ========================== +! 2008-11-17 - Marco Cattaneo + - Fix to requirements avoid warnings when making configurables database + - Add LoadDDDB algorithm, moved from DetDescChecks to avoid tests dependency + on DetDescChecks package + - Add missing dependencies for QMTest + +! 2008-11-14 - Marco Cattaneo + - In Configurable, set up VFSSvc, e.g. for use by ParticlePropertySvc + +! 2008-11-11 - Marco Clemencic + - Fixed configuration problems in the test after the changes in DDDB. + +! 2008-11-06 - Marco Clemencic + - Added the ConfigurableUser CondDB for the high level configuration of the + conditions database. The old configuration function (addCondDBLayer etc.) are + still available for backward compatibility, but implemented using the new + configurable which allows to specify local tags too. + +! 2008-10-31 - Marco Cattaneo + - Fix for gcc 4.3 + + NEEDS: LCGCMT > 55a + +! 2008-10-10 - Marco Clemencic + - Modified the requirements file following the changes in the CORAL interface + package (see bug #41579). + +!===================== Det/DetCond v12r3 2008-09-30 ========================== +! 2008-09-29 - Marco Clemencic + - Fixed a bug in CondDBCommon::generateXMLCatalog, failing for folders with + names shorter than 4 chars. + +!===================== Det/DetCond v12r2 2008-07-30 ========================== +! 2008-07-30 - Marco Clemencic + - Changed the name of the configurables for online partition from ONLINE-YYYYMM + to ONLINE_YYYYMM. + +! 2008-07-28 - Marco Cattaneo + - Fix windows compilation + +! 2008-07-23 - Marco Clemencic + - Changed the type of CondDBDispatcherSvc.Alternatives from list of strings + to map<string,string>. + - Added tests for DetCond.Configuration. + - Fixed a problem with conversion between 'double' and 'long long' in + CondDBTimeSwitchSvc. + +! 2008-07-21 - Marco Clemencic + - Added a function to DetCond.Configuration (configureOnlineSnapshots) to + prepare the configuration using monthly snapshots of the ONLINE partition. + The first and last snapshot used extend their validity to 0 and +infinity + respectively. + +!===================== Det/DetCond v12r1 2008-07-16 ========================== +! 2008-07-10 - Marco Clemencic + - Fixed a tiny memory leak introduced in COOLConfSvc during the deSEALing. + +!===================== Det/DetCond v12r0 2008-06-30 ========================== +! 2008-07-02 - Marco Clemencic + - Introduced a work-around for COOL bug #38422, which was preventing the usage + of local tags as overlays. + - Removed a left-over in the requirements file needed for some tests. + (It was breaking compilation on win32) + +! 2008-06-27 - Marco Clemencic + - Introduced the ICondDBReader implementation CondDBTimeSwitch. + - it allows to use different partitions for different IOVs + - added a simple test for it (using a test algorithm added to the package: + DetCondTest::TestConditionAlg). + +! 2008-06-26 - Marco Clemencic + - Improved direct mapping between the COOL hierarchy and the transient store + one: + - direct mapping enabled by default (can be turned off via options to improve + the performances of CondDBLayeringSvc and CondDBDispatcherSvc) + - correct mapping in CondDBDispatcherSvc and CondDBLayeringSvc: + - CondDBDispatcherSvc: add entries implied by alternatives + - CondDBLayeringSvc: expose all the possible entries + - modified ICondDBReader (needed for a generic implementation of the mapping) + - added tests for foreseen use-cases + - the code to generate the XML catalog has been moved to a separate file to + be shared among the implementations of ICondDBReader + - Added dictionaries for few CORAL interfaces that are not available through + COOL. + +! 2008-06-24 - Marco Clemencic + - Fixed a bug in the direct mapping between the hierarchy of the COOL + database and the transient store one. + +! 2008-06-10 - Marco Clemencic + - Adapted to the new SEAL-less COOL and CORAL. Needs LCG_55 (Gaudi v20r0) + +!===================== Det/DetCond v11r11 2008-05-19 ========================= +! 2008-05-19 - Marco Clemencic + - Added the possibility of direct mapping between the hierarchy of the COOL + database and the transient store one. + Disabled by default, but needed to use the Online partition of the condition + database. + The implementation still lacks few features: + - does not work if the cache is not enabled + - it is implemented only at the CondDBAccessSvc (it should work at the + CondDBDispatcherSvc and CondDBLayeringSvc level too) + +!===================== Det/DetCond v11r10 2008-04-24 ========================= +! 2008-04-24 - Marco Clemencic + - Improved the algorithm to select the closest replica of the database when + using LFCReplicaSvc. The local site (preferred replica), can be specified, in + order of priority, with job option (of COOLConfSvc), the environment + variables DIRACSITE and LHCBPRODSITE or the hard-coded default "CERN.ch". The + value of local site can be any substring (case insensitive) to be matched in + the "host" field of the CORAL LFC entries. The fall-back servers are used in + random order. + +! 2008-04-22 - Marco Clemencic + - Fixed a problem in CondDBAccessSvc related to the usage of local tags. + +! 2008-04-09 - Marco Clemencic + - Modified default idle connection time-out in CondDBAccessSvc from 600s to + 120s. + +!===================== Det/DetCond v11r9 2008-03-03 ========================== +! 2008-03-03 - Marco Clemencic + - Added the function "useCondDBLogger" to DetCond.Configuration. + - Modified DetCond.Configuration to expose the configurables provided by the + package when imported. + +! 2008-02-29 - Marco Clemencic + - Added the Python module DetCond.Configuration to provide useful functions + for the configuration of the CondDB: + - addCondDBLayer + - addCondDBAlternative + +! 2008-02-22 - Marco Cattaneo + - Remove hacks in requirements no longer needed with Gaudi v19r7 + +! 2008-02-12 - Marco Clemencic + - Fixed a problem occurring when trying to retrieve a folder which is not in + the database (typical case for CondDBLayeringSvc), due to an uninitialized + variable. + +!===================== Det/DetCond v11r8 2008-01-28 ========================== + NEEDS: LCGCMT >= 54 +! 2008-01-26 - Marco Clemencic + - Added the service CondDBLogger (implementation of ICondDBReader) that, if put + between a user and a provider of the ICondDBReader interface, stores in a + file all the requests that were made to the CondDBReader, with the time of + the request. + The class allows to generate some history of the CondDB traffic to be able to + analyze and replay it afterward. + - Added the algorithm CondDBReplayAlg. It can read a file produced with + CondDBLogger to replay the requests to the database. + - Modified ICondDBReader and CondDBAccessSvc to allow the retrieval of objects + from the conditions database using the channel name (available since COOL + 2.3.0, LCGCMT 54). + +! 2008-01-21 - Marco Clemencic + - Improved error messages in case of CORAL exceptions. + +! 2007-12-20 - Marco Clemencic + - Allow to use tags that are not global in CondDBAccessSvc. + - Added a service (COOLConfSvc/ICOOLConfSvc) dedicated to the instantiation and + configuration of COOL/CORAL. The options to configure COOL and CORAL have + been moved from CondDBAccessSvc to the new service. + +! 2007-12-20 - Marco Cattaneo + - Replace homemade linkopts with new Boost_linkopts_filesystem_mt + - Remove slc3 specific set, no longer supported in LCG_54 + +!===================== Det/DetCond v11r7 2007-12-03 ========================== +! 2007-11-29 - Marco Clemencic + - Added two options to CondDBAccessSvc to control the retrial period and + retrial time-out of CORAL. + +!===================== Det/DetCond v11r6 2007-09-04 ========================== +! 2007-08-01 - Marco Clemencic + - Fixed a bug connected to "lazy connection" feature. I was using an instance + of a cool object to call a static member function. + +! 2007-07-31 - Marco Clemencic + - Fixed a bug with the "lazy connection" feature. The thread to disconnect from + the database was started even if we never connect. + Now it is started only at the first connection. + +!===================== Det/DetCond v11r5 2007-07-05 ========================== +! 2007-07-05 - Marco Clemencic + - Added the possibility to connect to the database only when needed (and made + it the default), so a job does not need the database does not need to be + able to connect to it or to be reconfigured. + To restore the old behavior (connection at initialize) use the option: + CondDBAccessSvc.LazyConnect = False; + +!===================== Det/DetCond v11r4 2007-06-15 ========================== + NEEDS: LCGCMT >= 52 +! 2007-06-06 - Marco Clemencic + - Removed the check on macro CORAL_1_8_x (use always the new CORAL feature). + +!===================== Det/DetCond v11r3 2007-05-16 ========================== + NEEDS: LHCbKernel >= v7r3 (ICondDBInfo) + LCGCMT >= 51 (if macro CORAL_1_8_x is set, + for CORAL 1.8.0) + +! 2007-05-16 - Marco Clemencic + - The parts that depend on CORAL 1.8.0 API are now enclosed in #ifdef/#endif + directives, so that DetCond can be compiled with the old version of CORAL. + +! 2007-05-11 - Marco Clemencic + - Extended ICondDBReader with the interface ICondDBInfo from LHCbKernel and + implemented the new function in all the ICondDBReader's (CondDBCnvSvc, + CondDBAccessSvc, CondDBLayeringSvc, CondDBDispatcherSvc). + NOTE: this introduce a dependency on LHCbKernel. + +! 2007-05-03 - Marco Clemencic + - Added service OnlineDBValidatorSvc to check if the Online CondDB replica + is recent enough. (see doxygen documentation) + +! 2007-05-02 - Marco Clemencic + - First implementation of the algorithm to sort DB replicas extracted from + LFC. + +!===================== Det/DetCond v11r2 2007-04-23 ========================== +! 2007-04-20 - Marco Clemencic + - Added ICondDBAccessSvc::connectionString() to be able to find the + connection string that was used without looking in the options. + - Use a static std::auto_ptr instead of a basic pointer and a counter of + instances (for CondDBAccessSvc::s_XMLstorageSpec). + - Added class CondDBSQLiteCopyAccSvc to copy an SQLite file and connect to + the copy. + +!===================== Det/DetCond v11r1 2007-03-22 ========================== +! 2007-03-22 - Marco Clemencic + - Small improvement to the database disconnect message. + +! 2007-03-16 - Marco Clemencic + - Added an option to enable CORAL LFCReplicaService (off by default). + - Added an option to enable CORAL automatic connection purge. + - Added a check on the database in CondDBAccessSvc::i_checkTag to avoid + segmentation possible faults. + - Disable some compiler optimizations in libstdc++ on slc3, because it seems + that on SLC3 there are problems with multithreaded applications. + +!===================== Det/DetCond v11r0 2007-03-05 ========================== + NEEDS LCGCMT >= 50 + +! 2007-03-05 - Marco Cattaneo + - Removed obsolete DetCond_load.cpp file + +! 2007-02-28 - Marco Clemencic + - Removed a work-around for missing library in LCG_Interfaces/COOL + +! 2007-02-22 - Marco Clemencic + - Fixed a bug (segfault) occurring when requiring the time-out task without + a connection (pure memory cache). + - Moved few message from DEBUG to INFO and added few more messages (like + the connection string and the tag used). + - Activated by default the disconnect on time-out feature (with time out set + to 10 min.) + +! 2007-02-19 - Marco Clemencic + - Minor change in RelyConverter.cpp (removed a useless line) + +! 2007-02-14 - Marco CLEMENCIC + - Updated to changes in COOL API + - Added to CondDBAccessSvc a function to clear the cache + +!================ Det/DetCond v10r0 2007-01-31 ============================= +! 2007-01-31 - Marco Cattaneo + - Fix and retag requirements to link on Windows. + +! 2006-12-06 - Florence RANJARD + - apply_pattern install_more_includes + - fixes for new plugins (P.Mato) + +!================= Det/DetCond v9r1 2006-09-04 ============================== +! 2006-09-04 - Marco Clemencic + - Modified the way of specifying one of the element of the condition. Now the + path to a condition in XML is: + + "conddb:/path/to/condition/[attribute@]Folder.xml[:channel][#Name]" + +! 2006-08-31 - Marco Clemencic + - Added the possibility of using one CondDB condition to store more than one + file using elements of the attribute list. + Backward compatible chages in the API (with deprecated functions). + +! 2006-08-31 - Marco Clemencic + - Added the possibility of disconnection from the DB after an inactivity + period defined by CondDBAvvessSvc.ConnectionTimeOut. + (The feature is implemented using Boost.Thread) + +! 2006-08-30 - Marco Clemencic + - Fixed a bug in CondDBDispatcherSvc: the correct alternative database was + never selected + - Fixed a bug in RelyConverter that was causing a segmentation fault if the + retreived XML string didn't start with "<?xml" (it is not a valid XML + string, but it does not justfy a segfault ;) + +!================= Det/DetCond v9r0 2006-07-18 ============================== +! 2006-07-18 - Marco CLEMENCIC + - Added to CondDBAccessSvc the possibility of chosing between read-only and + read-write connections to the database. (default is read-only) + +! 2006-07-17 - Marco CLEMENCIC + - Using Gaudi random generator service instad of the posix one in + CondDBAccessSvc (needed for recursive tagging) + +! 2006-07-14 - Marco CLEMENCIC + - Removed interface ICondDBCnvSvc. Now CondDBCnvSvc is an ICondDBReader and + the layering of databases is delegated to the class CondDBLayeringSvc. + - Removed the obsolete method ICondDBEditor::createFolder + +! 2006-07-12 - Marco CLEMENCIC + - Fixed a small bug in the code for the selection of the alternative in + CondDBDispatcherSvc. + +! 2006-07-11 - Marco CLEMENCIC + *** will be v9r0 *** + - Completely redesigned the support for alternative DBs: + - Reverted to previous implementation of CondDBAccessSvc + - Splitted ICondDBAccessSvc in 3: + 1) ICondDBReader: read only functions + 2) ICondDBEditor: write functions (storeXML, createNode, etc.) + 3) ICondDBAccessSvc: access function (setTag, etc.) + - Added the class CondDBDispatcherSvc as an implementation of ICondDBReader. + This one is selecting the appropriate alternative AccessSvc to use. + The alternative is declared with something like: + CondDBDispatcherSvc.Alternatives += { "/OnLine=CondDBAccessSvc/OnlineAccSvc" }; + The new functionality is not tested, but it is backward compatible even using + CondDBDispatcherSvc with only the default access service (CondDBAccessSvc). + - Dictionary updated to include the 2 new interfaces. + - Removed dependency on PCRE (not needed anymore) + - Documentation still to be updated. + +! 2006-07-07 - Marco CLEMENCIC + - Added the possibility of specifying alternative databases for certain + sub trees to a CondDBAccessSvc. + Now you have a default DB (backward compatible) and you can use a different + COOL DB for all the directories under e.g. "/OnLine", with an option like + CondDBAccessSvc.AlternativeDBs += { "/OnLine=<connectionString>" }; + Note: it still has to be tested, but it is backward compatible. + - Added dependency on PCRE (used to parse the string to specify alternative DB) + +! 2006-06-16 - Marco CLEMENCIC + - Removed some code used for debugging which is not needed. + - Added the possibility to wait that the requested tag appears + (configurable number of trials and time between trials) + +! 2006-06-12 - Marco CLEMENCIC + - Many API changes + - remamed ICondDBAccessSvc::createFolder to ICondDBAccessSvc::createNode + - removed the version of ICondDBAccessSvc::storeXMLString taking two doubles + because it was obsolete and confunding + - replaced ICondDBAccessSvc::tagFolder with the two functions + ICondDBAccessSvc::tagLeafNode and ICondDBAccessSvc::recursiveTag + (the first for Folders, the second for sub-trees) + - removed obsolete properties: HostName, User, Password, HidePassword, + Database, Schema, BackEnd + - property TAG renamed to DefaultTAG + - default value for property UseCache set to true (it was false) + - Enabled tagging functionalities (based on COOL HVS) + +!================= Det/DetCond v8r0 2006-04-25 ============================== +! 2006-04-25 - Marco Clemencic + **** requires LCGCMT_43 **** + - Updated to COOL_1_3_x + +! 2006-04-13 - Marco Clemencic + - Fixed a problem with uninitialized variables just affecting the case of + a FolderSet stored in the CondDB cache. + +!================= Det/DetCond v7r10p1 2006-03-29 ============================ +! 2006-03-29 - Marco Cattaneo + - Trivial fix in requirements for GCCXML+Boost on Windows with LCG_v42a + +!================= Det/DetCond v7r10 2006-03-22 ============================== +! 2006-03-22 - Marco Cattaneo + - Add DetCondDict (to remove dependency on DetCond in DetSys) + +!================= Det/DetCond v7r9 2006-02-03 =============================== +! 2006-02-01 - Marco Clemencic + - Updated to Gaudi v18r2 (use Gaudi::Time instead of ITime+TimePoint) + - Added Boost and SEAL to the dependencies because they are not inherited + from other packages anymore + +! 2006-01-25 - Nicolas Gilardi + - Allow to use a COOL connection string instead of the splitted credentials + - Modified Function CondDBAccessSvc::createFolder() to use large (16M) + strings by default in the CondDB folders. + +! 2006-01-22 - Marco Clemencic + Nicolas Gilardi + - Updated to improved COOL API. + +================= Det/DetCond v7r8 2006-01-20 ================================ +! 2006-01-20 - Marco Cattaneo + - Add use CORAL to requirements. N.B.: this is temporary, should be done + directly in COOL interface package + +! 2005-12-08 - Marco Clemencic + - Use GaudiUtils::HashMap in CondDBCache.h + +================= Det/DetCond v7r7 2005-11-04 ================================ +! 2005-10-18 - Marco Clemencic + - Cosmetic improvements + (RelyConverter, CondDBGenericCnv, CondDBAccessSvc, CondDBCnvSvc) + - Added `#include <vector>' in ICondDBAccessSvc.h and ICondDBCnvSvc.h + +! 2005-10-05 - Marco Clemencic + - Minimal update to follow API changes from COOL_1_1_0 to COOL_1_2_4 + +================= Det/DetCond v7r6 2005-09-19 ================================ +! 2005-09-18 - Marco Clemencic + - Allow direct mapping of the CondDB structure to the DetectorDataSvc tree + (no need to pass through an XML file/string with only catalogs) + - Use the 3rd string of the GenericAddress to store the origin of the XML + string (needed for self referencing XML string with DetDescCnv > v2r8) + +! 2005-08-31 - Marco Clemencic + - Implemented RelyConverter::updateObjRefs in order to re-initialize + correctly the updated conditions. + +! 2005-08-30 - Marco Clemencic + - Added support to cool::ChannelId (needs DetDescCnv > v2r8) + - Fixed a bug in CondDBCache + (the search of conflicts in the IOVs worked only in a well defined case, + the one tested!) + +================= Det/DetCond v7r5 2005-07-21 ================================ +! 2005-07-21 - Marco Clemencic + - Apply always tag NEEDS_COOL_FACTORY (is needed by Windows and Python) + +! 2005-07-11 - Marco Clemencic + - Removed unused pointers from CondDBCnvSvc + +! 2005-07-07 - Marco Cattaneo + - Fix a doxygen warning + +! 2005-07-07 - Marco Clemencic + - Abstract interfaces moved to DetDesc (to allow python bindings) + - Added CondDBAccessSvc::dumpCache(), it prints (level=DEBUG) the content + of the cache. + +! 2005-06-30 - Marco Clemencic + - Added RelyConverter::fillObjectRefs (was missing, but needed for + initialization of objects) + +================= Det/DetCond v7r4 2005-06-23 ================================ +! 2005-06-23 - Marco Clemencic + - Added the possibility of having an in-memory copy of the CondDB. + +! 2005-06-14 - Marco Clemencic + - Renamed ConditionsDBCnvSvc to CondDBCnvSvc and added the interface + ICondDBCnvSvc + +================= Det/DetCond v7r3 2005-06-14 ================================ +! 2005-06-14 - Marco Cattaneo + - Move ConditionsDbCnvSvc and RelyConverter to component library. + +! 2005-06-14 - Marco Clemencic + - CondDBAccessSvc does not complain anymore if the user is not specified + (adapted to POOL XML authentication service, COOL > 1.1.0) + +! 2005-06-08 - Marco Clemencic + - Changed from "component library" to "component + link library" + +================= Det/DetCond v7r2 =========================================== +! 2005-05-27 - Marco Clemencic + - fixed compilation issue for Windows + +! 2005-05-25 - Marco Clemencic + - Adapted to COOL 1.1.0 (LCG_35) + +================= Det/DetCond v7r1 =========================================== +! 2005-05-12 - Marco Clemencic + - Fixed the compilation on WIN32 + - Added support to multiple databases through option + ConditionsDBCnvSvc.CondDBAccessServices + +================= Det/DetCond v7r0 =========================================== +! 2005-04-25 - Marco CLEMENCIC + - Upgrade to COOL_1_0_0 (first production release) + - Works with LHCb v18r3 + +================= Det/DetCond v6r1 =========================================== +! 2005-04-22 - Marco CLEMENCIC + - Upgrade to COOL_0_1_0-pre2 + - Support for tagging + - almost all the technicalities (POOL/COOL) moved to CondDBAccessSvc + - some clean up + - commit before the first production release + +============================================================================== +! 2005-02-09 - Marco CLEMENCIC + - Upgrade to first public preliminary version of COOL (COOL_0_0_3-pre1) + - Renamed XMLRelyCnv to RelyConverter (it can use, in principle, any + conversion service). + - Moved CondDBGenericCnv to the public interface in order to allow public + usage of RelyConverter. + +============================================================================== +! 2005-01-27 - Marco CLEMENCIC + - Upgrade to first preliminary version of the Conditions Database API: + COOL_0_0_1 + +============================================================================== +! 2004-12-08 - Marco Clemencic + - Upgrade to latest stable version of CondDB (CONDDB_0_2_0) and fixed for the +changes in Gaudi/LHCb + - Moved and modified part of the ConditionsDBCnvSvc to a dedicated converter +(XmlRelyCnv) + a generic CondDB converter to put common Converter functions in +one place + - Implemented the possibility to use a fall back Converter (the one relying on +DetectorPersistencySvc) if no dedicated converter is found. +Requirements v5r0 + +============================================================================== +!20030131 - Andrea Valassi +Upgrade to DetDesc v11r8. +Only change is in recommended CMTPATH. +- DetDesc is included in LHCB_v11r5 for all of rh61dbx, rh73dbx and Windows +- This makes it easier to distribute as DetDesc does not need to be recompiled +Requirements v4r3, private tag h20030131 + +============================================================================== +!20021203 - Andrea Valassi +Include the MySQL implementation for both RH73 and WIN32 +- DetCond on RH73/WIN32 now depends on both Oracle and MySQL implementations + > multiple "use..." in the requirements + > if the "use..." statement is removed, some code is #ifndef'd away + (as the base packages propagate to DetCond the relevant cppflags) + > to make the code more readable, implementation-specific init() and + i_buildCondDBInfo() have been introduced (#ifdef'd in only if necessary!) + > I assume RH61 is always Objy only +- Implementation is read at runtime from the job options + > ConditionsDBGate.condDBImpl = one of CondDBObjy, CondDBOracle, CondDBMySQL +- Remove CondDBKey.h from DetCond (I forgot to remove it on h20020301!) +Requirements v4r2, private tag h20021203 + +============================================================================== +!20021125 - Andrea Valassi +Upgrade to CondDBOracle v4r16, Gaudi v11r2 and DetDesc v11r2. +Upgrade to RedHat73 on lxplus7. +- no major change to DetCond code + > disable WIN32 compilation warning 4786 in ConditionsDBGate.cpp + > print out ORA_NLS33 and NLS_LANG to keep track of their values +- dependency on Det/CondDBOracle changed from v4r15 to v4r16 (RH7,WIN) +- dependency on Gaudi changed to v13r* (tested with v13r2) +- dependency on GaudiSvc changed to v10r* (tested with v10r1) +- dependency on Det/DetDesc changed to v11r* (tested with v11r2) +Modify CMT requirements to allow for runtime choice between Oracle and MySQL. +- precompiler directives are inherited from CondDB package(s) +- dependency on CONDDB (using Objectivity) changed to v3r02p3 (RH6) +Requirements v4r1, private tag h20021125 + +============================================================================== +!20020725 - Andrea Valassi +Upgrade to CondDBOracle v4r15 and Gaudi v10r4. +- no change to DetCond code +- dependency on Det/CondDBOracle changed from v3r10p1 to v4r15 (RH7,WIN) +- dependency on CONDDB (using Objectivity) remains v3r02p2 (RH6) +- dependency on Gaudi tested with GaudiKernel v12r3 and GaudiSvc v8r3 +- dependency on Det/DetDesc (v10r*) tested with v10r3 +Requirements v4r0, private tag h20020725 + +============================================================================== +!20020417 - Andrea Valassi +Upgrade to Gaudi v10 +- use RedHat7.2 tag rh72_gcc2952 (not rh72_gcc29521), defined in GaudiPolicy +- dependency on Det/CondDBOracle changed from v3r10 to v3r10p1 +- dependency on CONDDB changed from v3r02p1 to v3r02p2 (bug fix) +- adapt to new version of MsgStream.h in GaudiKernel for longlong printout +- dependency on Det/DetDesc changed from v9r* to v10r* +Requirements v3r0, private tag h20020417 + +============================================================================== +!20020405 - Andrea Valassi +Minor modifications to requirements +- dependency on CONDDB changed from v3r02 to v3r02p1 +- env. variable CONDDB_implementation is defined in CONDDB or Det/CondDBOracle +Requirements v2r1, private tag h20020405 + +============================================================================== +!20020328 - Andrea Valassi +First Oracle implementation ported to Linux (RedHat 7.2 only) +See doc/README.RedHat72 in Ex/DetCondExample for more details +Corresponds to Emil's first official release of ConditionsDB (0.3.1.0) +- change WIN32 dependency on Det/CondDBOracle package to version v3r10 +- add rh72_gcc29521 dependency on Det/CondDBOracle v3r10 +- keep rh61_gcc29521 dependency on CONDDB v3r02 +Requirements v2r1, private tag h20020328. + +============================================================================== +!20020308 - Andrea Valassi +Change dependency on CondDBOracle package to version v2r10 (0.2.1.0). +Requirements v2r1, private tag h20020308. + +============================================================================== +!20020301 - Andrea Valassi +First version supported on Windows using an Oracle implementation of CondDB. +- Platform-specific support + > remove CondDBKey.h from DetCond: use that from the ConditionsDB package + > interchange the contents of DetCond_dll and DetCond_load + > remove #ifdef's with dummy failure codes for non-Linux platforms +- Support of Oracle (needed also to suppport Oracle under Linux) + > implementation specified in the requirements is propagated via #ifdef's + > new init string for the Oracle database including host, user and password + > CondDBOracleMgrFactory or CondDBObjyDBMgrFactory called in either case +Requirements v2r1, private tag h20020301. + +============================================================================== +!20020110 - Flr + requirements - apply packageShr instead of ld_library_path pattern because + it is a component library. + do not apply package_Lshlibflags, there is no linker library. + +!20011220 - Andrea Valassi +Simplify dependencies on the Gaudi framework. + +============================================================================== +!20011216 - Andrea Valassi +Major changes due to tighter coordination with DetDesc and XmlDDDB packages. +- Update cannot be delegated to XmlCnvSvc until major changes in DetDes + > code creating and interpreting DOM trees in each Xml converter should be + executed also in updateObj(): to avoid duplicating code, a solution is + to move it from createObj() to updateObj() or better updateObjRefs(), + which should be called internally from createObj() + > my (temporary?) solution is to create a new object using the address, and + deep copy part of it into the old one by a Condition::update(Condition&) + method to deep copy only those properties of a DataObject that refer + to a Condition (eg validity and parameters); the registry, address, + reference counts and other DataObject properties should not be deep + copied instead (hence an overloaded operator= is not introduced) + > update of DataObjects is only possible for Conditions (and derived classes) + because this method exists only for Conditions + > this is the only reason to have a dependency on DetDesc + > however, DataObjects not implementing IValidity are now assumed valid + (previously, an error was returned when updating them) +- Changes in folder description + > classID are removed from all XML refs: remove it from folder description + > assume that secondary storage type is always read from folder description +- Remove ConditionsDBAddress (a GenericAddress of type CONDDB is enough) + > par[0] is still the COndDB folder name + > the tag name is not anymore in the CONDDB address + > par[1] is now the name of the element (e.g. the name of an XML element) + > the string storage type is not in the CONDDB address + (it is now assumed that it is always read from the folder description) + > ipar{0,1] are not used anymore +- Registry entry (can be 0) is used in creating and updating Conditions + > for instance: this is needed for catalog conversion + > it is set in the secondary temporary address (e.g. an XML catalog address) +- Minor changes in messaging: use VERBOSE tag for verbose comments +- Overload methods for writing representations in ConditionsDBCnvSvc + > they must be overloaded because this CnvSvc has no converters + > they are empty for the moment (not yet implemented) +- Upgrade to CMT v1r10: remove scripts and hacks needed to cure a bug in CMT +Requirements v2r0, private tag h20011216. + +============================================================================== +!20011130 - Andrea Valassi +Modified version of DetDataSvc in GaudiSvc committed to CVS +- Contains main features of ConditionDataSvc and ConditionsDBDataSvc +- Remove ConditionDataSvc and ConditionsDBDataSvc from this package + +============================================================================== +!20011129 - Andrea Valassi +- Remove the IConditionsDBDataSvc special interface + > ConditionsDBDataSvc now does little more than ConditionDataSvc +- Implement a dummy IIncidentListener interface in ConditionDataSvc +- Redefine ConditionsDBAddress_undefinedClassID = CLID_NULL (it will disappear) + +============================================================================== +!20011128 - Andrea Valassi +Move the global tag from the ConditionsDBDataSvc to the ConditionsDBCnvSvc +- Use IAddressCreator interface of CnvSvc to create addresses with global tag + > "DEFAULT" becomes a reserved word to indicate the global tag +- Remove method setGlobalTag (the tag can only be set in the job options) + +============================================================================== +!20011127 - Andrea Valassi +A few more changes before including my detector data service in GaudiSvc +- The event time is not passed in an address from the DataSvc to the CnvSvc + > remove IConditionAddress + > ConditionsDBCnvSvc now reads the event time from the DetDataSvc + > ConditionDataSvc::updateObject now just checks validity before delegating +- Move interface IDetDataSvc (formerly IConditionDataSvc) to GaudiKernel + > needed to retrieve the event time within the ConditionsDBCnvSvc + > the setEventTime method is temporary (eventually: use the IncidentService) +- Store ConditionsDBAddress private data as GenericAddress private data + +============================================================================== +!20011126 - Andrea Valassi +A few changes before including my data service in GaudiSvc. +- Move ConditionData from DetCond/src/Lib to DetCondExample + > only DataObjects are manipulated, with dynamic casts to IValidity + > no Lib anymore in DetCond/src +- Manipulate ITime and TimePoint objects rather than ITime pointers + > add bool method to check if the event time is defined in ConditionDataSvc + +============================================================================== +!20011123 - Andrea Valassi +Upgrade to Gaudi v9 +- Addresses now inherit from GenericAddress (which has been simplified a lot) +- There are no address factories any more +- Adapt to changes in RegistryEntry (which now implements IRegistry) +- Add dummy methods fillObjRefs and updateObjRefs in ConditionsDBCnvSvc +- Notify (by flag "true") ServiceLocator to create services not existing yet +Requirements v2, private tag h20011123. + +============================================================================== +!20010914 - Andrea Valassi +New package. +Requirements v1, private tag v1. + diff --git a/Det/DetCond/options/UseOracle.py b/Det/DetCond/options/UseOracle.py new file mode 100644 index 000000000..142aec20d --- /dev/null +++ b/Det/DetCond/options/UseOracle.py @@ -0,0 +1,3 @@ +# Additional options for accessing Oracle conditions DB. +from Configurables import CondDB +CondDB(UseOracle = True) diff --git a/Det/DetCond/python/DetCond/Configuration.py b/Det/DetCond/python/DetCond/Configuration.py new file mode 100755 index 000000000..038fa6b7e --- /dev/null +++ b/Det/DetCond/python/DetCond/Configuration.py @@ -0,0 +1,788 @@ +""" +High level configuration tools for Conditions Database. +""" +__author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>" + +from Gaudi.Configuration import allConfigurables, ConfigurableUser, importOptions, getConfigurable, log +from Configurables import ( CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBCnvSvc, + CondDBSQLiteCopyAccSvc, + CondDBLogger, + COOLConfSvc, + ApplicationMgr ) + +import os, re +from os.path import exists, join + +class CondDB(ConfigurableUser): + """ + Configurable user to allow high-level configuration of the access to the + conditions database. + """ + __slots__ = { "Tags" : {}, + "Simulation" : False, + "Upgrade" : False, + "UseOracle" : False, + "LocalTags" : {}, + "LogFile" : "", + "Overrides" : [], + "PartitionConnectionString": {}, + "SQLiteLocalCopiesDir": "", + "OverwriteSQLiteLocalCopy": False, + "DisableLFC" : False, + "Online" : False, + "IgnoreHeartBeat": False, + "HeartBeatCondition" : "/Conditions/Online/LHCb/Tick", + "EnableRunStampCheck": False, + "RunStampCondition": "", + "LatestGlobalTagByDataType" : "", + "LatestGlobalTagByDataTypes" : [], + "LatestLocalTagsByDataType": [], + "AllLocalTagsByDataType": [], + "UseLatestTags" : [], + "QueryGranularity" : 0, + "UseDBSnapshot" : False , + "DBSnapshotDirectory" : "/group/online/hlt/conditions" , + 'EnableRunChangeHandler' : False, + 'RunChangeHandlerConditions' : { 'online_%d.xml' : [ "Conditions/Online/LHCb/Magnet/Set" + , "Conditions/Online/Velo/MotionSystem" + , "Conditions/Online/LHCb/Lumi/LumiSettings" + , "Conditions/Online/LHCb/LHCFillingScheme" + , "Conditions/Online/LHCb/RunParameters" + , "Conditions/Online/Rich1/R1HltGasParameters" + , "Conditions/Online/Rich2/R2HltGasParameters" ] }, + 'LoadCALIBDB' : "OFFLINE" + } + _propertyDocDct = { + 'Tags' : """ Dictionary of tags (partition:tag) to use for the COOL databases """, + 'Simulation' : """ Boolean flag to select the simulation or real-data configuration """, + 'Upgrade' : """ Boolean flag to select the Upgrade simulation configuration """, + 'UseOracle' : """ Boolean flag to enable the usage of the CondDB from Oracle servers. NB: Obsolete as Oracle support is now dropped""", + 'LocalTags' : """ Dictionary with local tags to use to override the global ones (partition: list of local tags) """, + 'LogFile' : """ Record the requests to the database the specified file """, + 'Overrides' : """ Internal property used to add layers or alternatives """, + 'PartitionConnectionString' : """ Dictionary with alternative connection strings for the CondDB partitions """, + 'SQLiteLocalCopiesDir' : """ The directory where to copy the SQLite files before accessing them """, + 'OverwriteSQLiteLocalCopy' : """ When using SQLite local copies, overwrite existing files """, + 'DisableLFC' : """ Do not use LFC lookup even if we are connecting to Oracle """, + 'Online' : """ Flag to activate configuration options specific for the Online environment """, + 'IgnoreHeartBeat' : """ Do not set the HeartBeatCondition for the Online partition """, + 'HeartBeatCondition' : """ Location of the heart-beat condition in the database """, + 'EnableRunStampCheck': """ Enable the check for the special RunStamp condition """, + 'RunStampCondition': """ Path (in the CondDB) to the special RunsTamp condition. """, + 'LatestGlobalTagByDataType' : """ Use latest CondDB global tag marked with the data type""", + 'LatestGlobalTagByDataTypes' : """ Use latest CondDB global tag marked with the data type, will override LatestGlobalTagByDataType if set""", + 'LatestLocalTagsByDataType' : """ Use all latest CondDB local tags marked with the data type """, + 'AllLocalTagsByDataType' : """ Use all CondDB local tags marked with the data type """, + 'UseLatestTags' : """ List of the form [DataType, OnlyGlobalTags = False] to turn on the usage of the latest tags """, + 'QueryGranularity': """Granularity of the query in the database (in time units)""", + 'LoadCALIBDB': """ Load CALIB*.db file as additional layers on top of ONLINE-*.db file, could be either "HLT1" (w/o layering, ONLINE only), or "OFFLINE" (Layer CALIBOFF above CALIB & ONLINE ), Do not set it for the Online environment""", + } + LAYER = 0 + ALTERNATIVE = 1 + # List of known implementations of ICondDBReader (str is used for backward compatibility) + __CondDBReaders__ = [ CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc, + str ] + + def _checkOverrideArgs(self, accessSvc, connStr, dbFile, dbName): + """ + Check if the accessSvc is a valid CondDBReader or build one using the + other arguments. + """ + kwargs = { "accessSvc": accessSvc, "connStr": connStr, "dbFile": dbFile, "dbName": dbName } + if accessSvc is None: + if not connStr: + if dbFile: + if not dbName: + dbName = os.path.basename(dbFile) + m = re.match(r'([A-Z][A-Z0-9_]{0,7})(_\w+)?.db', dbName) + if m: + dbName = m.group(1) + else: + raise ValueError('invalid arguments %r' % kwargs) + connStr = "sqlite_file:%s/%s" % (dbFile, dbName) + else: + raise ValueError('invalid arguments %r' % kwargs) + name = dbName + else: + name = connStr.rsplit('/')[-1] + if not re.match(r'[A-Z][A-Z0-9_]{0,7}', name): + name = 'CondDBAccessSvc' + # make a unique name for the configurable + name = "automatic_" + name + name_format = name + '_%d' + i = 0 + while name in allConfigurables: + i += 1 + name = name_format % i + accessSvc = CondDBAccessSvc(name, ConnectionString = connStr) + elif type(accessSvc) not in __CondDBReaders__: # Check for supported types + raise TypeError("'%s' not supported as CondDBReader"%accessSvc.__class__.__name__) + return accessSvc + + def addLayer(self, accessSvc = None, connStr = None, dbFile = None, dbName = None): + """ + Add the given CondDBReader as a layer on top of the existing configuration. + + Example: + CondDB().addLayer(myDB) + """ + # Check the arguments and/or prepare a valid access svc + accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) + self.Overrides.append((self.LAYER, accessSvc)) + def _addLayer(self, accessSvc): + cnvSvc = allConfigurables["CondDBCnvSvc"] + + originalReader = cnvSvc.CondDBReader + if type(originalReader) == CondDBLayeringSvc: + # If the original reader is already a layering svc, we can extend the + # configuration. + originalReader.Layers.insert(0,accessSvc) + else: + # We have to create a new layering svc. + name = "CondDBLayeringSvc" + i = 0 + while name in allConfigurables: + i += 1 + name = "CondDBLayeringSvc_%d"%i + cnvSvc.CondDBReader = CondDBLayeringSvc(name, + Layers = [accessSvc, + originalReader]) + + def addAlternative(self, accessSvc = None, path = None, connStr = None, dbFile = None, dbName = None): + """ + Add the given CondDBReader as an alternative to the existing configuration + for the specified path. + + Example: + CondDB().addAlternative(myDB,"/Conditions/MyDetector/Alignment") + """ + if path is None: + raise ValueError("'path' must be specified") + # Check the arguments and/or prepare a valid access svc + accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) + self.Overrides.append((self.ALTERNATIVE, accessSvc, path)) + + def _addAlternative(self, accessSvc, path): + cnvSvc = allConfigurables["CondDBCnvSvc"] + + originalReader = cnvSvc.CondDBReader + if type(originalReader) == CondDBDispatcherSvc: + # If the original reader is already a dispatcher, we can extend the + # configuration: + originalReader.Alternatives[path] = accessSvc + else: + # We have to create a new dispatcher + name = "CondDBDispatcherSvc" + i = 0 + while name in allConfigurables: + i += 1 + name = "CondDBDispatcherSvc_%d"%i + cnvSvc.CondDBReader = CondDBDispatcherSvc(name, + MainAccessSvc = originalReader, + Alternatives = { path: accessSvc } + ) + + def useLatestTags(self, DataType, OnlyGlobalTags = False): + self.UseLatestTags = [DataType, OnlyGlobalTags] + + def _useLatestTags(self, DataTypes, OnlyGlobalTags = False, OnlyLocalTags = False): + """ + Configure the conditions database to use the latest local tags on top of the latest global tag for a given data type. + """ + # Check arguments + if type(DataTypes) is not list: + DataTypes = [DataTypes] + + # Check if the latest tags should be set for simulation or not + if not self.getProp("Simulation"): + partitions = ["DDDB", "LHCBCOND", "DQFLAGS"] + if os.environ['LoadCALIBDB'] is "OFFLINE": + partitions += ["CALIBOFF"] + else: + partitions = ["DDDB", "SIMCOND"] + + # Set the latest tags + from CondDBUI.Admin.TagsFilter import last_gt_lts + rel_notes = None + if self.getProp('Upgrade'): + rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') + + for partition in partitions: + gt, lts = None, [] + for dt in DataTypes: + tags = last_gt_lts(partition, dt, rel_notes) + if not tags: + # Allowing absence of valid tags for DQFLAGS + if partition == 'DQFLAGS': continue + # Allowing absence of valid tags for CALIBOFF before 2015 + elif partition == 'CALIBOFF' and dt.isdigit() and int(dt)<2015: continue + else: + raise RuntimeError("Cannot find tags for partition '%s'," + " data type '%s'" % (partition, dt)) + if not gt: + gt = tags[0] + lts += tags[1] + + if not OnlyLocalTags and gt: # Only for partitions with available global tags + self.Tags[partition] = gt + if not OnlyGlobalTags and lts: + if partition in self.LocalTags: self.LocalTags[partition] += lts + else: self.LocalTags[partition] = lts + + def _useAllLocalTags(self, DataTypes): + """ + Configure the conditions database to use all local tags for a given data type. + """ + + # Check arguments + if type(DataTypes) is not list: + DataTypes = [DataTypes] + + # Check if the latest tags should be set for simulation or not + if not self.getProp("Simulation"): + partitions = ["DDDB", "LHCBCOND"] + if os.environ['LoadCALIBDB'] is "OFFLINE": + partitions += ["CALIBOFF"] + else: + partitions = ["DDDB", "SIMCOND"] + + # Set the latest tags + from CondDBUI.Admin.TagsFilter import all_lts + rel_notes = None + if self.getProp('Upgrade'): + rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') + + for partition in partitions: + local_tags = [] + for dt in DataTypes: + lts = all_lts(partition, dt, rel_notes) + if lts: local_tags += lts + if partition in self.LocalTags: self.LocalTags[partition] += local_tags + else: self.LocalTags[partition] = local_tags + + def __make_sqlite_local_copy__(self, accsvc, local_dir = None, force_copy = None): + if isinstance(accsvc, str): + # convert the string in an actual configurable instance + # This is both for backward compatibility and CondDBTimeSwitchSvc + if "/" in accsvc: + tp, name = accsvc.split("/",1) + else: + tp = name = accsvc + accsvc = getConfigurable(name, tp) + if local_dir is None: + local_dir = self.getProp("SQLiteLocalCopiesDir") + if force_copy is None: + force_copy = self.getProp("OverwriteSQLiteLocalCopy") + # If the directory for the local copies is not specified, we do nothing + if not local_dir: + return accsvc + # Check if we are using Oracle or SQLite +# if self.getProp("UseOracle"): +# log.warning("Conflicting properties in CondDB Configurable: " +# "ignoring SQLiteLocalCopiesDir because UseOracle is set to True") +# return accsvc + # Modify partitions to use local copies of the DBs + newaccsvc = accsvc # fallback return value (no change) + if isinstance(accsvc, CondDBAccessSvc): + # replace the reader with another + m = re.match(r"^sqlite_file:(.*)/([_0-9A-Z]{1,8})$", + accsvc.getProp("ConnectionString")) + if not m: # not SQLite connection string + return accsvc + newaccsvc = CondDBSQLiteCopyAccSvc(accsvc.name() + "_local") + newaccsvc.OriginalFile = m.group(1) + newaccsvc.DestinationFile = os.path.join(local_dir, + os.path.basename(m.group(1))) + newaccsvc.DBName = m.group(2) + newaccsvc.ForceCopy = force_copy + newaccsvc.IgnoreCopyError = not force_copy # ignore copy errors if we do not overwrite (needed for local tags) + if hasattr(accsvc, "CacheHighLevel"): + newaccsvc.CacheHighLevel = accsvc.CacheHighLevel + elif isinstance(accsvc, CondDBDispatcherSvc): + # use the same dispatcher replacing its content + mainAccSvc = accsvc.getProp("MainAccessSvc") + accsvc.MainAccessSvc = self.__make_sqlite_local_copy__(mainAccSvc, local_dir) + alternatives = accsvc.getProp("Alternatives") + for alt in alternatives.keys(): + accsvc.Alternatives[alt] = \ + self.__make_sqlite_local_copy__(alternatives[alt], local_dir) + elif isinstance(accsvc, CondDBLayeringSvc): + # use the same layering service replacing its content + new_layers = [] + for layer in accsvc.getProp("Layers"): + new_layers.append(self.__make_sqlite_local_copy__(layer, local_dir)) + accsvc.Layers = new_layers + elif isinstance(accsvc, CondDBTimeSwitchSvc): + # use the same time switcher replacing its content, + # but we need to parse its options (in format "'%s':(%d,%d)") + readers_list = accsvc.getProp("Readers") + new_readers = [] + for line in readers_list: + # Parse the line for the reader (it looks like "'name':(0,1)") + r, iov = map(eval, line.rsplit(":")) + new_reader = self.__make_sqlite_local_copy__(r, local_dir) + new_readers.append("'%s':(%d,%d)" % + (new_reader.getFullName(), iov[0], iov[1])) + accsvc.Readers = new_readers + elif isinstance(accsvc, CondDBLogger): + # use the same logger replacing its content + logged = accsvc.getProp("LoggedReader") + accsvc.LoggedReader = self.__make_sqlite_local_copy__(logged, local_dir) + elif isinstance(accsvc, CondDBCnvSvc): + # use the same conversion service replacing its content + reader = accsvc.getProp("CondDBReader") + accsvc.CondDBReader = self.__make_sqlite_local_copy__(reader, local_dir) + return newaccsvc + + def _configureDBSnapshot(self): + + baseloc = self.getProp( "DBSnapshotDirectory" ) + self.DisableLFC = True + + # Set alternative connection strings and tags + # if simulation is False, we use DDDB, LHCBCOND and ONLINE + # True DDDB, SIMCOND + # (see Det/DetCond's configurable... ) + dbPartitions = { False : [ "DDDB", "LHCBCOND", "ONLINE" ] + , True : [ "DDDB", "SIMCOND" ] + } + + tag = self.getProp("Tags") + for part in dbPartitions[ self.getProp('Simulation') ] : + if tag[part] is 'default' : raise KeyError('must specify an explicit %s tag'%part) + self.PartitionConnectionString[part] = "sqlite_file:%(dir)s/%(part)s_%(tag)s.db/%(part)s" % {"dir": baseloc, + "part": part, + "tag": tag[part]} + self.Tags[part] = tag[part] + + # Set the location of the Online run-by-run conditions + if self.getProp('EnableRunChangeHandler') : + from Configurables import RunChangeHandlerSvc + rch = RunChangeHandlerSvc() + rch.Conditions = dict( (c,'/'.join([baseloc,f])) for f,cs in self.getProp("RunChangeHandlerConditions").iteritems() for c in cs ) + ApplicationMgr().ExtSvc.append(rch) + + def __apply_configuration__(self): + """ + Converts the high-level information passed as properties into low-level configuration. + """ + # special case for online + if self.getProp('UseDBSnapshot') : self._configureDBSnapshot() + + # In the Online/Upgrade/Simulation environment, LoadCALIBDB should be defaulted to HLT1 + if self.getProp("Online") or self.getProp('Upgrade') or self.getProp('Simulation'): + self._properties["LoadCALIBDB"].setDefault("HLT1") + # Set up environment variables for loading CALIBOFF layers, must be before loading any tags + LoadCALIBDB = self.getProp('LoadCALIBDB') + loadcaliboptions = ["HLT1", "OFFLINE"] + if LoadCALIBDB not in loadcaliboptions: + raise ValueError("'%s' is not a valid LoadCALIBDB value. Allowed: %s" %(LoadCALIBDB, loadcaliboptions)) + if LoadCALIBDB is "OFFLINE" and not exists(join(os.environ["SQLITEDBPATH"], "CALIBOFF.db")): + LoadCALIBDB = "HLT1" # When CALIBOFF.db is not there, reset the option + os.environ['LoadCALIBDB'] = LoadCALIBDB + + # Set the usage of the latest global/local tags + old_latest_Tags_prop = self.getProp("UseLatestTags") # it is deprecated + latest_GTags_prop = self.getProp("LatestGlobalTagByDataTypes") + if not latest_GTags_prop: # if property not set + latest_GTags_prop = self.getProp("LatestGlobalTagByDataType") + latest_LTags_prop = self.getProp("LatestLocalTagsByDataType") + all_LTags_prop = self.getProp("AllLocalTagsByDataType") + + if old_latest_Tags_prop: + if latest_GTags_prop or latest_LTags_prop: + log.warning("The property 'UseLatestTags' is deprecated:" + "'LatestGlobalTagByDataType(s)' and 'LatestLocalTagsByDataType'" + " will be used instead.") + else: + latest_GTags_prop = old_latest_Tags_prop[0] + if type(old_latest_Tags_prop[-1]) != bool or \ + (type(old_latest_Tags_prop[-1]) == bool and not old_latest_Tags_prop[1]): + latest_LTags_prop = old_latest_Tags_prop[0] + + if latest_GTags_prop: + datatype = latest_GTags_prop + if self.getProp("Tags"): + self.Tags = {} + self._useLatestTags(datatype, OnlyGlobalTags = True) + log.warning("Default global tags will be overridden with the latest ones" + " available for '%s' data type: %s"%(datatype, self.getProp("Tags")) ) + + if latest_LTags_prop: + datatypes = latest_LTags_prop + #if self.getProp("LocalTags"): + # self.LocalTags = {} + self._useLatestTags(datatypes, OnlyLocalTags = True) + log.warning("Latest unbound local tags on top of the latest global tags" + " of %s data type(s) are added: %s" + %(datatypes, self.getProp("LocalTags"))) + + if all_LTags_prop: + datatypes = all_LTags_prop + self._useAllLocalTags(datatypes) + log.warning("ALL local tags of %s data type(s) are added: %s" + %(datatypes, self.getProp("LocalTags"))) + + # Import SQLDDDB specific info + if self.getProp("UseOracle"): + CondDBAccessSvc("ONLINE", ConnectionString = "CondDBOnline/ONLINE") + if self.getProp("DisableLFC"): + COOLConfSvc(UseLFCReplicaSvc = False) + elif self.getProp('UseDBSnapshot'): + CondDBAccessSvc("ONLINE") + else: + configureOnlineSnapshots() +# importOptions("$SQLDDDBROOT/options/SQLDDDB.py") + + ######################################################################### + # Access to ConditionsDB + ########################################################################## + conns = self.getProp("PartitionConnectionString") + tags = self.getProp("Tags") + # DB partitions + partition = {} + parttypes = [ ("DDDB", CondDBAccessSvc), + ("LHCBCOND", CondDBAccessSvc), + ("ONLINE", CondDBTimeSwitchSvc), + ("SIMCOND", CondDBAccessSvc), + ("DQFLAGS", CondDBAccessSvc)] + if LoadCALIBDB is "OFFLINE": + # CALIBOFF not needed for the upgrade + parttypes += [("CALIBOFF", CondDBAccessSvc)] + + for (p ,t) in parttypes: + partition[p] = getAnyDBReader(p, t) + # Override connection strings: + if p in conns: + if type(partition[p]) is CondDBAccessSvc: + partition[p].ConnectionString = conns[p] + del conns[p] + + # Override connection strings for Upgrade case + if self.getProp('Simulation') and self.getProp('Upgrade') and type(partition[p]) is CondDBAccessSvc: + partition[p].ConnectionString = os.path.join('sqlite_file:$SQLITEUPGRADEDBPATH', p + '.db', p) + # Override tags + if p in tags and p != "ONLINE": + partition[p].DefaultTAG = tags[p] + del tags[p] + # Set the query granularity + if p != "CALIBOFF": self.propagateProperty("QueryGranularity", partition[p]) + if type(partition[p]) is CondDBTimeSwitchSvc: # also online + for r in partition[p].Readers: + config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] + if isinstance(config, CondDBAccessSvc): + self.propagateProperty("QueryGranularity", config) + # Pass along the configuration for the layered DBs + elif isinstance(config, CondDBLayeringSvc): + for ly in config.Layers: + if isinstance(ly, CondDBAccessSvc): + self.propagateProperty("QueryGranularity", ly) + + if conns: + log.warning("Cannot override the connection strings of the partitions %r", conns.keys()) + if tags and tags.keys()!=['ONLINE']: + log.warning("Cannot set the tag for partitions %r", tags.keys()) + + # In the Online environment, IgnoreHeartBeat should be defaulted to True + if self.getProp("Online"): + self._properties["IgnoreHeartBeat"].setDefault(True) + if not self.getProp("IgnoreHeartBeat"): + if isinstance(partition["ONLINE"], CondDBAccessSvc): + self.propagateProperty("HeartBeatCondition", partition["ONLINE"]) + elif isinstance(partition["ONLINE"], CondDBTimeSwitchSvc): + # Add the heart beat conditions to the latest snapshot only since the + # others are limited but valid by construction. + if partition["ONLINE"].Readers: + latest = partition["ONLINE"].Readers[-1] + config = allConfigurables[eval(latest.split(':')[0]).split("/")[1]] + if isinstance(config, CondDBAccessSvc): + self.propagateProperty("HeartBeatCondition", config) + # Pass along the configuration for the layered DBs + elif isinstance(config, CondDBLayeringSvc): + for ly in config.Layers: + #Only apply HeartBeatCondition for ONLINE + if isinstance(ly, CondDBAccessSvc) and ly.getName().startswith("ONLINE_"): + self.propagateProperty("HeartBeatCondition", ly) + + if not self.getProp("Simulation"): + # Standard configurations + # - Reconstruction / analysis + disp = CondDBDispatcherSvc("MainCondDBReader", + MainAccessSvc = partition["DDDB"], + Alternatives = { + "/Conditions": partition["LHCBCOND"], + "/Conditions/Online": partition["ONLINE"], + "/Conditions/DQ": partition["DQFLAGS"] + }) + else: + # - Simulation + disp = CondDBDispatcherSvc("SimulationCondDBReader", + MainAccessSvc = partition["DDDB"], + Alternatives = { + "/Conditions": partition["SIMCOND"] + }) + CondDBCnvSvc( CondDBReader = disp ) + + if not (self.getProp("Online") or self.getProp("Simulation")): + self._properties["EnableRunStampCheck"].setDefault(True) + if self.getProp("EnableRunStampCheck"): + from Configurables import RunStampCheck + rsc = RunStampCheck() + self.propagateProperty("RunStampCondition", rsc) + ApplicationMgr().ExtSvc.append(rsc) + + # Load the CALIBOFF layer above everything if it exists +# if len([x for x in parttypes if x[0] == 'CALIBOFF']): +# self._addLayer(getAnyDBReader('CALIBOFF')) + + localTags = self.getProp("LocalTags") + not_applied = [] + for p in localTags: + if p in partition: + taglist = list(localTags[p]) + taglist.reverse() # we need to stack the in reverse order to use the first as on top of the others + i = 0 # counter + if p is "CALIBOFF": + if LoadCALIBDB is not "OFFLINE": + raise ValueError("invalid argument LoadCALIBDB set at '%s' instead of 'OFFLINE' for accessing local tags for CALIBOFF.db" % LoadCALIBDB) + pcolayers = [] + for t in taglist: + pcolayers.append(partition[p].clone("CALIBOFF_%d" %i, DefaultTAG = t)) + i += 1 + for r in partition["ONLINE"].Readers: + config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] + if isinstance(config, CondDBLayeringSvc): + config.Layers = pcolayers + config.Layers + elif type(partition[p]) is not CondDBTimeSwitchSvc: + for t in taglist: + self._addLayer(partition[p].clone("%s_%d" % (p, i), + DefaultTAG = t)) + i += 1 + else: + not_applied.append(p) + else: + not_applied.append(p) + if not_applied: + log.warning("Cannot set the local tags for partitions %r", not_applied) + + # Modify partitions to use local copies of the DBs + # before adding user layers and alternatives, which should be already local. + # This is a no-operation if the property is not set + self.__make_sqlite_local_copy__(CondDBCnvSvc()) + + # Add layers and alternatives + call = { self.LAYER : self._addLayer, + self.ALTERNATIVE : self._addAlternative } + for override in self.getProp("Overrides"): + apply(call[override[0]], override[1:]) + + # Add the logger + filename = self.getProp("LogFile") + if filename: + cnvSvc = allConfigurables["CondDBCnvSvc"] + cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader, + LogFile = filename) + + # Suppress pointless warning from COOL_2_5_0 + msgSvc = getConfigurable("MessageSvc") + msgSvc.setError.append("RelationalDatabase") + + # Set up Virtual File System service, can be used by ParticlePropertySvc + from Gaudi.Configuration import VFSSvc + from Configurables import CondDBEntityResolver + VFSSvc().FileAccessTools.append(CondDBEntityResolver()) + + +# Exported symbols +__all__ = [ "addCondDBLayer", "addCondDBAlternative", "useCondDBLogger", + "configureOnlineSnapshots" ] +# Configurables provided by the package +__all__ += [ "CondDBAccessSvc", + "CondDBDispatcherSvc", "CondDBLayeringSvc", "CondDBTimeSwitchSvc", + "CondDBSQLiteCopyAccSvc", "CondDBLogger", + "CondDBCnvSvc", + "CondDB" ] + +# List of known implementations of ICondDBReader (str is used for backward compatibility) +__CondDBReaders__ = [ CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc, + str ] + +def _assertConfig(funcname): + """ + Check if the default configuration has been loaded. + """ + if "CondDBCnvSvc" not in allConfigurables: + raise RuntimeError("You cannot call '%s' before the standard CondDB configuration"%funcname) + +def addCondDBLayer(accessSvc): + """ + Add the given CondDBReader as a layer on top of the existing configuration. + + Example: + addCondDBLayer(myDB) + """ + DetCond().addLayer(accessSvc) + +def addCondDBAlternative(accessSvc, path): + """ + Add the given CondDBReader as an alternative to the existing configuration + for the specified path. + + Example: + addCondDBAlternative(myDB,"/Conditions/MyDetector/Alignment") + """ + DetCond().addAlternative(accessSvc, path) + +def useCondDBLogger(filename = None, logger = None): + """ + Add the CondDBLogger to the chain of CondDBReaders. + + The simplest usage is to call the function without options (use defaults), or + pass a file name. + """ + _assertConfig('useCondDBLogger') + cnvSvc = allConfigurables["CondDBCnvSvc"] + if logger is None: + # use the default configuration + cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader) + elif type(logger) is CondDBLogger: + # use the user-provided configurable + logger.LoggedReader = cnvSvc.CondDBReader + cnvSvc.CondDBReader = logger + else: + raise TypeError("useCondDBLogger does not support '%s'"%logger.__class__.__name__) + # Use the user specified filename, if any + if filename: + cnvSvc.CondDBReader.LogFile = filename + +def _timegm(t): + """Inverse of time.gmtime. Implementation from Gaudi::Time.""" + import time + if t[8] != 0: # ensure that dst is not set + t = tuple(list(t[0:8]) + [0]) + t1 = time.mktime(t) + gt = time.gmtime(t1) + t2 = time.mktime(gt) + return t1 + (t1 - t2) + +def defConnStrFunc(ym_tuple): + return self.connStrOnline(ym_tuple) + +def connStrOnline(ym_tuple): + dbpath = os.environ["SQLITEDBPATH"] + if exists(join(dbpath, "ONLINE-%04d%02d.db" % ym_tuple)): + return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d%02d.db/ONLINE" % ym_tuple + return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d.db/ONLINE" % ym_tuple[0] + +def getAnyDBReader(layer = 'CALIBOFF', svc = CondDBAccessSvc): + CacheHighLevel = 200 + if layer == 'DDDB' : CacheHighLevel = 1700 + # Put the discovered layer on top + cfg = getConfigurable(layer, svc) + if svc is not CondDBAccessSvc: return cfg + try: cfg.ConnectionString + except AttributeError: # Set up connection for the 1st time + connstr = "sqlite_file:$SQLITEDBPATH/%s.db/%s" % (layer, layer) + if layer == 'DQFLAGS' : + cfg = CondDBAccessSvc(layer, ConnectionString = connstr, + CacheLowLevel = 5, CacheHighLevel = 10) + else: + cfg = CondDBAccessSvc(layer, ConnectionString = connstr, + CacheHighLevel = CacheHighLevel) + return cfg + +def getOnlineDBReader(ym_tuple, granularity = 'YEARLY', connStrFunc = None): + cnstr = '' + ymstr = '' + if granularity == 'YEARLY': + ymstr = "%04d" %ym_tuple[0] + cnstr = connStrFunc((ym_tuple[0],13)) + else: + ymstr = "%04d%02d" %ym_tuple + cnstr = connStrFunc(ym_tuple) + + ptnm = "ONLINE_" + ymstr + accSvc = CondDBAccessSvc(ptnm, ConnectionString = cnstr) + dblayers = [ accSvc ] + LoadCALIBDB = os.environ.get('LoadCALIBDB') + if ym_tuple[0] < 2015 or LoadCALIBDB is not "OFFLINE": # For datatype before 2015, no CALIBOFF layer is needed + return accSvc + dbpath = os.environ["SQLITEDBPATH"] + layer = 'CALIBOFF' + if exists(join(dbpath, layer + '.db')): + # Put the discovered layer on top + cfg = getConfigurable(layer, CondDBAccessSvc) + try: cfg.ConnectionString + except AttributeError: # Set up connection for the 1st time + cfg = CondDBAccessSvc("CALIBOFF", ConnectionString = + cnstr.replace('ONLINE-%s.db/ONLINE' %ymstr, "%s.db/%s" % (layer, layer)), CacheHighLevel = 200) + dblayers.insert(0, cfg) + + if (len(dblayers) == 1): return accSvc # In case no CALIBOFF.db is found + return CondDBLayeringSvc("ONLINELAYER_"+ymstr, Layers = dblayers ) + +def configureOnlineSnapshots(start = None, end = None, connStrFunc = None): + if connStrFunc is None: + connStrFunc = connStrOnline + + # prepare the configurable instance + ONLINE = CondDBTimeSwitchSvc("ONLINE") + + # Default snapshots granularity + granularity = 'YEARLY' + + # Set the first available snapshot pair: per-year by default + if start is None: + first_snapshot = (2008, None) + else: + first_snapshot = start + + # Set the last available snapshot pair: current year by default + if end is None: + import time + last_snapshot = (time.gmtime()[0], None) + else: + last_snapshot = end + + # If last snapshot is per-month switch the first one to be also per-month + if last_snapshot[1]: + granularity = 'MONTHLY' + first_snapshot = (2008, 6) + + # reset the list of readers, for safety + ONLINE.Readers = [] + # loop from first to last-1 + i = first_snapshot + until = 0 # this makes the first service used from times starting from 0 + while i < last_snapshot: + accSvc = getOnlineDBReader(i, granularity, connStrFunc) + since = until + # increment + if granularity == 'YEARLY': + i = (i[0]+1, None) + until = int(_timegm(tuple([i[0], 1, 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 + else: + if i[1] == 12: i = (i[0]+1,1) + else: i = (i[0],i[1]+1) + until = int(_timegm(tuple([i[0], i[1], 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 + descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) + ONLINE.Readers.append(descr) + + # append the last database with validity extended to the maximum validity + accSvc = getOnlineDBReader(i, granularity, connStrFunc) + since = until + until = 0x7fffffffffffffffL # Defined in PyCool.cool as ValidityKeyMax + descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) + ONLINE.Readers.append(descr) diff --git a/Det/DetCond/python/DetCond/HistoCond.py b/Det/DetCond/python/DetCond/HistoCond.py new file mode 100644 index 000000000..c89d49911 --- /dev/null +++ b/Det/DetCond/python/DetCond/HistoCond.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# ============================================================================= +## @file DetCond/HistoCond.py +# Decorate the Condition object with functions to extract 1d and 2d-histograms +# @authorVanya BELYAEV Ivan.Belyaev@nikhef.nl +# @date 2009-12-01 +# ============================================================================= +""" +Decorate the Condition object with functions to extract 1d and 2d-histograms, and +define functions to convert 1d and 2d histograms to Condition parameter strings. +""" +# ============================================================================= +__author__ = "Vanya BELYAEV Ivan.Belyaev@nikhef.nl and Dmitry Golubkov" +__version__ = "CVS Tag $Name: not supported by cvs2svn $, verison $Revision: 1.1 $" +# ============================================================================= +# export nothing +__all__ = () ## export nothing +# ============================================================================= + +## import HistoStrings.Histos +from GaudiPython.Bindings import gbl as cpp + +_C = cpp.Condition +# ============================================================================= +## function to convert 1D histogram to an xml param string +def histo1DAsParam ( h1d, name = 'name', comment = 'comment' ) : + """ + Convert 1D histogram to an xml param string + """ + param_head = '\n <param name = "%s" type = "Histo1D" comment="%s">\n' + param_tail = '\n </param>\n' + + return param_head % (name, comment) + h1d.toString() + param_tail +# ============================================================================= +## function to convert 2D histogram to an xml param string +def histo2DAsParam ( h2d, name = 'name', comment = 'comment' ) : + """ + Convert 2D histogram to an xml param string + """ + param_head = '\n <param name = "%s" type = "Histo2D" comment="%s">\n' + param_tail = '\n </param>\n' + + return param_head % (name, comment) + h2d.toString() + param_tail +# ============================================================================= +## decorate the condition object: +if not hasattr ( _C , 'paramAsH1' ) : + + _F1 = cpp.DetDesc.Params.paramAsHisto1D + + # ========================================================================= + ## Extract the 1D-histogram form condition objects + # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + # @date 2009-12-01 + def _paramAsH1_ ( self , name ) : + """ + Extract the 1D-histiogram from condition objects + + >>> cond = ... ## get the condition object + >>> name = ... ## the name + + >>> h1 = cond.paramAsH1 ( name ) + >>> h1 = cond.paramAsHisto1D ( name ) # same as Condition.paramAsH1 + """ + return _F1 ( self , name ) + + _paramAsH1_ . __doc__ += '\n' + _F1 . __doc__ + _C .paramAsH1 = _paramAsH1_ + _C .paramAsHisto1D = _paramAsH1_ + +# ============================================================================= +## decorate the condition object: +if not hasattr ( _C , 'paramAsH2' ) : + + _F2 = cpp.DetDesc.Params.paramAsHisto2D + + # ========================================================================= + ## Extract the 2D-histogram form condition objects + # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + # @date 2009-12-01 + def _paramAsH2_ ( self , name ) : + """ + Extract the 2D-histiogram from condition objects + + >>> cond = ... ## get the condition object + >>> name = ... ## the name + + >>> h2 = cond.paramAsH2 ( name ) + >>> h2 = cond.paramAsHisto2D ( name ) # same as Condition.paramAsH2() + """ + return _F2 ( self , name ) + + _paramAsH2_ . __doc__ += '\n' + _F2 . __doc__ + _C .paramAsH2 = _paramAsH2_ + _C .paramAsHisto2D = _paramAsH2_ + +if '__main__' == __name__ : + + print __doc__ + print __author__ + print __version__ + +# ============================================================================= +# The END +# ============================================================================= diff --git a/Det/DetCond/python/DetCond/__init__.py b/Det/DetCond/python/DetCond/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Det/DetCond/src/Lib/CondDBGenericCnv.cpp b/Det/DetCond/src/Lib/CondDBGenericCnv.cpp new file mode 100755 index 000000000..b83b90922 --- /dev/null +++ b/Det/DetCond/src/Lib/CondDBGenericCnv.cpp @@ -0,0 +1,139 @@ +// Include files +#include "GaudiKernel/IDetDataSvc.h" +#include "GaudiKernel/Time.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/IValidity.h" +#include "GaudiKernel/DataObject.h" + +#include "DetDesc/IDetectorElement.h" +#include "DetDesc/ValidDataObject.h" + +#include "CoolKernel/ValidityKey.h" +#include "CoolKernel/IFolder.h" +#include "CoolKernel/IObject.h" +#include "CoolKernel/IDatabase.h" +#include "CoolKernel/Exception.h" + +// local +#include "DetCond/CondDBGenericCnv.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBGenericCnv +// +// 2004-12-03 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBGenericCnv::CondDBGenericCnv(ISvcLocator* svc,const CLID& clid): + Converter(CONDDB_StorageType,clid,svc) +{} +//============================================================================= +// Destructor +//============================================================================= +CondDBGenericCnv::~CondDBGenericCnv() = default; + +//========================================================================= +// Initialization +//========================================================================= +StatusCode CondDBGenericCnv::initialize() { + // Initializes the grand father + StatusCode sc = Converter::initialize(); + + // Query the IDetDataSvc interface of the detector data service + m_detDataSvc = serviceLocator()->service("DetectorDataSvc"); + if( !sc.isSuccess() ) { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + log << MSG::ERROR << "Can't locate DetectorDataSvc" << endmsg; + return sc; + } else { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Succesfully located DetectorDataSvc" << endmsg; + } + // Get a pointer to the CondDBReader (implemented by the conversion service) + m_condDBReader.reset( conversionSvc().get() ); + if ( !m_condDBReader ) { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + log << MSG::ERROR << "The conversion service does not implement ICondDBReader!" << endmsg; + return StatusCode::FAILURE; + } + + return sc; +} + +//========================================================================= +// Finalization +//========================================================================= +StatusCode CondDBGenericCnv::finalize() { + m_detDataSvc.reset(); + m_condDBReader.reset(); + return Converter::finalize(); +} + +//========================================================================= +// Ask the event time to the DetectorDataSvc +//========================================================================= + +StatusCode CondDBGenericCnv::eventTime(Gaudi::Time &time) const { + if (!m_detDataSvc->validEventTime()){ + return StatusCode::FAILURE; + } + time = m_detDataSvc->eventTime(); + return StatusCode::SUCCESS; +} + +//========================================================================= +// Set the validity of the object +//========================================================================= +void CondDBGenericCnv::setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject){ + // Set validity of created object + IValidity* pValidity = dynamic_cast<IValidity*>(pObject); + + if ( pValidity != NULL ) { // it has a validity + + pValidity->setValidity(since, till); + + } else { + + // I cannot set the validity range + MsgStream log(msgSvc(),"CondDBGenericCnv"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG + << "Created object (CLID = " << pObject->clID() + << ") does not implement IValidity: cannot set validity" + << endmsg; + } +} + +//========================================================================= +// get an object from the conditions database +//========================================================================= +StatusCode CondDBGenericCnv::getObject (const std::string &path, const cool::ChannelId &channel, + ICondDBReader::DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until) { + + Gaudi::Time now; + StatusCode sc = eventTime(now); + if (sc.isFailure()) { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + log << MSG::ERROR << "Cannot create DataObject: event time undefined" << endmsg; + return sc; + } + + return m_condDBReader->getObject(path,now,data,descr,since,until,channel); +} + +//========================================================================= +// get get the list of nodes in a folderset from the conditions database +//========================================================================= +StatusCode CondDBGenericCnv::getChildNodes(const std::string &path,std::vector<std::string> &node_names){ + MsgStream log(msgSvc(),"CondDBGenericCnv"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; + + return m_condDBReader->getChildNodes(path,node_names); +} +//============================================================================= + diff --git a/Det/DetCond/src/component/COOLConfSvc.cpp b/Det/DetCond/src/component/COOLConfSvc.cpp new file mode 100755 index 000000000..384a0b8f0 --- /dev/null +++ b/Det/DetCond/src/component/COOLConfSvc.cpp @@ -0,0 +1,281 @@ +#ifdef __INTEL_COMPILER // Disable ICC remark from CORAL MessageStream and Boost + #pragma warning(disable:2259) +#endif + +// Include files +#include "RelationalAccess/ConnectionService.h" +#include "RelationalAccess/IConnectionServiceConfiguration.h" +#include "RelationalAccess/IReplicaSortingAlgorithm.h" +#include "RelationalAccess/IDatabaseServiceDescription.h" + +#include "CoolKernel/IDatabaseSvc.h" +#include "CoolApplication/Application.h" +#include "CoolApplication/DatabaseSvcFactory.h" + +#include "COOLConfSvc.h" + +#ifdef WIN32 +#define NOMSG +#define NOGDI +#endif + +// For the case insensitive string comparison (boost::algorithm::icontains). +#include "boost/algorithm/string/predicate.hpp" +// For random numbers not affecting simulation. +#include "boost/random/linear_congruential.hpp" +//#include "boost/random/uniform_smallint.hpp" +#include "boost/date_time/posix_time/posix_time_types.hpp" + +namespace +{ + + /** @class ReplicaSortAlg + * + * Small class implementing coral::IReplicaSortingAlgorithm interface to allow dynamic sorting of + * database replicas obtained from LFC. + * + * When retrieving the list of DB replicas, LFCReplicaService obtains a list in an arbitrary order. + * We have to provide to CORAL a class to be used to sort the list of replicas according to our + * needs. First we want the closest DB, identified by the environment variable LHCBPRODSITE, then + * the CERN server (LCG.CERN.ch), while the remaining one can be in any order (this implementation + * uses the natural string ordering). + * + * @author Marco Clemencic + * @date 2007-05-02 + */ + class ReplicaSortAlg: virtual public coral::IReplicaSortingAlgorithm + { + typedef coral::IDatabaseServiceDescription dbDesc_t; + typedef std::vector< const dbDesc_t * > replicaSet_t; + + /** @class ReplicaSortAlg::Comparator + * + * Comparison function defining which replica comes before another. + * + * This class is used via the STL algorithm "sort" to order the list the way we need it. + * + * @author Marco Clemencic + * @date 2007-05-02 + */ + class Comparator: public std::binary_function<const dbDesc_t*,const dbDesc_t*,bool> + { + typedef boost::rand48 RandomGenType; + typedef RandomGenType::result_type WeightType; + typedef std::map<std::string,WeightType> WeightMap; + + /// Site that have to be used before the others + std::string site; + /// Map used to remember the priority of the sites. + /// the local site has weight -1, the other are randomly chosen the first + /// time they are encountered. + mutable WeightMap weights; + /// Random number generator. Using Boost to avoid interactions with the + /// random generator services. + mutable RandomGenType gen; + + WeightType getWeight(const std::string& key) const { + WeightMap::iterator i = weights.find(key); + if ( weights.end() == i ) { // not found + WeightType newWeight = 0; + if (boost::algorithm::icontains(key,site)) { + // it means that this is the site with highest priority + newWeight = gen.max(); + } else { + // all other sites are distributed randomly + newWeight = gen(); + } + weights[key] = newWeight; + return newWeight; + } + return i->second; + } + + public: + + /// Constructor. + /// @param theSite the local LHCb Production Site (<i>SITE</i>.<i>country</i>) + Comparator(std::string theSite): + site(std::move(theSite)), + gen(// this is the rather longish Boost way of getting the current number of + // seconds since the beginning of the day... that I want to use as seed + // for the local random number generator (I do not use "seconds since epoch" + // because the boosted way of getting it is too long). + boost::posix_time::second_clock::universal_time().time_of_day().total_seconds()) + {} + + /// Main function + result_type operator() (first_argument_type a, second_argument_type b) const + { + return getWeight(a->serviceParameter(a->serverNameParam())) + < + getWeight(b->serviceParameter(b->serverNameParam())); + } + + }; + + std::string localSite; + MsgStream log; + + public: + + /// Constructor. + /// @param theSite the local LHCb Production Site (LCG.<i>SITE</i>.<i>country</i>) + ReplicaSortAlg(std::string theSite, IMessageSvc *msgSvc): + localSite(std::move(theSite)), + log(msgSvc,"ReplicaSortAlg") + { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Constructor" << endmsg; + } + + /// Destructor. + virtual ~ReplicaSortAlg() + { + // log << MSG::VERBOSE << "ReplicaSortAlg --> destructor" <<std::endl; + } + + /// Main function + virtual void sort (std::vector< const coral::IDatabaseServiceDescription * > &replicaSet) + { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { + log << MSG::VERBOSE << "Original list" << endmsg; + replicaSet_t::iterator i; + for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { + log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; + } + + log << MSG::VERBOSE << "Sorting..." << endmsg; + } + std::sort(replicaSet.begin(),replicaSet.end(),Comparator(localSite)); + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { + log << MSG::VERBOSE << "Sorted list" << endmsg; + replicaSet_t::iterator i; + for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { + log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; + } + } + } + + }; + +} + +// Factory implementation +DECLARE_SERVICE_FACTORY(COOLConfSvc) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +COOLConfSvc::COOLConfSvc(const std::string& name, ISvcLocator* svcloc): + base_class(name,svcloc) +{ + declareProperty("UseLFCReplicaSvc", m_useLFCReplicaSvc = false ); + declareProperty("LocalSite", m_localSite = "", + "The name of the site we are running on, used to order the " + "list of replicas in LFC."); + declareProperty("EnableCoralConnectionCleanUp", m_coralConnCleanUp = false ); + declareProperty("CoralConnectionRetrialPeriod", m_retrialPeriod = 60, + "Time between two connection trials (in seconds)."); + declareProperty("CoralConnectionRetrialTimeOut", m_retrialTimeOut = 15*60, + "How long to keep retrying before giving up (in seconds)."); +} +//============================================================================= +// Destructor +//============================================================================= +COOLConfSvc::~COOLConfSvc() {} + +//============================================================================= +// Access to COOL DatabaseSvc +//============================================================================= +cool::IDatabaseSvc& COOLConfSvc::databaseSvc() { + return coolApplication()->databaseService(); +} + +//============================================================================= +// Access to SEAL Context +//============================================================================= +coral::IConnectionService& COOLConfSvc::connectionSvc() { + return coolApplication()->connectionSvc(); +} + +//============================================================================= +// initialize +//============================================================================= +StatusCode COOLConfSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if ( ! m_coolApplication.get() ) { + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initializing COOL Application" << endmsg; + m_coolApplication.reset(new cool::Application); + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Getting CORAL Connection Service configurator" << endmsg; + coral::IConnectionServiceConfiguration &connSvcConf = + m_coolApplication->connectionSvc().configuration(); + + if ( m_useLFCReplicaSvc ) { + + log << MSG::INFO << "Using CORAL LFCReplicaService" << endmsg; + connSvcConf.setLookupService( "CORAL/Services/LFCReplicaService" ); + connSvcConf.setAuthenticationService( "CORAL/Services/LFCReplicaService" ); + + if ( m_localSite.empty() ) { + // if we didn't get a site from options, we try the environment var DIRACSITE + m_localSite = System::getEnv("DIRACSITE"); + if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { + // if DIRACSITE is not defined, we try, for backward compatibility, LHCBPRODSITE + m_localSite = System::getEnv("LHCBPRODSITE"); + if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { + // if none of the env. vars is set, let's stick to a "sensible" default + m_localSite = "CERN.ch"; + } + } + } + log << MSG::INFO << "Using '" << m_localSite << "' as preferred site" << endmsg; + + m_replicaSortAlg.reset(new ReplicaSortAlg(m_localSite,msgSvc())); + connSvcConf.setReplicaSortingAlgorithm(*m_replicaSortAlg); + } + + if ( ! m_coralConnCleanUp ) { + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Disabling CORAL connection automatic clean up" << endmsg; + connSvcConf.disablePoolAutomaticCleanUp(); + connSvcConf.setConnectionTimeOut( 0 ); + + } + + connSvcConf.setConnectionRetrialPeriod(m_retrialPeriod); + log << MSG::INFO << "CORAL Connection Retrial Period set to " + << connSvcConf.connectionRetrialPeriod() << "s" << endmsg; + + connSvcConf.setConnectionRetrialTimeOut(m_retrialTimeOut); + log << MSG::INFO << "CORAL Connection Retrial Time-Out set to " + << connSvcConf.connectionRetrialTimeOut() << "s" << endmsg; + + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode COOLConfSvc::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + m_coolApplication.reset(); + m_replicaSortAlg.reset(); + return base_class::finalize(); +} diff --git a/Det/DetCond/src/component/COOLConfSvc.h b/Det/DetCond/src/component/COOLConfSvc.h new file mode 100755 index 000000000..6de60e7cb --- /dev/null +++ b/Det/DetCond/src/component/COOLConfSvc.h @@ -0,0 +1,94 @@ +#ifndef COMPONENT_COOLCONFSVC_H +#define COMPONENT_COOLCONFSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "GaudiKernel/GaudiException.h" +#include "DetCond/ICOOLConfSvc.h" + +// Forward declarations +template <class TYPE> class SvcFactory; + +namespace cool { + class Application; + class RecordSpecification; +} +namespace coral { + class IReplicaSortingAlgorithm; +} + +/** @class COOLConfSvc COOLConfSvc.h + * + * Class used as interface to LCG COOL library API. It should expose as less as + * possible COOL internal details. + * + * @author Marco Clemencic + * @date 2005-01-11 + */ + +class COOLConfSvc: public extends1<Service, ICOOLConfSvc> { +public: + /// Initialize COOL (CondDB) Configuration Service + virtual StatusCode initialize(); + + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICOOLConfSvc implementation + /// Access to the CORAL connection service used by COOL (if needed). + virtual coral::IConnectionService& connectionSvc(); + + /// Get the COOL Database service (used to connect to the databases). + virtual cool::IDatabaseSvc& databaseSvc(); + +protected: + /// Standard constructor + COOLConfSvc(const std::string& name, ISvcLocator* svcloc); + + virtual ~COOLConfSvc( ); ///< Destructor + +private: + + inline cool::Application *coolApplication(){ + if (!m_coolApplication.get()) + throw GaudiException("Attempt to access COOL instance before initialization", + "(COOLConfSvc)" + name() + "::coolApplication", + StatusCode::FAILURE); + return m_coolApplication.get(); + } + + /// Pointer to a shared instance of the COOL Application + std::unique_ptr<cool::Application> m_coolApplication; + + std::unique_ptr<coral::IReplicaSortingAlgorithm> m_replicaSortAlg; + + /// Flag to turn off/on the CORAL LFCReplicaService (option UseLFCReplicaSvc, default = false). + /// Setting this option works only if it is set for the first COOLConfSvc initialized + /// because of a "feature" of CORAL. + bool m_useLFCReplicaSvc; + + /// Name of the grid site the application is running on. It is meaningful only + /// if m_useLFCReplicaSvc (option UseLFCReplicaSvc) is set to true. If not + /// specified the value of the environment variables "DIRACSITE" or + /// "LHCBPRODSITE" is used. If even the environment variables are not set, + /// then it is assumed to be "CERN.ch". (Note: the value is case insensitive) + std::string m_localSite; + + /// Flag to turn off/on the CORAL Automatinc connection clean up + /// (option EnableCoralConnectionCleanUp, default = false). + /// Setting this option works only if it is set for the first COOLConfSvc initialized. + bool m_coralConnCleanUp; + + /// Time between two connection trials (in seconds). + /// Passed to CORAL when loaded. + int m_retrialPeriod; + + /// How long to keep retrying before giving up (in seconds). + /// Passed to CORAL when loaded. + int m_retrialTimeOut; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<COOLConfSvc>; + +}; +#endif // COMPONENT_COOLCONFSVC_H diff --git a/Det/DetCond/src/component/CondDBAccessSvc.cpp b/Det/DetCond/src/component/CondDBAccessSvc.cpp new file mode 100755 index 000000000..d8d75e653 --- /dev/null +++ b/Det/DetCond/src/component/CondDBAccessSvc.cpp @@ -0,0 +1,1492 @@ +// Include files +#include <sstream> +//#include <cstdlib> +//#include <ctime> + + +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +#include "GaudiKernel/IRndmGenSvc.h" +#include "GaudiKernel/IRndmEngine.h" + +#include "CoolKernel/DatabaseId.h" +#include "CoolKernel/IDatabaseSvc.h" +#include "CoolKernel/IFolder.h" +#include "CoolKernel/IFolderSet.h" +#include "CoolKernel/IObject.h" +#include "CoolKernel/IObjectIterator.h" +#include "CoolKernel/Exception.h" +#include "CoolKernel/RecordSpecification.h" +#include "CoolKernel/FolderSpecification.h" +#include "CoolKernel/StorageType.h" +#include "CoolKernel/Record.h" + +#include "CoralBase/AttributeList.h" +#include "CoralBase/Exception.h" +// FIXME: Needed because of COOL bug #38422 +#include "CoralBase/AttributeException.h" + +#include "DetCond/ICOOLConfSvc.h" + +// local +#include "CondDBAccessSvc.h" +#include "CondDBCache.h" + +#include "CondDBCommon.h" +#include "IOVListHelpers.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBAccessSvc) + +// Utility function +namespace { + template <class EXC> + inline void report_exception(MsgStream &log, const std::string &msg, const EXC& e){ + log << MSG::ERROR << msg << endmsg; + log << MSG::ERROR << System::typeinfoName(typeid(e)) << ": " + << e.what() << endmsg; + } +} + +#include "GaudiKernel/Sleep.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBAccessSvc +// +// 2005-01-11 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBAccessSvc::CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc): + base_class(name,svcloc), + m_coolConfSvc(0), + m_cache(0), + m_rndmSvc(0), + m_latestHeartBeat(0) +{ + declareProperty("ConnectionString", m_connectionString = "" ); + declareProperty("DefaultTAG", m_dbTAG = "" ); + declareProperty("NoDB", m_noDB = false ); + declareProperty("UseCache", m_useCache = true ); + declareProperty("CacheLowLevel", m_cacheLL = 10 ); + declareProperty("CacheHighLevel", m_cacheHL = 100 ); + //declareProperty("CachePreload", m_cachePreload=3600*1E9); // ns + declareProperty("CheckTAGTrials", m_checkTagTrials = 1 ); + declareProperty("CheckTAGTimeOut", m_checkTagTimeOut = 60 ); + declareProperty("ReadOnly", m_readonly = true ); + + declareProperty("ConnectionTimeOut", m_connectionTimeOutProp = 120 ); + + declareProperty("LazyConnect", m_lazyConnect = true ); + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); + declareProperty("HeartBeatCondition", m_heartBeatCondition = ""); + + declareProperty("QueryGranularity", m_queryGranularity = 0, + "Granularity of the query in the database (in time units), " + "to allow bulk retrievals."); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBAccessSvc::~CondDBAccessSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBAccessSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if (m_connectionTimeOutProp) { + m_connectionTimeOut = boost::posix_time::seconds(m_connectionTimeOutProp); + } else { + m_connectionTimeOut = boost::posix_time::pos_infin; + } + + if ( m_noDB && !m_useCache ) { + log << MSG::ERROR << "Database access disabled and cache off: I cannot work like that. Ciao!" << endmsg; + return StatusCode::FAILURE; + } + + if ( !m_noDB ) { + if ( connectionString() == "" ) { + // we need a connection string to connect to the DB + log << MSG::ERROR << "Connection to database requested and no connection string provided." << endmsg; + log << MSG::ERROR << "Set the option \"" << name() << ".ConnectionString\"." << endmsg; + return StatusCode::FAILURE; + } + + if ( ! m_lazyConnect ) { + sc = i_initializeConnection(); + if (!sc.isSuccess()) return sc; + } + + } + else { + log << MSG::INFO << "Database not requested: I'm not trying to connect" << endmsg; + } + + // set up cache if needed + if (m_useCache) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize CondDB cache." << endmsg; + m_cache = new CondDBCache(MsgStream(msgSvc(), name() + ".Cache"), + m_cacheHL, m_cacheLL); + if (m_cache == NULL) { + log << MSG::ERROR << "Unable to initialize CondDB cache." << endmsg; + return StatusCode::FAILURE; + } + // when we do bulk retrievals it is normal to have overlaps when inserting objects + // into the cache + m_cache->setSilentConflicts(m_queryGranularity > 0); + + } else { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "CondDB cache not needed" << endmsg; + m_cache = NULL; + } + if ( m_xmlDirectMapping && ! m_useCache ) { + // @todo: make it possible to use the direct mapping without cache + log << MSG::FATAL << "Cannot use direct XML mapping without cache (YET)" << endmsg; + return StatusCode::FAILURE; + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { + if (!m_heartBeatCondition.empty()) { + log << MSG::DEBUG << "Using heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; + } + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBAccessSvc::finalize(){ + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(), name() ); + log << MSG::DEBUG << "Finalize" << endmsg; + } + + // stop TimeOut thread + i_stopTimeoutChecker(); + + // release the database + m_db.reset(); + if (m_useCache) { + // dump the content of the cache + m_cache->dump(); + // dispose of the cache manager + delete m_cache; + } + if ( m_rndmSvc ) m_rndmSvc->release(); + + return base_class::finalize(); +} + +//============================================================================= +// Connect to the database +//============================================================================= +StatusCode CondDBAccessSvc::i_initializeConnection(){ + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(), name() ); + log << MSG::DEBUG << "Connection string = \"" << connectionString() << "\"" << endmsg; + } + + StatusCode sc = i_openConnection(); + if (!sc.isSuccess()) return sc; + + // start TimeOut thread + i_startTimeoutChecker(); + + return i_validateDefaultTag(); +} + +//============================================================================= +// Connect to the database +//============================================================================= +StatusCode CondDBAccessSvc::i_openConnection(){ + MsgStream log(msgSvc(), name() ); + + try { + if (! m_db) { // The database is not yet opened + + if ( !m_coolConfSvc ) { + StatusCode sc = service("COOLConfSvc",m_coolConfSvc,true); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot get COOLConfSvc" << endmsg; + return sc; + } + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Get cool::DatabaseSvc" << endmsg; + cool::IDatabaseSvc &dbSvc = m_coolConfSvc->databaseSvc(); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { + log << MSG::DEBUG << "cool::DatabaseSvc got" << endmsg; + log << MSG::DEBUG << "Opening connection" << endmsg; + } + m_db = dbSvc.openDatabase(connectionString(),m_readonly); + + } + else { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Database connection already established!" << endmsg; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieve the root folderset." << endmsg; + m_rootFolderSet = m_db->getFolderSet("/"); + } + // catch ( cool::DatabaseDoesNotExist &e ) { + catch ( coral::Exception &e ) { + report_exception(log,"Problems opening database",e); + m_db.reset(); + return StatusCode::FAILURE; + } + catch ( cool::Exception &e ) { + report_exception(log,"Problems opening database",e); + m_db.reset(); + return StatusCode::FAILURE; + } + + touchLastAccess(); + log << MSG::INFO << "Connected to database \"" << connectionString() << "\"" << endmsg; + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::i_validateDefaultTag() { + MsgStream log(msgSvc(), name() ); + + // Check the existence of the provided tag. + StatusCode sc = i_checkTag(); + + // Try again if requested + int trials_to_go = m_checkTagTrials - 1; // take into account the trial just done + while (!sc.isSuccess() && (trials_to_go > 0)){ + log << MSG::INFO << "TAG \"" << tag() << "\" not ready, I try again in " << m_checkTagTimeOut << "s. " + << trials_to_go << " trials left." << endmsg; + Gaudi::Sleep(m_checkTagTimeOut); + sc = i_checkTag(); + --trials_to_go; + } + + // Fail if the tag is not found + if (!sc.isSuccess()){ + log << MSG::ERROR << "Bad TAG given: \"" << tag() << "\" not in the database" << endmsg; + return sc; + } + log << MSG::INFO << "Using TAG \"" << tag() << "\"" << endmsg; + return StatusCode::SUCCESS; +} +//============================================================================= +// TAG handling +//============================================================================= +const std::string &CondDBAccessSvc::tag() const { return m_dbTAG; } +StatusCode CondDBAccessSvc::setTag(const std::string &_tag){ + + if (m_dbTAG == _tag) return StatusCode::SUCCESS; // no need to change + + StatusCode sc = i_checkTag(_tag); + if ( sc.isSuccess() ) { + m_dbTAG = _tag; + // the cache must be cleared if the tag is changed + clearCache(); + MsgStream log(msgSvc(), name() ); + log << MSG::WARNING << "TAG changed to \"" << _tag << "\"" << endmsg; + } else { + MsgStream log(msgSvc(), name() ); + log << MSG::WARNING << "Unable to set TAG \"" << _tag + << "\": not in the DB. (Still using \"" << tag() << "\")" << endmsg; + } + return sc; +} +StatusCode CondDBAccessSvc::i_checkTag(const std::string &tag) const { + + MsgStream log(msgSvc(), name() ); + if ( !m_db ) { + log << MSG::ERROR << "Check tag \"" << tag + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Check availability of tag \"" << tag << "\"" << endmsg; + /// @TODO: check all sub-nodes to validate the tag and not only the root + if (m_rootFolderSet) { + // HEAD tags are always good + //if ( (tag.empty()) || (tag == "HEAD") ) return StatusCode::SUCCESS; + if ( cool::IHvsNode::isHeadTag(tag) ) { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "\"" << tag << "\" is a HEAD tag: OK" << endmsg; + return StatusCode::SUCCESS; + } + // try to resolve the tag (it cannot be checked) + try { + try { + m_rootFolderSet->resolveTag(tag); + } catch (cool::NodeRelationNotFound) { + // to be ignored: it means that the tag exists, but somewhere else. + } catch (coral::AttributeException) { // FIXME: COOL bug #38422 + // to be ignored: it means that the tag exists, but somewhere else. + } + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "\"" << tag << "\" found: OK" << endmsg; + return StatusCode::SUCCESS; + } catch (cool::TagNotFound &) { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "\"" << tag << "\" NOT found" << endmsg; + return StatusCode::FAILURE; + } + catch (cool::TagRelationNotFound &e) { + log << MSG::ERROR << "got a cool::TagRelationNotFound : " << e.what() << endmsg; + return StatusCode::FAILURE; + } + catch (std::exception &e) { + report_exception(log,"got exception",e); + return StatusCode::FAILURE; + } + + } + return StatusCode::FAILURE; +} + + +//============================================================================= +// Return the connection string used to connect to the database. +//============================================================================= +const std::string &CondDBAccessSvc::connectionString() const{ + return m_connectionString; +} + +//============================================================================= +// Utilities +//============================================================================= +StatusCode CondDBAccessSvc::createNode(const std::string &path, + const std::string &descr, + StorageType storage, + VersionMode vers) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot create node in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + try { + switch (storage) { + case FOLDERSET: + m_db->createFolderSet(path,descr,true); + break; + case XML: + { + cool::FolderSpecification spec((vers == SINGLE) + ?cool::FolderVersioning::SINGLE_VERSION + :cool::FolderVersioning::MULTI_VERSION, + CondDB::getXMLStorageSpec()); + + // append to the description the storage type + std::ostringstream _descr; + _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + m_db->createFolder(path, + spec, + _descr.str(), + true); + } + break; + default: + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": unknown StorageType" << endmsg; + return StatusCode::FAILURE; + } + } catch(cool::NodeExists &){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the node already exists" << endmsg; + return StatusCode::FAILURE; + } catch(cool::Exception &e){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::createNode(const std::string &path, + const std::string &descr, + const std::set<std::string> &fields, + StorageType storage, + VersionMode vers) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot create node in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + try { + switch (storage) { + case FOLDERSET: + m_db->createFolderSet(path,descr,true); + break; + case XML: + { + cool::RecordSpecification recSpec; + for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ + recSpec.extend(*f, cool::StorageType::String16M); + } + cool::FolderSpecification spec((vers == SINGLE) + ?cool::FolderVersioning::SINGLE_VERSION + :cool::FolderVersioning::MULTI_VERSION, + recSpec); + + // append to the description the storage type + std::ostringstream _descr; + _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + m_db->createFolder(path, + spec, + _descr.str(), + true); + } + break; + default: + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": unknown StorageType" << endmsg; + return StatusCode::FAILURE; + } + } catch(cool::NodeExists &){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the node already exists" << endmsg; + return StatusCode::FAILURE; + } catch(cool::Exception &e){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot store in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the object \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + try { + // retrieve folder pointer + cool::IFolderPtr folder = m_db->getFolder(path); + cool::Record payload(folder->payloadSpecification()); + payload["data"].setValue<cool::String16M>(data); + folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); + + } catch (cool::FolderNotFound &) { + + MsgStream log(msgSvc(), name() ); + if (m_db->existsFolderSet(path)) + log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << + path << '\"' << endmsg; + else + log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + + } catch (cool::Exception &e){ + + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the XML string into \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot store in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the object \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + try { + // retrieve folder pointer + cool::IFolderPtr folder = m_db->getFolder(path); + cool::Record payload(folder->payloadSpecification()); + for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ + payload[d->first].setValue<cool::String16M>(d->second); + } + + folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); + + } catch (cool::FolderNotFound &) { + + MsgStream log(msgSvc(), name() ); + if (m_db->existsFolderSet(path)) + log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << + path << '\"' << endmsg; + else + log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + + } catch (cool::Exception &e){ + + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the XML string into \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + + } + return StatusCode::SUCCESS; +} + +cool::ValidityKey CondDBAccessSvc::timeToValKey(const Gaudi::Time &time) const { + // ValidityKey is an uInt64 of which only 63 bits used (0 -> 9223372036854775807), + // while time.ns() is a positive signed Int64! (the same thing) + return time.ns(); +} + +Gaudi::Time CondDBAccessSvc::valKeyToTime(const cool::ValidityKey &key) const { + return Gaudi::Time(key); +} + +StatusCode CondDBAccessSvc::tagLeafNode(const std::string &path, const std::string &tagName, + const std::string &description) { + MsgStream log(msgSvc(),name()); + + if ( m_readonly ) { + log << "Cannot tag in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + log << MSG::ERROR << "Unable to tag the leaf node \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + try { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering tagLeafNode: \"" << path << '"' << endmsg; + + cool::IFolderPtr folder = m_db->getFolder(path); + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION){ + log << MSG::WARNING << "Not tagging leaf node \"" << path << "\": single-version" << endmsg; + } else { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Tagging leaf node \"" << path << "\": " << tagName << endmsg; + folder->tagCurrentHead(tagName, description); + } + + } catch (cool::FolderNotFound &) { + + if (m_db->existsFolderSet(path)) + log << MSG::ERROR << "Node \"" << path << "\" is not leaf." << endmsg; + else + log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + + } catch (cool::Exception &e){ + + log << MSG::ERROR << "Unable tag leaf node \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + + } + + return StatusCode::SUCCESS; +} + +std::string CondDBAccessSvc::generateUniqueTagName(const std::string &base, + const std::set<std::string> &reserved) const { + + if ( !m_db->isOpen() ) { + throw GaudiException("Database not open","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); + } + if ( ! m_rndmSvc ) { + IRndmGenSvc *svc; + StatusCode sc = service("RndmGenSvc",svc,true); + const_cast<CondDBAccessSvc*>(this)->m_rndmSvc = svc; + if ( ! sc.isSuccess() ) { + throw GaudiException("Cannot get a pointer to RndmGenSvc","CondDBAccessSvc::generateUniqueTagName",sc); + } + } + + std::string tag = ""; + do { + // start with the signature + tag = "_auto_"; + // add the base, if any + if (!base.empty()) tag += base + "-"; + // append 6 randomly chosen chars in set [0-9A-Za-z] + for ( int i = 0; i<6; ++i ) { + char c=(char) ( 62.0 * m_rndmSvc->engine()->rndm() ); + if ( c > 61 ) GaudiException("Generator failure","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); // c %= 62; + if ( c >= 36 ) tag += c + 61; + else if ( c >= 10 ) tag += c + 55; + else tag += c + 48; + } + // check if the random name already exists or is reserved + } while ( m_db->existsTag(tag) || (reserved.find(tag) != reserved.end()) ); + + return tag; +} + + +StatusCode CondDBAccessSvc::recursiveTag(const std::string &path, const std::string &tagName, + const std::string &description) { + std::set<std::string> reserved; + DataBaseOperationLock dbLock(this); + return i_recursiveTag(path,tagName,description,tagName,reserved); +} + +StatusCode CondDBAccessSvc::i_recursiveTag(const std::string &path, const std::string &base, + const std::string &description, + const std::string &tagName, + std::set<std::string> &reserved) { + MsgStream log(msgSvc(),name()); + + if ( m_readonly ) { + log << MSG::ERROR << "Cannot tag in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + log << MSG::ERROR << "Unable to tag the inner node \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + try { + // start reserving the tag name we want to apply to the current folderset + reserved.insert(tagName); + + // get the list of child nodes (both types) + cool::IFolderSetPtr this_folderset = m_db->getFolderSet(path); + std::vector<std::string> folders = this_folderset->listFolders(); + std::vector<std::string> foldersets = this_folderset->listFolderSets(); + + // loop over leaf nodes and apply the tags + std::vector<std::string>::iterator f; + for ( f = folders.begin(); f != folders.end(); ++f ) { + + std::string auto_tag = generateUniqueTagName(base,reserved); + cool::IFolderPtr child_folder = m_db->getFolder(*f); + + if (child_folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION) { + // only multi-version folders can be tagged + child_folder->tagCurrentHead(auto_tag, description); + // associate the child folder tag with the parent one + child_folder->createTagRelation(tagName, auto_tag); + } + + } + + // loop over inner nodes and recurse + for ( f = foldersets.begin(); f != foldersets.end(); ++f ) { + + std::string auto_tag = generateUniqueTagName(base,reserved); + StatusCode sc = i_recursiveTag(*f,base,description,auto_tag,reserved); + if (!sc.isSuccess()) return sc; + + cool::IFolderSetPtr child_folderset = m_db->getFolderSet(*f); + child_folderset->createTagRelation(tagName, auto_tag); + + } + } + catch (cool::FolderSetNotFound &) { + if (m_db->existsFolder(path)) + log << MSG::ERROR << "Node \"" << path << "\" is a leaf." << endmsg; + else + log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + } + catch (cool::Exception &e) { + log << MSG::ERROR << "Problems tagging" << endmsg; + log << MSG::ERROR << e.what() << endmsg; + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + cool::ChannelId channel){ + return i_getObject(path, when, data, descr, since, until, + true, channel, ""); +} + +StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + const std::string &channel){ + return i_getObject(path, when, data, descr, since, until, + false, 0, channel); +} +/* +namespace { + ICondDBReader::IOVList getHoles(const ICondDBReader::IOV& iov, const ICondDBReader::IOVList& data){ + typedef ICondDBReader::IOVList IOVList; + typedef ICondDBReader::IOV IOV; + IOVList result; + + Gaudi::Time last = iov.since; // keep track of the end of coverage + // loop over covering interval + for (IOVList::const_iterator covered = data.begin(); covered != data.end(); ++covered) { + if (covered->since > last) { // hole between the end of coverage and begin of next IOV + result.push_back(IOV(last, covered->since)); + } + last = covered->until; // prepare to look for the next hole + } + if (last < iov.until) { + // we didn't get anything to cover until the end of the requested IOV + result.push_back(IOV(last, iov.until)); + } + + return result; + } +} +*/ + +ICondDBReader::IOVList CondDBAccessSvc::i_getIOVsFromDB(const std::string & path, const IOV &iov, cool::ChannelId channel) { + ICondDBReader::IOVList result; + try { + DataBaseOperationLock dbLock(this); + // we want a folder, so go to the database to get it + cool::IFolderPtr folder = database()->getFolder(path); + cool::IObjectIteratorPtr objects; + + // FIXME: we need to considered the query granularity + // Note: IFolder::browseObject returns the objects valid up to the 'until' + // included, which means that asking for [1,10] will return also the + // object starting at 10, so, to exclude it we need to ask for [1,9]. + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION + || tag().empty() || tag() == "HEAD" ){ + objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel); + } else { + objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel, folder->resolveTag(tag())); + } + + if (!objects->isEmpty()) {// check if we managed to find anything + while (objects->goToNext()) { + // add data to the cache while filling the list of IOVs + const cool::IObject &obj = objects->currentRef(); + m_cache->insert(folder, obj, channel); + result.push_back(ICondDBReader::IOV(Gaudi::Time(obj.since()), Gaudi::Time(obj.until()))); + } + } + } catch(cool::FolderNotFound &/*e*/) { + // ignore + } catch (cool::TagRelationNotFound &/*e*/) { + // ignore + } catch (cool::NodeRelationNotFound &) { + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + } + return result; +} + +ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + typedef ICondDBReader::IOVList IOVList; + IOVList result; + if (m_useCache){ + /// Look for holes in the timeline of the cache + result = m_cache->getIOVs(path, iov, channel); + IOVList holes = IOVListHelpers::find_holes(result, iov); + for(IOVList::iterator hole = holes.begin(); hole != holes.end(); ++hole) { + const IOVList cover = i_getIOVsFromDB(path, *hole, channel); + result.insert(result.end(), cover.begin(), cover.end()); + } + std::sort(result.begin(), result.end()); + } else { + result = i_getIOVsFromDB(path, iov, channel); + } + return result; +} + +ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + cool::ChannelId id; + if (m_useCache){ + // Check if the cache knows about the path + if (m_cache->hasPath(path)) { + // the folder is in the cache + if (m_cache->getChannelId(path, channel, id)) { + return getIOVs(path, iov, id); // we know about the folder and the channel + } else { + return ICondDBReader::IOVList(); // we know about the folder, but not about the channel + } + } + } + + // the folder is not in the cache or we do not use the cache, so we have to + // get the channel id from the DB + try { + DataBaseOperationLock dbLock(this); + cool::IFolderPtr folder = database()->getFolder(path); + id = folder->channelId(channel); + } catch(cool::FolderNotFound &/*e*/) { + return ICondDBReader::IOVList(); // unknown folder + } catch(cool::InvalidChannelName &/*e*/) { + return ICondDBReader::IOVList(); // unknown channel + } + return getIOVs(path, iov, id); +} + +StatusCode CondDBAccessSvc::i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, + DataPtr &data, + std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, + bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ + try { + + bool existsFolderSet = false; + { + DataBaseOperationLock dbLock(this); + existsFolderSet = database()->existsFolderSet(path); + } + // Check if the user asked for a folderset + if (existsFolderSet) { + if ( !m_xmlDirectMapping ) { + // with FolderSets, I put an empty entry and clear the shared_ptr + if (m_useCache) m_cache->addFolderSet(path,""); + data.reset(); + } else { + // Using XML direct mapping, foldersets are replaced in the cache + // with the XML equivalent (a catalog). + i_generateXMLCatalogFromFolderset(path); + // now get the data from the cache + m_cache->get(path,when,channel,since,until,descr,data); + } + + return StatusCode::SUCCESS; + } + else { + // Special retrieval procedure if we use "query granularity" (make sense + // only when using the cache). + if (m_useCache && m_queryGranularity > 0){ + // modify the range rounding it to the requested granularity (if needed) + // Range used for the query + cool::ValidityKey sinceWhen = when, untilWhen = when; + + sinceWhen -= when % m_queryGranularity; + untilWhen = sinceWhen + m_queryGranularity; + + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(),name()); + log << MSG::DEBUG << "Retrieving conditions in range " + << sinceWhen << " - " << untilWhen << endmsg; + } + + DataBaseOperationLock dbLock(this); + // we want a folder, so go to the database to get it + cool::IFolderPtr folder = database()->getFolder(path); + cool::IObjectIteratorPtr objects; + if ( !use_numeric_chid ) { // we need to convert from name to id + channel = folder->channelId(channelstr); + } + + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION + || tag().empty() || tag() == "HEAD" ){ + objects = folder->browseObjects(sinceWhen, untilWhen, channel); + } else { + objects = folder->browseObjects(sinceWhen, untilWhen, channel, folder->resolveTag(tag())); + } + + if (objects->isEmpty()) // check if we managed to find anything + return StatusCode::FAILURE; + + while (objects->goToNext()) { + m_cache->insert(folder, objects->currentRef(), channel); + } + // now get the data from the cache + m_cache->get(path, when, channel, since, until, descr, data); + + } else { // no-cache or no granularity are quite similar + + DataBaseOperationLock dbLock(this); + // we want a folder, so go to the database to get it + cool::IFolderPtr folder = database()->getFolder(path); + cool::IObjectPtr object; + if ( !use_numeric_chid ) { // we need to convert from name to id + channel = folder->channelId(channelstr); + } + + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION + || tag().empty() || tag() == "HEAD" ){ + object = folder->findObject(when, channel); + } else { + object = folder->findObject(when, channel, folder->resolveTag(tag())); + } + + if (m_useCache) { + // add the object to the cache + m_cache->insert(folder, *object, channel); + // and get the data back + m_cache->get(path, when, channel, since, until, descr, data); + } else { + data = DataPtr(new cool::Record(object->payload())); + descr = folder->description(); + since = object->since(); + until = object->until(); + } + } + } + } catch ( cool::FolderNotFound &/*e*/) { + //log << MSG::ERROR << e << endmsg; + return StatusCode::FAILURE; + } catch (cool::TagRelationNotFound &/*e*/) { + return StatusCode::FAILURE; + } catch (cool::ObjectNotFound &/*e*/) { + //log << MSG::ERROR << "Object not found in \"" << path << + // "\" for tag \"" << (*accSvc)->tag() << "\" ("<< now << ')' << endmsg; + //log << MSG::DEBUG << e << endmsg; + return StatusCode::FAILURE; + } catch (cool::NodeRelationNotFound &) { + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + return StatusCode::FAILURE; + } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + return StatusCode::FAILURE; + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::i_getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ + + cool::ValidityKey vk_when = timeToValKey(when); + cool::ValidityKey vk_since = 0, vk_until = 0; + + // This is not in i_getObjectFromDB because I need to ensure that m_latestHeartBeat + // is correctly set even when using the cache. + if (vk_when >= i_latestHeartBeat()) { + MsgStream log(msgSvc(), name()); + const Gaudi::Time hb = valKeyToTime(i_latestHeartBeat()); + log << MSG::ERROR << "Database not up-to-date. Latest known update is at " + << hb.format(false, "%Y-%m-%d %H:%M:%S") << "." << hb.nanoformat() + << " UTC, event time is " + << when.format(false, "%Y-%m-%d %H:%M:%S") << "." << when.nanoformat() + << " UTC" << endmsg; + return StatusCode::FAILURE; + } + + if (m_useCache) { + + // Check if the cache knows about the path + if ( m_cache->hasPath(path) ) { + + // the folder is in the cache + if ( !use_numeric_chid ) { // we need to convert from name to id + if (!m_cache->getChannelId(path,channelstr,channel)) { + // the channel name cannot be found in the cached folder + return StatusCode::FAILURE; + } + } + + if ( m_cache->get(path,vk_when,channel,vk_since,vk_until,descr,data) ) { + since = valKeyToTime(vk_since); + /// Artificially cutting the end of validity of the retrieved object to + /// the latest know heart beat guarantees that we will have to go back + /// to the database when the event time exceeds it. + /// Note that we are not calling i_latestHeartBeat() on purpose: + /// it returns +inf if called during initialize, but it sets + /// correctly the variable m_latestHeartBeat. + until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); + return StatusCode::SUCCESS; + } + } + + } + // If we get here, either we do not know about the folder, we didn't + // find the object, or we are not using the cache, so let's try the DB + if (m_noDB) { + // oops... we are not using the db: no way of getting the object from it + return StatusCode::FAILURE; + } + + StatusCode sc = i_getObjectFromDB(path,vk_when,data,descr,vk_since,vk_until,use_numeric_chid,channel,channelstr); + since = valKeyToTime(vk_since); + /// Artificially cutting the end of validity of the retrieved object to + /// the latest know heart beat guarantees that we will have to go back + /// to the database when the event time exceeds it. + /// Note that we are not calling i_latestHeartBeat() on purpose: + /// it returns +inf if called during initialize, but it sets + /// correctly the variable m_latestHeartBeat. + until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); + return sc; +} + +namespace { + // Small helper function to reduce duplications + inline void cannotGetHeartBeatError(CondDBAccessSvc *self, const std::string&path) { + MsgStream log(self->msgSvc(), self->name()); + log << MSG::ERROR << "Cannot get latest heart beat (" << path + << ") in the database" << endmsg; + } +} +const cool::ValidityKey& CondDBAccessSvc::i_latestHeartBeat() +{ + if (m_latestHeartBeat == 0) { + if (m_heartBeatCondition.empty() || + m_noDB) { // it doesn't make sense to ask for a heart beat if we do not use the DB + // no heart beat condition: the database is always valid + m_latestHeartBeat = cool::ValidityKeyMax; + } else { + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(),name()); + log << MSG::DEBUG << "Retrieving heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; + } + // we do not use the normal functions to retrieve the object because + // we want to by-pass the cache + try { + DataBaseOperationLock dbLock(this); + cool::IFolderPtr folder = database()->getFolder(m_heartBeatCondition); + cool::IObjectPtr obj = folder->findObject(cool::ValidityKeyMax-1, 0); + m_latestHeartBeat = obj->since(); + } + catch (cool::Exception &) { + cannotGetHeartBeatError(this, m_heartBeatCondition); + m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database + } + catch (coral::Exception &) { + cannotGetHeartBeatError(this, m_heartBeatCondition); + m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database + } + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(),name()); + log << MSG::DEBUG << "Latest heart beat at " << m_latestHeartBeat << endmsg; + } + } + } + if (FSMState() != Gaudi::StateMachine::RUNNING) { + // Temporarily consider the database valid if not running + // (e.g. during initialize). + // Note that the retrieve is done (and must be done) anyway, + // because it is needed by i_getObject(). + return cool::ValidityKeyMax; + } + return m_latestHeartBeat; +} + + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) { + MsgStream log(msgSvc(),name()); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; + + folders.clear(); + foldersets.clear(); + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + if (database()->existsFolderSet(path)) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "FolderSet \"" << path << "\" exists" << endmsg; + + cool::IFolderSetPtr folderSet = database()->getFolderSet(path); + + std::vector<std::string> fldr_names = folderSet->listFolders(); + std::vector<std::string> fldrset_names = folderSet->listFolderSets(); + + for ( std::vector<std::string>::iterator f = fldr_names.begin(); f != fldr_names.end(); ++f ) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << *f << endmsg; + // Check if folder is tagged with a tag set to load db with. + cool::IFolderPtr folder = database()->getFolder(*f); + if (folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION){ + try{ + folder->resolveTag(tag()); + folders.push_back(f->substr(f->rfind('/')+1)); + } catch (cool::TagRelationNotFound &) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Tag '" << tag() + << "' relation was not found for ': "<< *f << "' folder" << endmsg; + } catch (cool::ReservedHeadTag &) { + //to be ignored: 'HEAD' tag is in every node + folders.push_back(f->substr(f->rfind('/')+1)); + } catch (cool::NodeRelationNotFound &) { + //to be ignored: it means that the tag exists, but it is not in the node '/'. + } catch (coral::AttributeException &) { // FIXME: COOL bug #38422. To be ignored: + //it means that the tag exists, but it is not in the node '/'. + } catch (coral::Exception &e) { + report_exception(log,"got CORAL exception",e); + folders.push_back(f->substr(f->rfind('/')+1)); + } + } else { //add folder if it is single version without tag verification + folders.push_back(f->substr(f->rfind('/')+1)); + } + } + + for ( std::vector<std::string>::iterator f = fldrset_names.begin(); f != fldrset_names.end(); ++f ) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << *f << endmsg; + foldersets.push_back(f->substr(f->rfind('/')+1)); + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { + log << MSG::DEBUG << "got " << folders.size() << " sub folders" << endmsg; + log << MSG::DEBUG << "got " << foldersets.size() << " sub foldersets" << endmsg; + } + + } else { + // cannot get the sub-nodes of a folder! + return StatusCode::FAILURE; + } + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + m_cache->getSubNodes(path,folders,foldersets); + } else { + // no cache and no db + return StatusCode::FAILURE; + } + } catch ( cool::FolderNotFound &/*e*/) { + //log << MSG::ERROR << e << endmsg; + return StatusCode::FAILURE; + } catch (coral::Exception &e) { + report_exception(log,"got CORAL exception",e); + } + return StatusCode::SUCCESS; + + +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { + + std::vector<std::string> temp; + StatusCode sc = getChildNodes(path, node_names, temp); + if (sc.isSuccess()) + node_names.insert(node_names.end(), temp.begin(), temp.end()); + return sc; + +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBAccessSvc::exists(const std::string &path) { + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + return database()->existsFolderSet(path) || database()->existsFolder(path); + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + return m_cache->hasPath(path); + } + + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + // if we do not have neither DB nor cache, or we got an exception + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBAccessSvc::isFolder(const std::string &path) { + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + return database()->existsFolder(path); + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + return m_cache->isFolder(path); + } + + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + // if we do not have neither DB nor cache, or we got an exception + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBAccessSvc::isFolderSet(const std::string &path) { + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + return database()->existsFolderSet(path); + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + return m_cache->isFolderSet(path); + } + + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + // if we do not have neither DB nor cache, or we got an exception + return false; +} + +//========================================================================= +// Disconnect from the database. +//========================================================================= +void CondDBAccessSvc::disconnect() { + boost::mutex::scoped_lock busy_lock(m_busy); + if ( database() && database()->isOpen() ) { + if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { + debug() << "Forced disconnect from database (will reconnect automatically)" << endmsg; + } + database()->closeDatabase(); + } else if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { + debug() << "Database already disconnected" << endmsg; + } + i_stopTimeoutChecker(); +} + +//========================================================================= +// Add database name and TAG to the passed vector. +//========================================================================= +void CondDBAccessSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + /// @todo This should be something like + /// <quote> + /// tags.push_back(LHCb::CondDBNameTagPair(database()->dbName(),tag())); + /// </quote> + /// but COOL API does not provide that function yet. (Available since 2.2.0) + + std::string dbName; + // Parsing of COOL connection string to find database name + // - first type: <tech>://<server>;schema=<schema>;dbname=<dbname> + std::string::size_type pos = connectionString().find("dbname="); + if ( std::string::npos != pos ) { + pos += 7; + std::string::size_type pos2 = connectionString().find(';',pos); + if ( std::string::npos != pos2 ) + dbName = connectionString().substr(pos,pos2-pos); + else + dbName = connectionString().substr(pos); + } else { + // - second type: <alias>/<dbname> + pos = connectionString().find_last_of('/'); + if ( std::string::npos != pos ) { + dbName = connectionString().substr(pos+1); + } else { + throw GaudiException("Cannot understand COOL connection string", + "CondDBAccessSvc::defaultTags",StatusCode::FAILURE); + } + } + // If the tag is a "HEAD" tag, I want to show "HEAD" + std::string tagName = tag(); + if (cool::IHvsNode::isHeadTag(tagName)) { + tagName = "HEAD"; + } + + tags.push_back(LHCb::CondDBNameTagPair(dbName,tagName)); + +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec) { + if (!m_useCache) { + MsgStream log(msgSvc(),name()); + log << MSG::ERROR << "Cache not in use: I cannot add a folder to it." << endmsg; + return StatusCode::FAILURE; + } + return m_cache->addFolder(path,descr,spec) ? StatusCode::SUCCESS : StatusCode::FAILURE; +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddFolderSet(const std::string &path, const std::string &descr) { + if (!m_useCache) { + MsgStream log(msgSvc(),name()); + log << MSG::ERROR << "Cache not in use: I cannot add a folder-set to it." << endmsg; + return StatusCode::FAILURE; + } + return m_cache->addFolderSet(path,descr) ? StatusCode::SUCCESS : StatusCode::FAILURE; +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path) { + std::ostringstream _descr; + _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + return cacheAddFolder(path,_descr.str(),CondDB::getXMLStorageSpec()); +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) { + std::ostringstream _descr; + _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + cool::RecordSpecification spec; + for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ + spec.extend(*f, cool::StorageType::String16M); + } + return cacheAddFolder(path,_descr.str(),spec); +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const cool::IRecord& payload, cool::ChannelId channel) { + if (!m_useCache) { + MsgStream log(msgSvc(),name()); + log << MSG::ERROR << "Cache not in use: I cannot add an object to it." << endmsg; + return StatusCode::FAILURE; + } + return m_cache->addObject(path,timeToValKey(since),timeToValKey(until),payload,channel) + ? StatusCode::SUCCESS + : StatusCode::FAILURE; +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string &data, cool::ChannelId channel) { + /// @todo this is affected by the evolution in COOL API + cool::Record payload(CondDB::getXMLStorageSpec()); + payload["data"].setValue<cool::String16M>(data); + return cacheAddObject(path,since,until,payload,channel); +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::map<std::string,std::string> &data, cool::ChannelId channel) { + cool::RecordSpecification spec; + for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ + spec.extend(d->first,cool::StorageType::String16M); + } + + cool::Record payload(spec); + + for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ + payload[d->first].setValue<cool::String16M>(d->second); + } + return cacheAddObject(path,since,until,payload,channel); +} + +//========================================================================= +// +//========================================================================= +void CondDBAccessSvc::clearCache() +{ + if (m_useCache) { + m_cache->clear(); + } +} + +//========================================================================= +// +//========================================================================= +void CondDBAccessSvc::dumpCache() const { + if (m_useCache) m_cache->dump(); +} + +//========================================================================= +// +//========================================================================= +void CondDBAccessSvc::i_generateXMLCatalogFromFolderset(const std::string &path){ + // Use the name of the folderset as catalog name. + std::string::size_type pos = path.rfind('/'); + if ( std::string::npos == pos ) { + pos = 0; // if we cannot find '/' let's take the whole string + } else { + ++pos; + } + std::string folderset_name = path.substr(pos); + + // Get the names of sub-folders and sub-foldersets + std::vector<std::string> fldr_names, fldrset_names; + getChildNodes(path, fldr_names, fldrset_names).ignore(); + + std::string xml; + CondDB::generateXMLCatalog(folderset_name,fldr_names,fldrset_names,xml); + + // Put the data in the cache + if ( ! m_cache->hasPath(path) ) + cacheAddXMLFolder(path); + + // This is needed because we cannot add objects valid for the current event + // to the cache using the ICondDBAccessSvc API. + bool check_enabled = m_cache->setIOVCheck(false); + cacheAddXMLData(path,Gaudi::Time::epoch(),Gaudi::Time::max(),xml,0).ignore(); + m_cache->setIOVCheck(check_enabled); + +} diff --git a/Det/DetCond/src/component/CondDBAccessSvc.h b/Det/DetCond/src/component/CondDBAccessSvc.h new file mode 100755 index 000000000..34e578470 --- /dev/null +++ b/Det/DetCond/src/component/CondDBAccessSvc.h @@ -0,0 +1,506 @@ +#ifndef COMPONENT_CONDDBACCESSSVC_H +#define COMPONENT_CONDDBACCESSSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "GaudiKernel/GaudiException.h" +#include "Kernel/ICondDBInfo.h" +#include "DetCond/ICondDBAccessSvc.h" +#include "DetCond/ICondDBReader.h" +#include "DetCond/ICondDBEditor.h" +#include <set> + +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition.hpp> +#include <boost/thread/thread_time.hpp> + +#include "CoolKernel/IDatabase.h" + +// Forward declarations +template <class TYPE> class SvcFactory; + +class CondDBCache; +class IRndmGenSvc; +class ICOOLConfSvc; + +namespace cool { + class Application; + class RecordSpecification; +} + +/** @class CondDBAccessSvc CondDBAccessSvc.h + * + * Class used as interface to LCG COOL library API. It should expose as less as + * possible COOL internal details. + * + * @author Marco Clemencic + * @date 2005-01-11 + */ + +class CondDBAccessSvc: public extends3<Service, + ICondDBAccessSvc, + ICondDBReader, + ICondDBEditor> { +public: + + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + /// (Version with alphanumeric channel id) + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags ) const; + + // --------- ICondDBEditor implementation + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + StorageType storage = XML, + VersionMode vers = MULTI) const; + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + const std::set<std::string> &fields, + StorageType storage = XML, + VersionMode vers = MULTI) const; + + /// Utility function that simplifies the storage of an XML string. + virtual StatusCode storeXMLData(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; + + /// Utility function that simplifies the storage of a set of XML strings. + virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; + + /// Tag the given leaf node with the given tag-name. + virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, + const std::string &description = ""); + + /// Tag the given inner node with the given tag-name, recursively tagging the head + /// of child nodes with automatically generated tag-names. + virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, + const std::string &description = ""); + + // --------- ICondDBAccessSvc implementation + + /// Used to obtain direct access to the database. + virtual cool::IDatabasePtr& database() { return m_db; } + + /// Convert from Gaudi::Time class to cool::ValidityKey. + virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const; + + /// Convert from cool::ValidityKey to Gaudi::Time class. + virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const; + + /// Return the currently set TAG to use. + virtual const std::string &tag() const; + + /// Set the TAG to use. + virtual StatusCode setTag(const std::string &_tag); + + /// Return the connection string used to connect to the database. + virtual const std::string &connectionString() const; + + /// Add a folder to the cache (bypass the DB) + virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec); + + /// Add a folder-set to the cache (bypass the DB) + virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr); + + /// Add a folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path); + + /// Add an XML folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields); + + ///Add an object to the cache (bypass the DB) + virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const cool::IRecord& payload, cool::ChannelId channel = 0); + + ///Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string& data, cool::ChannelId channel = 0); + + /// Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::map<std::string,std::string> &data, cool::ChannelId channel = 0); + + /// Clear the cache + virtual void clearCache(); + + /// Dump the cache (debug) + virtual void dumpCache() const; + +protected: + /// Standard constructor + CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc); + + virtual ~CondDBAccessSvc( ); ///< Destructor + +protected: + // Properties + + /// Property CondDBAccessSvc.ConnectionString: full connection string to open database access. + /// Format is: "<BackEnd>://<HostName>;schema=<Schema>;dbname=<Database>;[user=<User>;][password=<Password>;]" + /// or "<HostAlias>/<Database>". + std::string m_connectionString; + +private: + /// Property CondDBAccessSvc.DefaultTAG: which tag to use if none is specified + std::string m_dbTAG; + + /** Property CondDBAccessSvc.UseCache: store the retrieved informations into a cache for faster + later access. */ + bool m_useCache; + + /// Property CondDBAccessSvc.CacheLowLevel: minimum fill of the cache. + size_t m_cacheLL; + + /// Property CondDBAccessSvc.CacheHighLevel: maximum fill of the cache. + size_t m_cacheHL; + + /// Property CondDBAccessSvc.NoDB: do not use the database (cache must be on). + bool m_noDB; + + /// Property CondDBAccessSvc.ReadOnly: open the database as read-only (default: true). + bool m_readonly; + + /// Property CondDBAccessSvc.CheckTAGTrials: Number of times to retry the check on the tag (default = 1). + int m_checkTagTrials; + + /// Property CondDBAccessSvc.CheckTAGTimeOut: Seconds to sleep between one trial and the following (default = 60). + int m_checkTagTimeOut; + + /// Pointer to the service initializing COOL/CORAL. + ICOOLConfSvc *m_coolConfSvc; + + /// Shared pointer to the COOL database instance + cool::IDatabasePtr m_db; + + /// Shared pointer to the COOL database instance + cool::IFolderSetPtr m_rootFolderSet; + + /// Pointer to the cache manager + CondDBCache *m_cache; + + /// Pointer to the random generator service + IRndmGenSvc *m_rndmSvc; + + /// Lazy connection flag. + /// If true (the default), the connection to (lazy = connect only when needed). + bool m_lazyConnect; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Path in the condition database (not in the transient store) to be used as + /// heart-beat marker. + /// The latest update of the condition specified give information about when + /// the replica was last updated: We cannot guarantee that the database is more + /// "up to date" then the "since" field of the latest object in the heart-beat + /// condition. + std::string m_heartBeatCondition; + + /// Latest know update of the database ("since" field of the latest heart-beat condition). + /// Initialized to 0, if no heart-beat condition is requested, it is set to + /// cool::ValidityKeyMax, otherwise, during the first access to the DB, the + /// object valid until ValidityKeyMax is retrieved and its "since" field is + /// recorded in this variable. + /// When disconnected from the database, it is reset to 0 to force a re-check. + cool::ValidityKey m_latestHeartBeat; + + // ---------------------------------------------- + // ---------- Private Member Functions ---------- + // ---------------------------------------------- + + /// Connect to the COOL database. It sets 'm_db'. + StatusCode i_initializeConnection(); + + /// Connect to the COOL database. It sets 'm_db'. + StatusCode i_openConnection(); + + /// Internal method to retrieve an object. + StatusCode i_getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + bool use_numeric_chid, + cool::ChannelId channel, const std::string &channelstr); + + /// Internal method to retrieve an object from the database. + /// If the cache is activated, the result is copied there. + StatusCode i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, + DataPtr &data, + std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, + bool use_numeric_chid, + cool::ChannelId channel, const std::string &channelstr); + + /// Internal method to get the list of IOVs in a range. + /// @see ICondDBReader::getIOVs + IOVList i_getIOVsFromDB(const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + + void i_generateXMLCatalogFromFolderset(const std::string &path); + + /// Connect to the COOL database. It sets 'm_db'. + StatusCode i_validateDefaultTag(); + + /// Check if the TAG set exists in the DB. + inline StatusCode i_checkTag() const { return i_checkTag(tag()); } + + /// Check if the given TAG exists in the DB. + StatusCode i_checkTag(const std::string &tag) const; + + /// Generate a tag name that do not create conflicts in the DB. + /// Tagnames generated by this method will start with "_auto_". + /// If base value is passed to the method, the result will have + /// a "_auto_`base`-" prefix. + std::string generateUniqueTagName(const std::string &base, + const std::set<std::string> &reserved) const; + + /// Function used by recursiveTag to do the real work. + StatusCode i_recursiveTag(const std::string &path, + const std::string &base, + const std::string &description, + const std::string &tagName, + std::set<std::string> &reserved); + + + /// Return the value of m_latestHeartBeat. + /// The value is retrieved from the database when requested the first time + /// in the RUNNING state. + const cool::ValidityKey &i_latestHeartBeat(); + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBAccessSvc>; + + /// AttributeListSpecification used to sore XML strings + static std::unique_ptr<cool::RecordSpecification> s_XMLstorageSpec; + + /// Parameter controlling the granularity of the queries to the conditions database (in time units). + /// + /// When different from 0, instead of retrieving the only condition valid for the requested event time, + /// we will retrieve all the conditions valid for a range around the event time, rounded by the + /// granularity. + /// + /// For example, with granularity set to 1h and the event time 16:18:08, all the conditions valid for the + /// range 16:00:00 to 17:00:00 will be retrieved. + /// + /// \b Note: if the cache is not enabled the parameter has no effect. + cool::ValidityKey m_queryGranularity; + + // ------------------------------------- + // ---------- Time Out Thread ---------- + // ------------------------------------- + + /// Property CondDBAccessSvc.ConnectionTimeOut: How many seconds to keep the connection to the DB open after the + /// last access (default = 120, 0 means never). The connection will be started again if a new operation is performed. + int m_connectionTimeOutProp; + boost::posix_time::time_duration m_connectionTimeOut; + + /// Mutex to avoid conflicts between the main thread and the thread trying to close the connection. + boost::mutex m_busy; + + /// The time of last access. + boost::system_time m_lastAccess; + + /// Mutex to protect the last access time. + boost::mutex m_lastAccessMutex; + + /// Pointer to the second thread. + std::unique_ptr<boost::thread> m_timeOutCheckerThread; + + /// Function to set the last access time to "now". + inline void touchLastAccess() + { + boost::mutex::scoped_lock myLock(m_lastAccessMutex); + m_lastAccess = boost::get_system_time(); + } + + /// Get the last access time. + inline const boost::system_time &lastAccess() const + { + return m_lastAccess; + } + + /// Start the timeout checker thread, if requested. + inline void i_startTimeoutChecker() { + if ( UNLIKELY( (!m_timeOutCheckerThread) + && (!m_connectionTimeOut.is_pos_infinity()) ) ) { + m_timeOutCheckerThread.reset( new boost::thread(TimeOutChecker{this}) ); + } + } + + /// Stop the timeout checker thread if running. + inline void i_stopTimeoutChecker() { + if ( LIKELY( NULL != m_timeOutCheckerThread.get() ) ) { + m_timeOutCheckerThread->interrupt(); // tell the thread to stop + m_timeOutCheckerThread->join(); // wait for it + m_timeOutCheckerThread.reset(); // delete it + } + } + + /// Class executed in a separate thread to disconnect from the database if + /// a time-out is reached. + class TimeOutChecker + { + /// Pointer to the CondDBAccessSvc, used to acquire operation locks and + /// access parameters. + CondDBAccessSvc *m_owner; + /// Cached MsgStream to report messages. + MsgStream log; + + public: + TimeOutChecker(CondDBAccessSvc *owner): + m_owner(owner), + log(m_owner->msgSvc(),m_owner->name()+".TimeOutChecker") + { + } + + void operator () () + { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Starting" << endmsg; + + boost::system_time last_access = m_owner->lastAccess(); + + // set initial check time + boost::system_time next_check = last_access + m_owner->m_connectionTimeOut; + + try { + // enter infinite loop + while (true) { + // Wait until the next check point time is reached. + // An early exit must be triggered by a call to this->interrupt(), which + // will produce an exception during the sleep. + boost::thread::sleep(next_check); + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Time-out reached (" << next_check << ")" << endmsg; + + boost::mutex::scoped_lock busy_lock(m_owner->m_busy); + + if ( last_access == m_owner->lastAccess() ) { // no further accesses + + if ( m_owner->database()->isOpen() ) { // close the database + log << MSG::INFO << "Disconnect from database after being idle for " + << m_owner->m_connectionTimeOut.total_seconds() + << "s (will reconnect if needed)"<< endmsg; + m_owner->database()->closeDatabase(); + // reset the latest heart beat because it may be different the next time + // we connect to the DB + if (!m_owner->m_heartBeatCondition.empty()) m_owner->m_latestHeartBeat = 0; + } + + // schedule the next check for now + dt (seems a good estimate) + next_check = boost::get_system_time() + m_owner->m_connectionTimeOut; + + } else { + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Wait more" << endmsg; + + // schedule the next check for last_access + dt + next_check = last_access = m_owner->lastAccess(); + next_check += m_owner->m_connectionTimeOut; + } + } + } + // Ignore the exception since it is used only to exit from the loop. + catch (boost::thread_interrupted&) {} + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Stopping" << endmsg; + } + }; + + class DataBaseOperationLock + { + CondDBAccessSvc *m_owner; + MsgStream log; + boost::mutex::scoped_lock busy_lock; + public: + DataBaseOperationLock(const CondDBAccessSvc *owner): + m_owner(const_cast<CondDBAccessSvc*>(owner)), + log(m_owner->msgSvc(),m_owner->name()+".DataBaseOperationLock"), + busy_lock(m_owner->m_busy) // lock the access to the db + { + // If the database has not been instantiated yet, we may be using + // lazy connection and we have to connect now. + if (!m_owner->m_db) { + // we have to release the lock because i_initializeConnection + // needs to lock the DB + busy_lock.unlock(); + StatusCode sc = m_owner->i_initializeConnection(); + busy_lock.lock(); + if (! sc.isSuccess()) + throw GaudiException("Cannot initialize connection", + "DataBaseOperationLock::DataBaseOperationLock", + sc); + } + if (!m_owner->m_db->isOpen()){ + log << MSG::INFO << "Connecting to database" << endmsg; + m_owner->m_db->openDatabase(); // ensure that the db is open + m_owner->i_startTimeoutChecker(); // ensure that the timeout checker is running + } + } + + ~DataBaseOperationLock() + { + m_owner->touchLastAccess(); // update last access time + } + }; + + friend class TimeOutChecker; + friend class DataBaseOperationLock; + +}; +#endif // COMPONENT_CONDDBACCESSSVC_H diff --git a/Det/DetCond/src/component/CondDBCache.cpp b/Det/DetCond/src/component/CondDBCache.cpp new file mode 100755 index 000000000..2e6e94cc4 --- /dev/null +++ b/Det/DetCond/src/component/CondDBCache.cpp @@ -0,0 +1,444 @@ +// Include files +#include "CondDBCache.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBCache +// +// 2005-06-13 : Marco Clemencic +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBCache::CondDBCache(const MsgStream& log, size_t highLvl, size_t lowLvl): + m_highLvl(highLvl), m_lowLvl(lowLvl), + m_level(0), + m_log(log), + m_lastRequestedTime(0), m_checkLastReqTime(true), + m_silentConflicts(false) +{ + if ( highLvl == 0 ) { + m_log << MSG::WARNING << "High level == 0 : forced to 100" << endmsg; + m_highLvl = 100; + } + if ( highLvl <= lowLvl ) { + m_log << MSG::WARNING << "High level <= low level : low level forced to 0" << endmsg; + m_lowLvl = 0; + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Cache initialized with high/low levels = " << + m_highLvl << '/' << m_lowLvl << endmsg; +} +//============================================================================= +// Destructor +//============================================================================= +CondDBCache::~CondDBCache() { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Cache deleted. Level was = " << m_level << endmsg; +} + +//========================================================================= +// Add a new item to the cache +//========================================================================= +bool CondDBCache::insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel) { + // increment object count and check the limit + if ( m_level >= highLevel() ){ + // needs clean up + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Level above max threshold" << endmsg; + clean_up(); + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Insert Folder '" << folder->fullPath() + << "', IOV : " << obj.since() << " - " << obj.until() + << ", channel : " << channel << endmsg; + + FolderIdType id(folder->fullPath()); + StorageType::iterator f = m_cache.find(id); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(id, CondFolder(folder))).first; + // Fill the map of channel names. + std::map<cool::ChannelId,std::string>::const_iterator p; + std::map<cool::ChannelId,std::string> ch_names = folder->listChannelsWithNames(); + for (p = ch_names.begin(); p != ch_names.end(); ++p) { + f->second.channelNames[p->second] = p->first; + } + } else { + if (f->second.items[channel].end() != f->second.conflict(obj.since(), obj.until(), channel)) { + const MSG::Level lvl = (m_silentConflicts ? MSG::DEBUG : MSG::WARNING); + m_log << lvl << "Conflict found: item not inserted" << endmsg; + ItemListType::iterator i = f->second.conflict(obj.since(), obj.until(), channel); + m_log << lvl << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; + return false; + } + } + // for vectors + // f->second.items.push_back(CondItem(&f->second,obj)); + // for lists + ItemListType &items = f->second.items[channel]; + ItemListType::iterator pos = items.begin(); + while (pos != items.end() && pos->iov.first < obj.since()) { + ++pos; + } + items.insert(pos, CondItem(&f->second, obj)); + + ++m_level; + return true; +} + +//========================================================================= +// Add a new folder using the given specification and description. (Bypass the real DB) +//========================================================================= +bool CondDBCache::addFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec) { + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; + } + return true; +} +bool CondDBCache::addFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec, + const std::map<cool::ChannelId,std::string>& ch_names) { + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; + // Fill the map of channel names. + std::map<cool::ChannelId,std::string>::const_iterator p; + for (p = ch_names.begin(); p != ch_names.end(); ++p) { + f->second.channelNames[p->second] = p->first; + } + } + return true; +} + +//========================================================================= +// Add a new folder using the given specification and description. (Bypass the real DB) +//========================================================================= +bool CondDBCache::addFolderSet(const std::string &path, const std::string &descr) { + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(path,CondFolder(descr))).first; + } + return true; +} + +//========================================================================= +// Add a new object to a given folder +//========================================================================= +bool CondDBCache::addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before) { + // new objects cannot be already valid. check it! + if ( IOVCheck() && (m_lastRequestedTime != 0) + && ( since <= m_lastRequestedTime && m_lastRequestedTime < until ) ) { + m_log << (m_silentConflicts ? MSG::DEBUG : MSG::WARNING) + << "New item IOV is compatible with last requested time:" + << " not allowed to avoid inconsistencies" << endmsg; + return false; + } + // increment object count and check the limit + if ( m_level >= highLevel() ){ + // needs clean up + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Level above max threshold" << endmsg; + clean_up(); + } + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + m_log << MSG::WARNING << "Could not find the folder: object not added" << endmsg; + return false; + } + if (!f->second.spec) { // no specification means FolderSet + m_log << MSG::WARNING << '"' << path << '"' << " is a FolderSet: object not added" << endmsg; + return false; + } + + // when bypassing the DB, the conflicts must be solved + /* + if (f->second.conflict(since,until) != f->second.items.end()) { + m_log << MSG::WARNING << "Conflict found: item not inserted" << endmsg; + return false; + } + */ + // **** COOL single version style --> [x;+inf] + [y(>x);z] = [x;y], [y;z] + // scan for conflicting items (from the end) + ItemListType::iterator i = f->second.conflict(since,until,channel); + if ( i != f->second.items[channel].end() ) { // conflict found + if ( i->iov.second == cool::ValidityKeyMax && i->iov.first < since ) { + // solvable conflict + if (iov_before) *iov_before = i->iov; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Solvable conflict found: old until = " << i->iov.second << endmsg; + i->iov.second = since; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " new until = " << i->iov.second << endmsg; + } else { + // conflict not solvable + m_log << MSG::WARNING << "Unsolvable conflict found: item not inserted" << endmsg; + return false; + } + } + // for vectors + // f->second.items.push_back(CondItem(&f->second,since,until,rec)); + // for lists + f->second.items[channel].push_front(CondItem(&f->second,since,until,rec)); + ++m_level; + return true; +} + +//========================================================================= +// Get data from given path and valid at given time +//========================================================================= +bool CondDBCache::get(const std::string &path, const cool::ValidityKey &when, + const cool::ChannelId &channel, + cool::ValidityKey &since, cool::ValidityKey &until, + std::string &descr, ICondDBReader::DataPtr &payload ) { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Request Folder '" << path + << "' @ " << when << " channel " << channel; + m_lastRequestedTime = when; + StorageType::iterator folder = m_cache.find(path); + if (folder != m_cache.end()) { + if ( ! folder->second.spec ) { + // It's a FolderSet! no objects inside + since = cool::ValidityKeyMin; + until = cool::ValidityKeyMax; + descr = folder->second.description; + payload.reset(); + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << " FOUND (FolderSet)" << endmsg; + return true; + } + ItemListType::iterator i = folder->second.find(when,channel); + if ( i != folder->second.items[channel].end() ) { + since = i->iov.first; + until = i->iov.second; + descr = folder->second.description; + payload = i->data; + //i->score += 1.0; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << " FOUND" << endmsg; + return true; + } + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << " MISSING" << endmsg; + return false; +} +//========================================================================= +// +//========================================================================= +bool CondDBCache::getChannelId(const std::string &path,const std::string &name, + cool::ChannelId &channel) const { + StorageType::const_iterator f = m_cache.find(path); + if ( m_cache.end() != f ) { + CondFolder::ChannelNamesMapType::const_iterator id = f->second.channelNames.find(name); + if ( f->second.channelNames.end() != id ) { + channel = id->second; + return true; + } + } + channel = 0; + return false; +} +//========================================================================= +// +//========================================================================= +void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets) { + + folders.clear(); + foldersets.clear(); + + StorageType::iterator f; + for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { + const std::string &p = f->first; + if ( p.find(path) == 0 // the string must start with path + && ( p.size() > path.size() ) // it must contain something more than the path + && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name + if ( f->second.spec.get() ) { + // this is a folder + folders.push_back(p.substr(path.size())); + } else { + // this is a folderset + foldersets.push_back(p.substr(path.size())); + } + } + } +} +//========================================================================= +// +//========================================================================= +void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &node_names) { + // @todo: could be implemented as getSubNodes(path,node_names,node_names); + + node_names.clear(); + + StorageType::iterator f; + for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { + const std::string &p = f->first; + if ( p.find(path) == 0 // the string must start with path + && ( p.size() > path.size() ) // it must contain something more than the path + && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name + node_names.push_back(p.substr(path.size())); + } + } +} +//========================================================================= +// Remove unused entries from the cache +//========================================================================= + +void CondDBCache::clean_up(){ + typedef std::vector<std::pair<float,std::pair<CondDBCache::CondFolder*,std::pair<cool::ValidityKey,cool::ChannelId> > > > + _vec_t; + _vec_t all_items; + float score = 0; + size_t old_level = level(); + + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) { + m_log << MSG::DEBUG << "Start cleaning up (level = " << level() << ")" << endmsg; + m_log << MSG::DEBUG << " Last requested time = " << m_lastRequestedTime << endmsg; + } + // collect all items info in order + StorageType::iterator folder; + for ( folder = m_cache.begin() ; folder != m_cache.end() ; ++folder ) { + + if ( ! folder->second.spec ) continue; // It's a FolderSet! no objects inside: skip it + + CondFolder::StorageType::iterator ch; + ItemListType::iterator i; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Folder " << folder->first << endmsg; + for ( ch = folder->second.items.begin(); ch != folder->second.items.end() ; ++ch ){ + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " channel : " << ch->first << endmsg; + for ( i = ch->second.begin(); i != ch->second.end() ; ++i ){ + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; + if ( ! (i->iov.first <= m_lastRequestedTime && i->iov.second > m_lastRequestedTime) ) { + if ( m_lastRequestedTime < i->iov.first ) { + score = (float)m_lastRequestedTime - i->iov.first; + } else { + score = (float)i->iov.second - m_lastRequestedTime; + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " score = " << score << endmsg; + all_items.push_back( + std::make_pair(score, + std::make_pair(&folder->second, + std::make_pair(i->iov.first,ch->first)))); + // i->score = 0; + } + } + } + } + std::sort(all_items.begin(),all_items.end()); + + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Remove items" << endmsg; + // remove items + _vec_t::iterator it = all_items.begin(); + while ( m_level > m_lowLvl && it != all_items.end()) { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Remove item since " << it->second.second.first << + " channel " << it->second.second.second << + // " from '" << it->second.first->path << "'" << + " (score =" << it->first << ")" << endmsg; + // folder when + it->second.first->erase(it->second.second.first,it->second.second.second); + --m_level; + ++it; + } + + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Remove empty folders:" << endmsg; + // remove empty folders + std::vector<FolderIdType> to_remove; + for ( StorageType::iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { + if (!i->second.sticky && i->second.empty()) { // delete folders which are empty but not sticky + to_remove.push_back(i->first); + } + } + for ( std::vector<FolderIdType>::iterator i = to_remove.begin(); i != to_remove.end(); ++i ) { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " " << *i << endmsg; + m_cache.erase(m_cache.find(*i)); + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Clean up finished (level = " << level() << ")" << endmsg; + if ( UNLIKELY(old_level == level()) ) { + m_log << MSG::WARNING << "No item removed: I increase high threshold" << endmsg; + setHighLevel(highLevel()+(highLevel()-lowLevel())/10+1); + m_log << MSG::WARNING << "New threshold = " << highLevel() << endmsg; + } +} + +//========================================================================= +// Check if an entry for the give path+time is in the cache +//========================================================================= +bool CondDBCache::hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel) const { + StorageType::const_iterator folder = m_cache.find(path); + if (folder != m_cache.end()) { + + if ( !folder->second.spec ) return true; // It's a FolderSet! They ignore time + + ItemListType::const_iterator i = folder->second.find(when,channel); + const ItemListType &lst = (*const_cast<CondFolder::StorageType *>(&folder->second.items))[channel]; + return i != lst.end(); + } + return false; +} + +ICondDBReader::IOVList CondDBCache::getIOVs(const std::string & path, const ICondDBReader::IOV & iov, cool::ChannelId channel) +{ + ICondDBReader::IOVList result; + StorageType::const_iterator folder = m_cache.find(path); + if (folder != m_cache.end()) { + if (folder->second.spec) { + // find the first recorded interval which overlaps with requested IOV + ItemListType::const_iterator i = folder->second.conflict(iov.since.ns(), iov.until.ns(), channel); + // marker for the end of IOVs in the cache for the channel + const ItemListType::const_iterator end = folder->second.end(channel); + // we add all the IOVs in the cache starting from the one found until + // we are in the list and the IOV is in the requested range. + for(; i != end && (i->iov.first < static_cast<cool::ValidityKey>(iov.until.ns())); ++i) { + result.push_back(ICondDBReader::IOV(i->iov.first, i->iov.second)); + } + } else { + // it's a FolderSet: IOV is infinite + result.push_back(ICondDBReader::IOV(Gaudi::Time::epoch(), Gaudi::Time::max())); + } + } + return result; +} + +//========================================================================= +// Dump the content of the cache to the message service. +//========================================================================= +void CondDBCache::dump() { + if (m_log.level() > MSG::DEBUG) return; // do not dump outside for non debug + m_log << MSG::DEBUG << "Cache content dump --------------------- BEGIN" << endmsg; + m_log << MSG::DEBUG << " Thresholds (high/low) -> " << m_highLvl << '/' << m_lowLvl << endmsg; + m_log << MSG::DEBUG << " Level = " << level() << endmsg; + for(StorageType::const_iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { + if ( !i->second.spec ) { // It's a FolderSet! They ignore time + m_log << MSG::DEBUG << "FolderSet '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; + continue; + } else { + m_log << MSG::DEBUG << "Folder '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; + } + + for(CondFolder::StorageType::const_iterator ch = i->second.items.begin(); ch != i->second.items.end(); ++ch) { + m_log << MSG::DEBUG << " Channel " << ch->first << endmsg; + size_t cnt = 0; + for(ItemListType::const_iterator j = ch->second.begin(); j != ch->second.end(); ++j) { + m_log << MSG::DEBUG << " Object " << cnt++ << endmsg; + m_log << MSG::DEBUG << " Score: " << j->score << endmsg; + m_log << MSG::DEBUG << " Validity: " << j->iov.first << " - " << j->iov.second << endmsg; + m_log << MSG::DEBUG << " Data: " << *(j->data)<< endmsg; + } + } + } + m_log << MSG::DEBUG << "Cache content dump --------------------- END" << endmsg; +} +//============================================================================= + diff --git a/Det/DetCond/src/component/CondDBCache.h b/Det/DetCond/src/component/CondDBCache.h new file mode 100755 index 000000000..0f8ab7994 --- /dev/null +++ b/Det/DetCond/src/component/CondDBCache.h @@ -0,0 +1,279 @@ +#ifndef COMPONENT_CONDDBCACHE_H +#define COMPONENT_CONDDBCACHE_H 1 + +// Include files +#include <string> +#include <vector> +#include <list> + +#include "GaudiKernel/MsgStream.h" + +#include "GaudiKernel/HashMap.h" + +#include "CoolKernel/types.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/ValidityKey.h" +#include "CoolKernel/IObject.h" +#include "CoolKernel/IFolder.h" +#include "CoolKernel/IRecord.h" +#include "CoolKernel/Record.h" +#include "CoolKernel/IRecordSpecification.h" +#include "CoolKernel/RecordSpecification.h" + +#include "DetCond/ICondDBReader.h" + +#include <boost/shared_ptr.hpp> + +/** @class CondDBCache CondDBCache.h component/CondDBCache.h + * + * Class used to manage in memory conditions. + * + * @author Marco Clemencic + * @date 2005-06-13 + */ +class CondDBCache { + +public: + + typedef std::pair<cool::ValidityKey,cool::ValidityKey> IOVType; + + //-------------------------------------------------------------------------------- + /// Standard constructor + CondDBCache(const MsgStream& log, size_t highLevel = 100, size_t lowLevel = 10); + + virtual ~CondDBCache( ); ///< Destructor + + /// Add a new data object to the cache. + /// \warning {no check performed} + bool insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel = 0); + + /// Shortcut for the regular implementations (for backward compatibility). + inline bool insert(const cool::IFolderPtr &folder,const cool::IObjectPtr &obj, const cool::ChannelId &channel = 0) { + return insert(folder, *obj.get(), channel); + } + + bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec); + bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec, + const std::map<cool::ChannelId,std::string>& ch_names); + bool addFolderSet(const std::string &path, const std::string &descr); + bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before = NULL); + /// (version kept for backward compatibility) + inline bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord& rec, IOVType *iov_before = NULL) + { + return addObject(path,since,until,rec,0,iov_before); + } + + + /// Search an entry in the cache and returns the data string or an empty string if no object is found. + bool get(const std::string &path, const cool::ValidityKey &when, + const cool::ChannelId &channel, + cool::ValidityKey &since, cool::ValidityKey &until, + std::string &descr, ICondDBReader::DataPtr &payload); + + /// Search an entry in the cache and returns the data string or an empty string if no object is found. + /// (version kept for backward compatibility) + inline bool get(const std::string &path, const cool::ValidityKey &when, + cool::ValidityKey &since, cool::ValidityKey &until, + std::string &descr, ICondDBReader::DataPtr &payload) { + return get(path,when,0,since,until,descr,payload); + } + + /// Find the value of the channel id for the given channel name in a folder + /// (if present in the cache). + /// Returns true if the channel name in the folder was found + bool getChannelId(const std::string &path,const std::string &name, + cool::ChannelId &channel) const; + + void getSubNodes(const std::string &path, std::vector<std::string> &node_names); + + void getSubNodes(const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets); + + /// Remove all entries from the cache; + inline void clear() {m_cache.clear();} + + /// Get the number of items cached. + inline size_t size() const; + + inline void setHighLevel(size_t lvl) { m_highLvl = lvl; } + inline void setLowLevel(size_t lvl) { m_lowLvl = lvl; } + inline size_t highLevel() const { return m_highLvl; } + inline size_t lowLevel() const { return m_lowLvl; } + + inline size_t level() const { return m_level; } + + void clean_up(); + + /// Check if the given path is present in the cache. + inline bool hasPath(const std::string &path) const { return m_cache.count(path) != 0; } + + /// Check if the path is a folderset. + inline bool isFolderSet(const std::string &path) const { + return hasPath(path) && (m_cache.find(path)->second.spec.get() == 0); + } + + /// Check if the path is a folderset. + inline bool isFolder(const std::string &path) const { + return hasPath(path) && (m_cache.find(path)->second.spec.get() != 0); + } + + /// Check if the given path,time pair is present in the cache. + bool hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const; + + /// Return the list of IOVs known for the given path, IOV, channel. + /// @see ICondDBReader::getIOVs + ICondDBReader::IOVList getIOVs(const std::string &path, const ICondDBReader::IOV &iov, cool::ChannelId channel = 0); + + void dump(); + + /// Set the flag to enable the check that the inserted IOVs are not compatible with the latest + /// requested time (needed to avoid that the cache is modified for the current event). + /// @return previous value + bool setIOVCheck(bool enable) + { + bool old = m_checkLastReqTime; + m_checkLastReqTime = enable; + return old; + } + + /// Tell if the check on inserted IOVs is enabled. + bool IOVCheck() { return m_checkLastReqTime; } + + /// Getter for the data member m_silentConflicts. + bool silentConflicts() const { return m_silentConflicts; } + + /// Getter for the data member m_silentConflicts. + void setSilentConflicts(bool value) { m_silentConflicts = value; } + +protected: + +private: + + struct CondFolder; + struct CondItem; + + typedef std::string FolderIdType; + //typedef std::vector<CondItem> ItemListType; + typedef std::list<CondItem> ItemListType; + // typedef std::map<FolderIdType,CondFolder> FolderListType; + typedef GaudiUtils::HashMap<FolderIdType,CondFolder> StorageType; + + /// Internal class used to record IOV+data pairs + struct CondItem { + /// Constructor. + CondItem(CondFolder *myFolder, const cool::IObject &obj): + folder(myFolder),iov(obj.since(),obj.until()), + data(new cool::Record(obj.payload())),score(1.0) {} + CondItem(CondFolder *myFolder, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord &rec): + folder(myFolder),iov(since,until), data(new cool::Record(rec)),score(1.0) {} + CondFolder *folder; + IOVType iov; + ICondDBReader::DataPtr data; + float score; + /// Check if the CondItem is valid at the given time. + inline bool valid(const cool::ValidityKey &when) const { + return iov.first <= when && when < iov.second; + } + }; + + /// Internal class used to keep the items common to a given path. + struct CondFolder { + + typedef GaudiUtils::Map<cool::ChannelId,ItemListType> StorageType; + typedef GaudiUtils::HashMap<std::string,cool::ChannelId> ChannelNamesMapType; + + CondFolder(const cool::IFolderPtr &fld): + description(fld->description()), + spec(new cool::RecordSpecification(fld->payloadSpecification())), + sticky(false) {} + CondFolder(const std::string &descr, const cool::IRecordSpecification& new_spec): + description(descr),spec(new cool::RecordSpecification(new_spec)),sticky(true) {} + // for a folderset (FolderSets are identified by missing spec) + CondFolder(const std::string &descr): + description(descr),sticky(true) {} + std::string description; + boost::shared_ptr<cool::IRecordSpecification> spec; + StorageType items; + ChannelNamesMapType channelNames; + bool sticky; + /// Search for the first item in the storage valid at the given time. + inline ItemListType::iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { + ItemListType &lst = items[channel]; + ItemListType::iterator i; + for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} + return i; + } + /// Const version of the search method. + inline ItemListType::const_iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const { + const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; + ItemListType::const_iterator i; + for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} + return i; + } + inline ItemListType::iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::ChannelId &channel = 0) { + ItemListType &lst = items[channel]; + ItemListType::iterator i; + for ( i = lst.begin(); i != lst.end() ; ++i ){ + // Given two IOVs a and b, they conflict if the intersection is not empty: + // max(a.s,b.s) < min(a.u,b.u) + if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; + } + return i; + } + inline ItemListType::const_iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::ChannelId &channel = 0) const { + const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; + ItemListType::const_iterator i; + for ( i = lst.begin(); i != lst.end() ; ++i ){ + if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; + } + return i; + } + inline ItemListType::iterator end(const cool::ChannelId &channel = 0) { + return items[channel].end(); + } + inline ItemListType::const_iterator end(const cool::ChannelId &channel = 0) const { + return (*const_cast<StorageType *>(&items))[channel].end(); + } + inline void erase (const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { + items[channel].erase(find(when,channel)); + } + inline bool empty() const { + for (StorageType::const_iterator ch = items.begin(); ch != items.end(); ++ch ) { + if (! ch->second.empty()) return false; + } + return true; + } + + }; + + /// Actual storage + StorageType m_cache; + + size_t m_highLvl; + size_t m_lowLvl; + size_t m_level; + + MsgStream m_log; + + cool::ValidityKey m_lastRequestedTime; + bool m_checkLastReqTime; + + // Do not print warning messages in case of conflicts during the insertion + bool m_silentConflicts; +}; + +inline size_t CondDBCache::size() const { + size_t count = 0; + StorageType::const_iterator folder; + for (folder = m_cache.begin(); folder != m_cache.end(); ++folder) { + for (CondFolder::StorageType::const_iterator ch = folder->second.items.begin(); ch != folder->second.items.end(); ++ch) + count += ch->second.size(); + } + return count; +} + +#endif // COMPONENT_CONDDBCACHE_H diff --git a/Det/DetCond/src/component/CondDBCnvSvc.cpp b/Det/DetCond/src/component/CondDBCnvSvc.cpp new file mode 100755 index 000000000..a192987ee --- /dev/null +++ b/Det/DetCond/src/component/CondDBCnvSvc.cpp @@ -0,0 +1,197 @@ +#include <string> + +#include "CondDBCnvSvc.h" +#include "DetCond/ICondDBReader.h" + +#include "GaudiKernel/GenericAddress.h" +#include "GaudiKernel/IDetDataSvc.h" +#include "GaudiKernel/IDataProviderSvc.h" +#include "GaudiKernel/MsgStream.h" + +/// Instantiation of a static factory to create instances of this service +DECLARE_SERVICE_FACTORY(CondDBCnvSvc) + +//---------------------------------------------------------------------------- + +/// Constructor +CondDBCnvSvc::CondDBCnvSvc( const std::string& name, ISvcLocator* svc) + : base_class ( name, svc, CONDDB_StorageType ), + m_dbReader(0) +{ + declareProperty( "CondDBReader", m_dbReaderName = "CondDBAccessSvc" ); +} + +//---------------------------------------------------------------------------- + +/// Destructor +CondDBCnvSvc::~CondDBCnvSvc() {} + +//---------------------------------------------------------------------------- + +/// Initialize the service. +StatusCode CondDBCnvSvc::initialize() +{ + + // Before anything else, we need to initialise the base class + StatusCode sc = base_class::initialize(); + if ( !sc.isSuccess() ) return sc; + + // Now we can get a handle to the MessageSvc + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Specific initialization starting" << endmsg; + + // Locate the Database Access Service + sc = service(m_dbReaderName,m_dbReader,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << m_dbReaderName << endmsg; + return sc; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved " << m_dbReaderName << endmsg; + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Specific initialization completed" << endmsg; + return sc; +} + +//---------------------------------------------------------------------------- + +/// Finalize the service. +StatusCode CondDBCnvSvc::finalize() +{ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalizing" << endmsg; + if (m_dbReader) m_dbReader->release(); + return base_class::finalize(); +} + +//---------------------------------------------------------------------------- + +/// Create an address using explicit arguments to identify a single object. +/// Par[0] is folder name in the CondDB. +/// Par[1] is entry name in the string (which may contain many conditions, +/// for instance in the case of XML files with more than one element). +StatusCode CondDBCnvSvc::createAddress( long svc_type, + const CLID& clid, + const std::string* par, + const unsigned long* ipar, + IOpaqueAddress*& refpAddress ) { + + // First check that requested address is of type CONDDB_StorageType + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering createAddress" << endmsg; + if ( svc_type!= CONDDB_StorageType ) { + log << MSG::ERROR + << "Cannot create addresses of type " << (int)svc_type + << " which is different from " << (int)CONDDB_StorageType + << endmsg; + return StatusCode::FAILURE; + } + + // Par[0] is folder name in the CondDB. + std::string folderName = par[0]; + + // Par[1] is entry name in the string (which may contain many conditions, + // for instance in the case of XML files with more than one element). + std::string entryName = par[1]; + + // iPar[0] is the cool::ChannelId + unsigned long channelId = ipar[0]; + + // Now create the address + refpAddress = new GenericAddress( CONDDB_StorageType, + clid, + folderName, + entryName, + channelId ); + return StatusCode::SUCCESS; + +} + +//---------------------------------------------------------------------------- + +/// Retrieve converter from list +IConverter* CondDBCnvSvc::converter(const CLID& clid) { + IConverter* cnv = 0; + cnv = ConversionSvc::converter(clid); + if ( cnv ) { + return cnv; + } + else { + return ConversionSvc::converter(CLID_Any); + } +} + +//---------------------------------------------------------------------------- +// Implementation of ICondDBReader +StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) +{ + return m_dbReader->getObject(path,when,data,descr,since,until,channel); +} + +StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) +{ + return m_dbReader->getObject(path,when,data,descr,since,until,channel); +} + +StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) +{ + return m_dbReader->getChildNodes(path,node_names); +} + +StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) +{ + return m_dbReader->getChildNodes(path,folders,foldersets); +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBCnvSvc::exists(const std::string &path) { + return m_dbReader->exists(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBCnvSvc::isFolder(const std::string &path) { + return m_dbReader->isFolder(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBCnvSvc::isFolderSet(const std::string &path) { + return m_dbReader->isFolder(path); +} + +void CondDBCnvSvc::disconnect() { + if(m_dbReader) + m_dbReader->disconnect(); +} + +ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return m_dbReader->getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return m_dbReader->getIOVs(path, iov, channel); +} + +void CondDBCnvSvc::defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const +{ + tags.clear(); + m_dbReader->defaultTags(tags); +} + diff --git a/Det/DetCond/src/component/CondDBCnvSvc.h b/Det/DetCond/src/component/CondDBCnvSvc.h new file mode 100755 index 000000000..88430fd0a --- /dev/null +++ b/Det/DetCond/src/component/CondDBCnvSvc.h @@ -0,0 +1,123 @@ +#ifndef DETCOND_CONDDBCNVSVC_H +#define DETCOND_CONDDBCNVSVC_H 1 + +/// Include files +#include "GaudiKernel/ConversionSvc.h" + +#include "DetCond/ICondDBReader.h" + +/// Forward and external declarations +template <class TYPE> class SvcFactory; +class IDetDataSvc; +class IOpaqueAddress; + +///--------------------------------------------------------------------------- +/** @class CondDBCnvSvc CondDBCnvSvc.h + + A conversion service for CERN-IT COOL (ex. CondDB) persistency. + Allows to create and update condition data objects (i.e. DataObjects + implementing IValidity). + + @author Marco Clemencic + @date November 2004 +*///-------------------------------------------------------------------------- + +class CondDBCnvSvc : public extends1<ConversionSvc, ICondDBReader> { + + /// Only factories can access protected constructors + friend class SvcFactory<CondDBCnvSvc>; + +protected: + + /// Constructor + CondDBCnvSvc( const std::string& name, ISvcLocator* svc ); + + /// Destructor + virtual ~CondDBCnvSvc(); + +public: + + // Overloaded from ConversionSvc + + /// Initialize the service + virtual StatusCode initialize(); + + /// Finalize the service + virtual StatusCode finalize(); + + using ConversionSvc::createAddress; + /// Create an address using explicit arguments to identify a single object. + virtual StatusCode createAddress (long svc_type, + const CLID& clid, + const std::string* par, + const unsigned long* ip, + IOpaqueAddress*& refpAddress ); + +public: + + /// Retrieve converter from list + virtual IConverter* converter(const CLID& clid); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + +private: + + /// List of all the names of the known databases. It is filled via the option + /// CondDBCnvSvc.CondDBReader. If none is given, "CondDBAccessSvc" is used. + std::string m_dbReaderName; + + /// Handles to the database Access services + ICondDBReader* m_dbReader; + +protected: + +}; + +#endif // DETCOND_CONDITIONSDBCNVSVC_H + + diff --git a/Det/DetCond/src/component/CondDBCommon.cpp b/Det/DetCond/src/component/CondDBCommon.cpp new file mode 100755 index 000000000..c0fbf40bb --- /dev/null +++ b/Det/DetCond/src/component/CondDBCommon.cpp @@ -0,0 +1,90 @@ +#include "CondDBCommon.h" + +#include <sstream> + +#include "CoolKernel/RecordSpecification.h" +#include "CoolKernel/Record.h" +#include "CoolKernel/StorageType.h" + +static std::unique_ptr<cool::RecordSpecification> s_XMLStorageSpec{}; + +namespace CondDB { + +const cool::RecordSpecification& getXMLStorageSpec() { + if ( s_XMLStorageSpec.get() == NULL){ + // attribute list spec template + s_XMLStorageSpec = std::unique_ptr<cool::RecordSpecification>(new cool::RecordSpecification()); + s_XMLStorageSpec->extend("data", cool::StorageType::String16M); + } + return *s_XMLStorageSpec; +} + +namespace { + inline bool ends_with(const std::string& s, const std::string &suff) { + const auto count = suff.size(); + const auto size = s.size(); + return (size >= count) && + (s.compare(size - count, count, suff) == 0); + } +} + +void generateXMLCatalog(const std::string &name, + const std::vector<std::string> &fldrs, + const std::vector<std::string> &fldrsets, + std::string &data) { + std::ostringstream xml; // buffer for the XML + + // XML header, root element and catalog initial tag + xml << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + << "<!DOCTYPE DDDB SYSTEM \"conddb:/DTD/structure.dtd\">" + << "<DDDB><catalog name=\"" << name << "\">"; + + // sub-folders are considered as container of conditions + std::vector<std::string>::const_iterator f; + for (const auto& f: fldrs) { + // Ignore folders with the .xml extension. + // We never used .xml for Online conditions and after the Hlt1/Hlt2 split + // we need to avoid automatic mapping for the .xml files. + if (!ends_with(f, ".xml")) { + xml << "<conditionref href=\"" << name << '/' << f << "\"/>"; + } + } + // sub-foldersets are considered as catalogs + for (const auto& f: fldrsets) { + xml << "<catalogref href=\"" << name << '/' << f << "\"/>"; + } + // catalog and root element final tag + xml << "</catalog></DDDB>"; + + data = xml.str(); +} + +StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, + ICondDBReader::DataPtr &payload){ + // get the list of subnodes + std::vector<std::string> folders, foldersets; + StatusCode sc = reader->getChildNodes(path,folders,foldersets); + if (sc.isFailure()) return sc; + + // extract the name of the folderset + std::string::size_type pos = path.rfind('/'); + std::string name; + if ( std::string::npos != pos ) { + name = path.substr(pos+1); + } else { + name = path; + } + + // generate the XML catalog + std::string xml; + generateXMLCatalog(name,folders,foldersets,xml); + + // prepare new payload + cool::Record *rec = new cool::Record(getXMLStorageSpec()); + (*rec)["data"].setValue<cool::String16M>(xml); + payload.reset(rec); + + return sc; +} + +} diff --git a/Det/DetCond/src/component/CondDBCommon.h b/Det/DetCond/src/component/CondDBCommon.h new file mode 100755 index 000000000..476f26811 --- /dev/null +++ b/Det/DetCond/src/component/CondDBCommon.h @@ -0,0 +1,29 @@ +#ifndef CONDDBCOMMON_H_ +#define CONDDBCOMMON_H_ + +#include <string> +#include <vector> +#include "DetCond/ICondDBReader.h" + +// forward declaration +namespace cool{ + class RecordSpecification; +} + +/** @file Utility functions shared among DetCond components. + * + * @author Marco Clemencic + */ +namespace CondDB { + void generateXMLCatalog(const std::string &name, + const std::vector<std::string> &fldrs, + const std::vector<std::string> &fldrsets, + std::string &data); + + StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, + ICondDBReader::DataPtr &data); + + const cool::RecordSpecification& getXMLStorageSpec(); +} + +#endif /*CONDDBCOMMON_H_*/ diff --git a/Det/DetCond/src/component/CondDBDQScanner.cpp b/Det/DetCond/src/component/CondDBDQScanner.cpp new file mode 100644 index 000000000..48cdd8556 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDQScanner.cpp @@ -0,0 +1,147 @@ +// Include files + +// From Gaudi +#include "GaudiKernel/IConverter.h" +#include "GaudiKernel/IAddressCreator.h" +#include "GaudiKernel/IOpaqueAddress.h" + +#include "CoolKernel/IRecord.h" +#include "CoolKernel/RecordException.h" + +// From LHCb +#include "DetCond/ICondDBReader.h" +#include "DetDesc/Condition.h" + +// local +#include "CondDBDQScanner.h" +#include "RelyConverter.h" + +// ---------------------------------------------------------------------------- +// Implementation file for class: CondDBDQScanner +// +// 04/11/2011: Marco Clemencic +// ---------------------------------------------------------------------------- +DECLARE_TOOL_FACTORY(CondDBDQScanner) + +// ============================================================================ +// Standard constructor, initializes variables +// ============================================================================ +CondDBDQScanner::CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent) + : base_class(type, name, parent) +{ + + declareProperty("ConditionPath", + m_condPath = "/Conditions/DQ/Flags", + "Path in the Conditions Database where to find the Data " + "Quality condition."); + + declareProperty("CondDBReader", + m_condDBReaderName = "CondDBCnvSvc", + "Service implementing the ICondDBReader interface to be used " + "to access the CondDB."); + + declareProperty("Converter", + m_converterName = "DetectorPersistencySvc", + "Service implementing the IConverter interface."); +} + +CondDBDQScanner::~CondDBDQScanner() {} + +IDQFilter::FlagsType CondDBDQScanner::scan(const Gaudi::Time & since, const Gaudi::Time & until) const +{ + typedef ICondDBReader::IOVList IOVList; + typedef ICondDBReader::IOV IOV; + IDQFilter::FlagsType flags; + + ICondDBReader::DataPtr data; + Gaudi::Time dataSince, dataUntil; + std::string desc; + + // Loop over the list of conditions in the folder + IOVList iovs = m_condDB->getIOVs(m_condPath, IOV(since, until)); + for(IOVList::iterator iov = iovs.begin(); iov != iovs.end(); ++iov) { + // get the condition data (XML) + StatusCode sc = m_condDB->getObject(m_condPath, iov->since, data, desc, dataSince, dataUntil); + if (sc.isFailure()){ + Exception("Problems retrieving data from the database"); + return flags; // never reached, but helps Coverity + } + + try { + // prepare the IOpaqueAddress to be given to the PersistencySvc + const long storageType = RelyConverter::getStorageType(m_condPath, desc); + const std::string xml_data = (*data.get())["data"].data<std::string>(); + IOpaqueAddress *addr = RelyConverter::createTmpAddress("conddb:" + m_condPath, + storageType, + "Flags", + Condition::classID(), + xml_data, + info(), + m_converter->addressCreator()); + if (!addr){ + Exception("Failed to create temporary IOpaqueAddress"); + return flags; // never reached, but helps Coverity + } + + // Retrieve the condition data + DataObject *obj = 0; + Condition *cond = 0; + if (m_converter->createObj(addr, obj).isFailure() + || m_converter->fillObjRefs(addr, obj).isFailure() + || (cond = dynamic_cast<Condition*>(obj)) == 0) { //assignment intended + delete addr; + if (obj) delete obj; + Exception("Conversion of Condition failed"); + return flags; // never reached, but helps Coverity + } + delete addr; + + // Merge the condition map with the collected one. + const IDQFilter::FlagsType &condFlags = cond->param<IDQFilter::FlagsType>("map"); + flags.insert(condFlags.begin(), condFlags.end()); + + delete obj; + + } catch (cool::RecordSpecificationUnknownField &e) { + Exception(std::string("I cannot find the data inside COOL object: ") + e.what()); + } + } + + return flags; +} + + + + +StatusCode CondDBDQScanner::initialize() +{ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + m_condDB = service(m_condDBReaderName); + if (UNLIKELY(!m_condDB.isValid())) { + error() << "Cannot get the ICondDBReader implementation " << m_condDBReaderName << endmsg; + return StatusCode::FAILURE; + } + + m_converter = service(m_converterName); + if (UNLIKELY(!m_converter.isValid())) { + error() << "Cannot get the IConverter implementation " << m_converterName << endmsg; + return StatusCode::FAILURE; + } + + return sc; +} + + + +StatusCode CondDBDQScanner::finalize() +{ + m_condDB.reset(); // release the ICondDBReader service + + return base_class::finalize(); +} + + + +// ============================================================================ diff --git a/Det/DetCond/src/component/CondDBDQScanner.h b/Det/DetCond/src/component/CondDBDQScanner.h new file mode 100644 index 000000000..c686a8fd4 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDQScanner.h @@ -0,0 +1,56 @@ +#ifndef SRC_CONDDBDQSCANNER_H +#define SRC_CONDDBDQSCANNER_H 1 +// Include files +// from Gaudi +#include "GaudiAlg/GaudiTool.h" +#include "GaudiKernel/SmartIF.h" + +// Implemented interfaces +#include "Kernel/IDQScanner.h" // IDQScanner + +class ICondDBReader; +class IConverter; + +/** Basic implementation of an IDQScanner based on the Conditions Database. + * + * @author Marco Clemencic + * @date 04/11/2011 + */ +class CondDBDQScanner: public extends1<GaudiTool, IDQScanner> { +public: + /// Standard constructor + CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent); + virtual ~CondDBDQScanner(); ///< Destructor + + /// Scan all the Data Quality flags in the give time range in the CondDB. + /// @return merged list of DQ flags + virtual IDQFilter::FlagsType scan(const Gaudi::Time& since, const Gaudi::Time& until) const; + + virtual StatusCode initialize(); ///< Initialize the instance. + virtual StatusCode finalize(); ///< Finalize the instance. + +protected: +private: + + /// Path to the condition object containing the Data Quality flags. + /// (property ConditionPath) + std::string m_condPath; + + /// ICondDBReader implementation to use to access the Conditions Database. + /// (property CondDBReader) + std::string m_condDBReaderName; + + /// IConverter implementation (e.g. the persistency service) to use to convert + /// the data to a Condition. + /// (property Converter) + std::string m_converterName; + + /// ICondDBReader instance. + SmartIF<ICondDBReader> m_condDB; + + /// ICondDBReader instance. + SmartIF<IConverter> m_converter; + +}; + +#endif // SRC_CONDDBDQSCANNER_H diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.cpp b/Det/DetCond/src/component/CondDBDispatcherSvc.cpp new file mode 100755 index 000000000..624638275 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDispatcherSvc.cpp @@ -0,0 +1,294 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +// local +#include "CondDBDispatcherSvc.h" +#include "CondDBCommon.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBDispatcherSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBDispatcherSvc +// +// 2006-07-10 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBDispatcherSvc::CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc), + m_mainDB(0), + m_alternatives() +{ + declareProperty("MainAccessSvc", m_mainAccessSvcName = "CondDBAccessSvc" ); + declareProperty("Alternatives", m_alternativesDeclarationMap ); + + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBDispatcherSvc::~CondDBDispatcherSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBDispatcherSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + // locate the main access service + sc = service(m_mainAccessSvcName,m_mainDB,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << m_mainAccessSvcName << endmsg; + return sc; + } + + // locate all the alternative AccessSvcs + std::map<std::string,std::string>::iterator decl; + for ( decl = m_alternativesDeclarationMap.begin(); decl != m_alternativesDeclarationMap.end(); ++decl ) { + const std::string &altPath = decl->first; + const std::string &svcName = decl->second; + + if ( m_alternatives.find(altPath) != m_alternatives.end() ) { + log << MSG::ERROR << "More than one alternative for path " << altPath << endmsg; + return StatusCode::FAILURE; + } + + ICondDBReader *svcPtr; + sc = service(svcName,svcPtr,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << svcName << endmsg; + return sc; + } + + m_alternatives[altPath] = svcPtr; + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved '" << svcName << "' (for path '" << altPath << "')" << endmsg; + + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBDispatcherSvc::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + + if (m_mainDB) { + m_mainDB->release(); + m_mainDB = 0; + } + + std::map<std::string,ICondDBReader*>::iterator alt; + for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { + if (alt->second) alt->second->release(); + } + m_alternatives.clear(); + + return base_class::finalize(); +} + +ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return alternativeFor(path)->getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return alternativeFor(path)->getIOVs(path, iov, channel); +} + +//========================================================================= +// find the appropriate alternative +//========================================================================= +ICondDBReader *CondDBDispatcherSvc::alternativeFor(const std::string &path) const { + MsgStream log(msgSvc(), name() ); + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Get alternative DB for '" << path << "'" << endmsg; + if ( path.empty() || (path == "/") ) { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Root node: using '" << m_mainAccessSvcName << "'" << endmsg; + return m_mainDB; + } + + // loop over alternatives + std::map<std::string,ICondDBReader*>::const_reverse_iterator alt; + for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { + if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { + log << MSG::VERBOSE << "Comparing with " << alt->first << endmsg; + } + // FIXME: (MCl) wrong logic + // path=/Conditions/Velo/AlignmentCatalog.xml + // alt.=/Conditions/Velo/Alignment + // Should not match + if ( ( path.size() >= alt->first.size() ) && + ( path.substr(0,alt->first.size()) == alt->first ) ){ + if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { + IService *svc = dynamic_cast<IService*>(alt->second); + log << MSG::VERBOSE << "Using '" ; + if (svc) log << svc->name(); + else log << "unknown"; + log << "'" << endmsg; + } + + return alt->second; + } + } + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Not found: using '" << m_mainAccessSvcName << "'" << endmsg; + return m_mainDB; +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) { + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); + } + return sc; +} +StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) { + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); + } + return sc; +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { + return getChildNodes(path,node_names,node_names); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) { + // clear the destination vectors + folders.clear(); + foldersets.clear(); + + // Get the folders and foldersets from the dedicated alternative + std::vector<std::string> tmpv1,tmpv2; + StatusCode sc = alternativeFor(path)->getChildNodes(path,tmpv1,tmpv2); + if (sc.isFailure()) return sc; + + // Find alternatives for subfolders of the path. + std::map<std::string,ICondDBReader*>::reverse_iterator alt; + std::string::size_type path_size = path.size(); + for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { + // check if the path for the alternative is a subfolder of the required path + // i.e. alt->first should be = path + '/' + extra + if ( ( alt->first.size() > (path_size+1) ) && // it must be long enough + ( alt->first[path_size] == '/' ) && + ( alt->first.substr(0,path_size) == path ) ){ + // take the name of the child folder[set] implied by the alternative + // i.e. substring from after (path+'/') to the next '/' + std::string sub = alt->first.substr(path_size+1, + alt->first.find('/',path_size+1)-(path_size+1)); + if (std::find(tmpv1.begin(),tmpv1.end(),sub) == tmpv1.end() && + std::find(tmpv2.begin(),tmpv2.end(),sub) == tmpv2.end()){ + // this subnode is an addition due to the alternative + // let's check the type + if (alt->second->isFolder(path+'/'+sub)) + tmpv1.push_back(sub); // folder + else + tmpv2.push_back(sub); // folderset + } + } + } + + // copy the temporary vectors to the output ones + folders = tmpv1; + foldersets = tmpv2; + return sc; +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBDispatcherSvc::exists(const std::string &path) { + return alternativeFor(path)->exists(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBDispatcherSvc::isFolder(const std::string &path) { + return alternativeFor(path)->isFolder(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBDispatcherSvc::isFolderSet(const std::string &path) { + return alternativeFor(path)->isFolderSet(path); +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBDispatcherSvc::disconnect() { + // loop over alternatives + std::map<std::string,ICondDBReader*>::const_iterator alt; + for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { + alt->second->disconnect(); + } + if (m_mainDB) + m_mainDB->disconnect(); +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBDispatcherSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + // first add the main db + m_mainDB->defaultTags(tags); + + // loop over alternatives + std::map<std::string,ICondDBReader*>::const_iterator alt; + for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { + alt->second->defaultTags(tags); + } +} + + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.h b/Det/DetCond/src/component/CondDBDispatcherSvc.h new file mode 100755 index 000000000..2e3819280 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDispatcherSvc.h @@ -0,0 +1,109 @@ +#ifndef COMPONENT_CONDDBDISPATCHERSVC_H +#define COMPONENT_CONDDBDISPATCHERSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "DetCond/ICondDBReader.h" +#include <vector> +#include <map> + +template <class TYPE> class SvcFactory; + +/** @class CondDBDispatcherSvc CondDBDispatcherSvc.h component/CondDBDispatcherSvc.h + * + * + * + * @author Marco Clemencic + * @date 2006-07-10 + */ +class CondDBDispatcherSvc: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + + +protected: + /// Standard constructor + CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBDispatcherSvc( ); ///< Destructor + + +private: + + ICondDBReader *alternativeFor(const std::string &path) const; + + // -------------------- Data Members + + /// Property CondDBDispatcherSvc.MainAccessSvc: the AccessSvc instance to use to retrieve all the + /// objects for which an alternative is not specified (default to "CondDBAccessSvc"). + std::string m_mainAccessSvcName; + + /// Property CondDBDispatcherSvc.Alternatives: list of alternative Access Services in the form of + /// "/path/for/alternative":"ServiceType/ServiceName". + std::map<std::string,std::string> m_alternativesDeclarationMap; + + /// Pointer to the main access service. + ICondDBReader* m_mainDB; + + /// Container fo the alternatives. + std::map<std::string,ICondDBReader*> m_alternatives; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBDispatcherSvc>; + +}; +#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.cpp b/Det/DetCond/src/component/CondDBLayeringSvc.cpp new file mode 100755 index 000000000..d78161e24 --- /dev/null +++ b/Det/DetCond/src/component/CondDBLayeringSvc.cpp @@ -0,0 +1,288 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +// local +#include "CondDBLayeringSvc.h" +#include "CondDBCommon.h" +#include "IOVListHelpers.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBLayeringSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBLayeringSvc +// +// 2006-07-14 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +// This is needed otherwise the implementation of std::map does +// not find operator<(Gaudi::Time,Gaudi::Time). +namespace Gaudi { using ::operator<; } + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBLayeringSvc::CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc) { + + declareProperty("Layers", m_layersNames ); + + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); + +} +//============================================================================= +// Destructor +//============================================================================= +CondDBLayeringSvc::~CondDBLayeringSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBLayeringSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + // locate all the AccessSvcs layers + std::vector<std::string>::iterator lname; + for ( lname = m_layersNames.begin(); lname != m_layersNames.end(); ++lname ) { + + ICondDBReader *svcPtr; + sc = service(*lname,svcPtr,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << *lname << endmsg; + return sc; + } + + m_layers.push_back(svcPtr); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved '" << *lname << "'" << endmsg; + + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBLayeringSvc::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + + std::vector<ICondDBReader*>::iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ( *layer ) (*layer)->release(); + } + m_layers.clear(); + + return base_class::finalize(); +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) +{ + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + std::vector<ICondDBReader*>::iterator layer; + sc = StatusCode::FAILURE; + for ( layer = m_layers.begin(); + layer != m_layers.end() && sc.isFailure(); + ++layer ) { + sc = (*layer)->getObject(path,when,data,descr,since,until,channel); + } + } + return sc; +} +StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) +{ + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + std::vector<ICondDBReader*>::iterator layer; + sc = StatusCode::FAILURE; + for ( layer = m_layers.begin(); + layer != m_layers.end() && sc.isFailure(); + ++layer ) { + sc = (*layer)->getObject(path,when,data,descr,since,until,channel); + } + } + return sc; +} + +template <typename Channel> +ICondDBReader::IOVList CondDBLayeringSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) +{ + IOVList iovs; + + IOVList missing; // IOVs not found + missing.push_back(iov); + + std::vector<ICondDBReader*>::iterator layer; + // for each layer + for ( layer = m_layers.begin(); + layer != m_layers.end() && !missing.empty(); + ++layer ) { + + IOVList layer_iovs; + + // look for the missing IOVs in this layer + for ( IOVList::iterator m = missing.begin(); + m != missing.end(); + ++m ) { + IOVList missing_iovs = (*layer)->getIOVs(path, *m, channel); + // if we found something merge with the others in the layer + if (!missing_iovs.empty()) { + // ensure that the found IOVs do not overlap with the already available ones + missing_iovs.front().since = std::max(missing_iovs.front().since, m->since); + missing_iovs.back().until = std::min(missing_iovs.back().until, m->until); + layer_iovs.insert(layer_iovs.end(), missing_iovs.begin(), missing_iovs.end()); + } + else continue; + } + + // if we got IOVs in this layer, we add them to the results list + if (!layer_iovs.empty()) { + iovs.insert(iovs.end(), layer_iovs.begin(), layer_iovs.end()); + std::sort(iovs.begin(), iovs.end()); + // regenerate the list of holes + missing = IOVListHelpers::find_holes(iovs, iov); + } + } + + return iovs; +} + +ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return i_getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return i_getIOVs(path, iov, channel); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) +{ + return getChildNodes(path,node_names,node_names); +} + +namespace { + // helper function + template <class Input, class Output> + void merge(const Input &i, Output &o){ + typename Input::const_iterator it; + for (it = i.begin(); it != i.end(); ++it){ + if (std::find(o.begin(),o.end(),*it)==o.end()) { + o.push_back(*it); + } + } + } +} +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) +{ + // clear the destination vectors + folders.clear(); + foldersets.clear(); + + // Get the folders and foldersets from the dedicated alternative + std::vector<std::string> tmpv1,tmpv2; + StatusCode sc = StatusCode::FAILURE; + std::vector<ICondDBReader*>::iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->getChildNodes(path,tmpv1,tmpv2).isSuccess()){ + // we consider it a success if it worked at least for one of the layers + sc = StatusCode::SUCCESS; + merge(tmpv1,folders); + merge(tmpv2,foldersets); + } + } + return sc; +} +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBLayeringSvc::exists(const std::string &path) { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->exists(path)) return true; + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBLayeringSvc::isFolder(const std::string &path) { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->exists(path)) return (*layer)->isFolder(path); + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBLayeringSvc::isFolderSet(const std::string &path) { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->exists(path)) return (*layer)->isFolderSet(path); + } + return false; +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBLayeringSvc::disconnect() { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + (*layer)->disconnect(); + } +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBLayeringSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + // loop over layers + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + (*layer)->defaultTags(tags); + } +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.h b/Det/DetCond/src/component/CondDBLayeringSvc.h new file mode 100755 index 000000000..c821688ef --- /dev/null +++ b/Det/DetCond/src/component/CondDBLayeringSvc.h @@ -0,0 +1,103 @@ +#ifndef COMPONENT_CONDDBLAYERINGSVC_H +#define COMPONENT_CONDDBLAYERINGSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "DetCond/ICondDBReader.h" +#include <vector> + +template <class TYPE> class SvcFactory; + +/** @class CondDBLayeringSvc CondDBLayeringSvc.h component/CondDBLayeringSvc.h + * + * + * @author Marco CLEMENCIC + * @date 2006-07-14 + */ +class CondDBLayeringSvc: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + +protected: + + /// Standard constructor + CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBLayeringSvc( ); ///< Destructor + +protected: + +private: + + // -------------------- Data Members + + /// Property CondDBLayeringSvc.Layers: list of Access Service layers. + /// They will be searched from the first to the last. + std::vector<std::string> m_layersNames; + + /// Container fo the alternatives. + std::vector<ICondDBReader*> m_layers; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBLayeringSvc>; + + /// Internal implementation helper to generalize the channel type. + template <typename Channel> + IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); + +}; +#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBLogger.cpp b/Det/DetCond/src/component/CondDBLogger.cpp new file mode 100755 index 000000000..9ec6bc57f --- /dev/null +++ b/Det/DetCond/src/component/CondDBLogger.cpp @@ -0,0 +1,250 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +#include <fstream> + +// local +#include "CondDBLogger.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBLogger) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBLogger +// +// 2008-01-24 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBLogger::CondDBLogger( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc), m_loggedReader(nullptr) { + + declareProperty("LoggedReader", m_loggedReaderName = "", + "Fully qualified name of the ICondDBReader to which the calls" + " have to be forwarded."); + declareProperty("LogFile", m_logFileName = "", + "Path to the log file (it is overwritten if it exists). " + "If not specified or set to empty, the file name is set from " + "the name of the instance plus '.log'." ); + +} +//============================================================================= +// Destructor +//============================================================================= +CondDBLogger::~CondDBLogger() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBLogger::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if ( m_loggedReaderName.empty() ){ + log << MSG::ERROR << "Property LoggedReader is not set." << endmsg; + return StatusCode::FAILURE; + } + + // locate the CondDBReader + sc = service(m_loggedReaderName,m_loggedReader,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << m_loggedReaderName << endmsg; + return sc; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved '" << m_loggedReaderName << "'" << endmsg; + + // Set the default value of the file name if not specified. + if ( m_logFileName.empty() ){ + m_logFileName = name() + ".log"; + log << MSG::INFO << "Property LogFile not specified, using '" + << m_logFileName << "'" << endmsg; + } + + // Open the output file and start writing. + m_logFile = std::unique_ptr<std::ostream>(new std::ofstream(m_logFileName.c_str())); + if ( ! m_logFile->good() ) { + log << MSG::ERROR << "Problems opening " << m_logFileName << endmsg; + return StatusCode::FAILURE; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "File '" << m_logFileName << "' opened for writing." << endmsg; + + (*m_logFile) << "INI: " << Gaudi::Time::current().ns() << " " << name() << " logging " << m_loggedReaderName << std::endl; + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBLogger::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + + if ( m_loggedReader ) { + m_loggedReader->release(); + m_loggedReader = 0; + } + + if (m_logFile.get()) { + (*m_logFile) << "FIN: " << Gaudi::Time::current().ns() << " " << name() << std::endl; + m_logFile.reset(0); + } + + return base_class::finalize(); +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GET: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << when.ns() << " " << std::flush; + StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} +StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GCN: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << when.ns() << " " << std::flush; + StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} + +ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "IOV: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << iov.since.ns() << " " << iov.until.ns() << std::endl; + return m_loggedReader->getIOVs(path, iov, channel); + } + return ICondDBReader::IOVList(); +} + +ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "ICN: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << iov.since.ns() << " " << iov.until.ns() << std::endl; + return m_loggedReader->getIOVs(path, iov, channel); + } + return ICondDBReader::IOVList(); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLogger::getChildNodes (const std::string &path, std::vector<std::string> &node_names) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + StatusCode sc = m_loggedReader->getChildNodes(path,node_names); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLogger::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + StatusCode sc = m_loggedReader->getChildNodes(path,folders,foldersets); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBLogger::exists(const std::string &path) { + if ( m_loggedReader ) { + (*m_logFile) << "XST: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + bool out = m_loggedReader->exists(path); + (*m_logFile) << out << std::endl; + return out; + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBLogger::isFolder(const std::string &path) { + if ( m_loggedReader ) { + (*m_logFile) << "IFL: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + bool out = m_loggedReader->isFolder(path); + (*m_logFile) << out << std::endl; + return out; + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBLogger::isFolderSet(const std::string &path) { + if ( m_loggedReader ) { + (*m_logFile) << "IFS: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + bool out = m_loggedReader->isFolderSet(path); + (*m_logFile) << out << std::endl; + return out; + } + return false; +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBLogger::disconnect() { + if ( m_loggedReader ) { + (*m_logFile) << "DIS: " << Gaudi::Time::current().ns() << std::endl; + m_loggedReader->disconnect(); + } +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBLogger::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + if ( m_loggedReader ) { + (*m_logFile) << "TAG: " << Gaudi::Time::current().ns() << std::endl; + m_loggedReader->defaultTags(tags); + } +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLogger.h b/Det/DetCond/src/component/CondDBLogger.h new file mode 100755 index 000000000..d05fc8fd1 --- /dev/null +++ b/Det/DetCond/src/component/CondDBLogger.h @@ -0,0 +1,147 @@ +#ifndef COMPONENT_CONDDBLOGGER_H +#define COMPONENT_CONDDBLOGGER_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "DetCond/ICondDBReader.h" + +template <class TYPE> class SvcFactory; + +/** @class CondDBLogger CondDBLogger.h component/CondDBLogger.h + * + * Logger of acesses to CondDB. + * + * CondDBLogger is a simple class that allow to store in a file all the + * requests made to a ICondDBReader instance. It has to be used as a front-end + * to the instance we want to monitor. + * + * Given the following option snippet + * @code + * MyCondDBUser.Reader = "ACondDBReader"; + * @endcode + * the CondDBLogger can be enabled with + * @code + * CondDBLogger.LoggedReader = "ACondDBReader"; + * MyCondDBUser.Reader = "CondDBLogger"; + * @endcode + * or in python options + * @code + * user = MyCondDBUser() + * user.Reader = CondDBLogger(LoggedReader = user.Reader) + * @endcode + * + * The format of the log file is very simple. Each line starts with an + * operation code then the time of the operation in ns (as returned by + * Gaudi::Time::ns()). The rest of the line depend on the operation: + * - "INI:" + * - Initialization of the logger + * - "TAG:" + * - Request of the used tag + * - "GCH:" + * - Retrieve the child nodes of a folderset. + * - "GET:" + * - Request of an object from the database, the format is<br> + * <path> <channel id> <path> <evt.time> <status> + * - "GCN:" + * - Request of an object from the database using the channel name, the format is<br> + * <path> <channel name> <path> <evt.time> <status> + * - "FIN:" + * - Finalization of the logger + * - "IOV:" + * - Request list of IOVs (using numeric channel) + * - "ICN:" + * - Request list of IOVs (using channel name) + * + * @param LoggedReader + * Fully qualified name of the ICondDBReader to which the calls have to + * be forwarded. + * @param LogFile + * Path to the log file (it is overwritten if it exists). If not + * specified or set to empty, the file name is set from the name of the + * instance plus '.log'. + * + * @author Marco CLEMENCIC + * @date 2008-01-24 + */ +class CondDBLogger: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + +protected: + + /// Standard constructor + CondDBLogger( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBLogger( ); ///< Destructor + +private: + + // -------------------- Data Members + + /// Pointer to the CondDBReader whose activity has to be logged. + ICondDBReader *m_loggedReader; + + /// Name of the CondDBReader whose activity has to be logged. + std::string m_loggedReaderName; + + /// Path to the file that will contain the log. + std::unique_ptr<std::ostream> m_logFile; + + /// Path to the file that will contain the log. + std::string m_logFileName; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBLogger>; + +}; +#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBReplayAlg.cpp b/Det/DetCond/src/component/CondDBReplayAlg.cpp new file mode 100755 index 000000000..101826444 --- /dev/null +++ b/Det/DetCond/src/component/CondDBReplayAlg.cpp @@ -0,0 +1,162 @@ +// Include files + +// from Gaudi +// needed to sleep between two operations +#include "GaudiKernel/Sleep.h" + +#include "DetCond/ICondDBReader.h" +#include <fstream> + +// local +#include "CondDBReplayAlg.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBReplayAlg +// +// Jan 25, 2008 : Marco Clemencic +//----------------------------------------------------------------------------- + +// Declaration of the Algorithm Factory +DECLARE_ALGORITHM_FACTORY( CondDBReplayAlg ) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBReplayAlg::CondDBReplayAlg( const std::string& name, + ISvcLocator* pSvcLocator) + : GaudiAlgorithm ( name , pSvcLocator ) + , m_reader(NULL) +{ + declareProperty("Reader", m_readerName = "CondDBCnvSvc", + "Name of the reader to use to replay the requests."); + declareProperty("LogFile", m_logFileName = "", + "Path to the log file to re-play. " + "If not specified or set to empty, the file name is set from " + "the name of the instance plus '.log'." ); +} +//============================================================================= +// Destructor +//============================================================================= +CondDBReplayAlg::~CondDBReplayAlg() {} + +//============================================================================= +// Initialization +//============================================================================= +StatusCode CondDBReplayAlg::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Initialize" << endmsg; + + const bool create = true; + m_reader = svc<ICondDBReader>(m_readerName,create); + + // Open the input file. + std::unique_ptr<std::istream> logFile(new std::ifstream(m_logFileName.c_str())); + if ( ! logFile->good() ) { + error() << "Problems opening " << m_logFileName << endmsg; + return StatusCode::FAILURE; + } + info() << "File '" << m_logFileName << "' opened for reading." << endmsg; + + // Parse the input file + std::string opcode, tmp; + operation_t operation; + Gaudi::Time last_time; + Gaudi::Time::ValueType tmptime; + while ( ! logFile->eof() ) { + + (*logFile) >> opcode; + if ("GET:" == opcode || "GCN:" == opcode) { // we use this operation... + + operation.use_numeric_channel = ("GET:" == opcode); + + (*logFile) >> tmptime; operation.time = Gaudi::Time(tmptime); + (*logFile) >> operation.node; + (*logFile) >> tmptime; operation.evttime = Gaudi::Time(tmptime); + + if (operation.use_numeric_channel) { + (*logFile) >> operation.channel; + } + else { + (*logFile) >> operation.chn_name; + } + + if ( last_time > operation.time ) { + error() << "Error in the log file: the operation time is not strictly increasing"; + return StatusCode::FAILURE; + } + + //info() << operation.time.ns() << " " << operation.node << " " << operation.evttime.ns() << " " << operation.channel << endmsg; + last_time = operation.time; + m_operations.push_back(operation); + } + // skip the rest of the line + std::getline(*logFile,tmp); + } + info() << "Found " << m_operations.size() << " operations to replay." << endmsg; + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode CondDBReplayAlg::execute() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Execute" << endmsg; + + info() << "Replaying database operations ..." << endmsg; + ICondDBReader::DataPtr data; + std::string descr; + Gaudi::Time since, until; + // replay the operations + Gaudi::Time last_optime, last_time; + bool first = true; + for(list_t::iterator op = m_operations.begin(); op != m_operations.end(); ++op) { + + if ( first ) { + // we do not have to wait for the first operation + first = false; + } else { + // calculate how much we have to sleep + Gaudi::Time::ValueType ns_to_sleep = (op->time.ns() - last_optime.ns()) // time between operations + - (Gaudi::Time::current().ns() - last_time.ns()); // time wasted + + if ( ns_to_sleep > 0 ) Gaudi::NanoSleep(ns_to_sleep); + } + + last_optime = op->time; + + // I have to store the current time before the operation otherwise + // we to not count the time that the operation takes as already elapsed. + last_time = Gaudi::Time::current(); + + // Get the object + if (op->use_numeric_channel) { + m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->channel).ignore(); + } + else { + m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->chn_name).ignore(); + } + + } + info() << "Replay completed." << endmsg; + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode CondDBReplayAlg::finalize() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Finalize" << endmsg; + + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBReplayAlg.h b/Det/DetCond/src/component/CondDBReplayAlg.h new file mode 100755 index 000000000..9eff90934 --- /dev/null +++ b/Det/DetCond/src/component/CondDBReplayAlg.h @@ -0,0 +1,60 @@ +#ifndef CONDDBREPLAYALG_H_ +#define CONDDBREPLAYALG_H_ + +// Include files +// from Gaudi +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/Time.h" +#include <list> + +class ICondDBReader; + +/** @class CondDBReplayAlg CondDBReplayAlg.h + * + * Simple algorithm that reads a file in the format produced by CondDBLogger + * and re-play the request to the database with the same timing written in the + * log file. + * + * @author Marco Clemencic <marco.clemencic@cern.ch> + * @date 2008-01-25 + */ +class CondDBReplayAlg : public GaudiAlgorithm { +public: + /// Standard constructor + CondDBReplayAlg( const std::string& name, ISvcLocator* pSvcLocator ); + + virtual ~CondDBReplayAlg( ); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization + +protected: + +private: + + /// Path to the file containing the log. + std::string m_logFileName; + + /// Name of the reader to use to replay the requests. + std::string m_readerName; + + /// Pointer to the ICondDBReader service. + ICondDBReader *m_reader; + + struct operation_t { + Gaudi::Time time; + std::string node; + Gaudi::Time evttime; + bool use_numeric_channel; + cool::ChannelId channel; + std::string chn_name; + }; + typedef std::list<operation_t> list_t; + + /// List of operations to perform + list_t m_operations; + +}; + +#endif /*CONDDBREPLAYALG_H_*/ diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp new file mode 100755 index 000000000..f4701c43f --- /dev/null +++ b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp @@ -0,0 +1,135 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Property.h" +#include "GaudiKernel/IJobOptionsSvc.h" +#include "GaudiKernel/ThreadGaudi.h" + +#include "boost/filesystem/path.hpp" +#include "boost/filesystem/operations.hpp" +#include "boost/filesystem/exception.hpp" + +// local +#include "CondDBSQLiteCopyAccSvc.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBSQLiteCopyAccSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBSQLiteCopyAccSvc +// +// 2007-03-22 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBSQLiteCopyAccSvc::CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ): + CondDBAccessSvc(name,svcloc) +{ + declareProperty("OriginalFile", m_source_path = "" ); + declareProperty("DestinationFile", m_dest_path = "" ); + declareProperty("DBName", m_dbname = "" ); + declareProperty("ForceCopy", m_force_copy = false ); + declareProperty("IgnoreCopyError", m_ignore_copy_error = false ); +} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBSQLiteCopyAccSvc::initialize(){ + //before initializing the parent, I have to copy the file + StatusCode sc = setProperties(); + if ( ! sc.isSuccess() ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Failed to set properties" << endmsg; + return sc; + } + + // this should be done after getting the properties + MsgStream log(msgSvc(), name() ); + + // preliminary checks on the options + if ( m_source_path.empty() ) { + log << MSG::ERROR << "You must provide the source file path via the option '" + << name() << ".OriginalFile'" << endmsg; + return StatusCode::FAILURE; + } + if ( m_dest_path.empty() ) { + log << MSG::ERROR << "You must provide the destination file path via the option '" + << name() << ".DestinationFile'" << endmsg; + return StatusCode::FAILURE; + } + if ( m_dbname.empty() ) { + log << MSG::ERROR << "You must provide the database name via the option '" + << name() << ".DBName'" << endmsg; + return StatusCode::FAILURE; + } + + try { + + // if "force" mode is selected: remove the destination file if it exists + if ( m_force_copy ) { + bool file_existed = boost::filesystem::remove( m_dest_path ); + if ( file_existed ) { + log << MSG::WARNING << "Removed file '" << m_dest_path << "' to replace it" << endmsg; + } + } + + // copy the source file + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Copying " + << m_source_path << " -> " + << m_dest_path << endmsg; + boost::filesystem::copy_file(m_source_path,m_dest_path); + + } + catch (boost::filesystem::filesystem_error &e){ + + MSG::Level lvl = MSG::ERROR; + if ( m_ignore_copy_error ) lvl = MSG::WARNING; + + log << lvl << "Problems occurred copying the file" << endmsg; + log << lvl << e.what() << endmsg; + if ( ! m_ignore_copy_error ) + return StatusCode::FAILURE; + } + + /* + // I need to override the connection string property + IJobOptionsSvc* jos; + const bool CREATEIF(true); + sc = serviceLocator()->service( "JobOptionsSvc", jos, CREATEIF ); + if( sc.isFailure() ) { + log << MSG::ERROR << "Service JobOptionsSvc not found" << endmsg; + } + + sc = jos->addPropertyToCatalogue( getGaudiThreadGenericName(name()), + StringProperty( "ConnectionString", + "sqlite_file:" + m_dest_path + "/" + m_dbname) ); + jos->release(); + if ( ! sc.isSuccess() ) { + log << MSG::ERROR << "Failed to override the property '" << name() << ".ConnectionString'"<< endmsg; + return sc; + } + */ + + // Set the connection string to be used (the one from the base class will be ignored). + m_sqlite_connstring = "sqlite_file:" + m_dest_path + "/" + m_dbname; + + // Initialize the base class. + return CondDBAccessSvc::initialize(); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBSQLiteCopyAccSvc::~CondDBSQLiteCopyAccSvc() {} + +//============================================================================= +// Return the connection string used to connect to the database. +//============================================================================= +const std::string &CondDBSQLiteCopyAccSvc::connectionString() const { + return m_sqlite_connstring; +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h new file mode 100755 index 000000000..1daecf30c --- /dev/null +++ b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h @@ -0,0 +1,55 @@ +#ifndef COMPONENT_CONDDBSQLITECOPYACCSVC_H +#define COMPONENT_CONDDBSQLITECOPYACCSVC_H 1 + +// Include files +#include "CondDBAccessSvc.h" + +/** @class CondDBSQLiteCopyAccSvc CondDBSQLiteCopyAccSvc.h component/CondDBSQLiteCopyAccSvc.h + * + * Extension to CondDBAccessSvc SQLite specific. The original SQLite file is copied to + * a different direcory before being used. This is particularily helpful when the original + * file is accessible only via NFS (see http://www.sqlite.org/faq.html#q7 for details). + * + * @author Marco Clemencic + * @date 2007-03-22 + */ +class CondDBSQLiteCopyAccSvc: public CondDBAccessSvc { + +public: + + /// Initilize the service + virtual StatusCode initialize(); + + /// Return the connection string used to connect to the database. + virtual const std::string &connectionString() const; + + +protected: + /// Standard constructor + CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBSQLiteCopyAccSvc( ); ///< Destructor + +private: + + /// Path to the original file + std::string m_source_path; + /// Path to destination file + std::string m_dest_path; + /// COOL database name + std::string m_dbname; + + /// Whether to overwrite the destination file. + bool m_force_copy; + /// Whether ingore copy error (e.g. if the destination file exists, try to use it) + bool m_ignore_copy_error; + + /// Needed to avoid interference with the connection string set by CondDBAccessSvc + /// standard options (we need to overwrite it). + std::string m_sqlite_connstring; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBSQLiteCopyAccSvc>; + +}; +#endif // COMPONENT_CONDDBSQLITECOPYACCSVC_H diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp b/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp new file mode 100755 index 000000000..7df80596a --- /dev/null +++ b/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp @@ -0,0 +1,363 @@ +// Include files +#ifdef WIN32 // Hacks to compile on Windows... +#define NOMSG +#define NOGDI +#define max max +#endif + +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "GaudiKernel/IDetDataSvc.h" + +// local +#include "CondDBTimeSwitchSvc.h" +#include "CondDBCommon.h" + + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBTimeSwitchSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBTimeSwitchSvc +// +// 2006-07-10 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +// This is needed otherwise the implementation of std::map does +// not find operator<(Gaudi::Time,Gaudi::Time). +namespace Gaudi { using ::operator<; } +//============================================================================= +// Code copied from GaudiKernel Parsers, to have a parser for +// pair<long long,long long>. +// ============================================================================ +// GaudiKernel +// ============================================================================ +// 2011-08-26 : alexander.mazurov@gmail.com +#include "GaudiKernel/ParsersFactory.h" +namespace { + StatusCode parse(std::pair<long long,long long>& result, + const std::string& input){ + return Gaudi::Parsers::parse_(result, input); + } +} +//============================================================================= + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBTimeSwitchSvc::CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc), + m_readersDeclatations(), + m_readers(), + m_latestReaderRequested(0), + m_dds(0) +{ + + // "'CondDBReader':(since, until)", with since and until doubles + declareProperty("Readers", m_readersDeclatations); + + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBTimeSwitchSvc::~CondDBTimeSwitchSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBTimeSwitchSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if (m_readersDeclatations.empty()) { + log << MSG::ERROR << "No CondDBReader has been specified" + " (property 'Readers')." << endmsg; + return StatusCode::FAILURE; + } + + // decoding the property "Readers" + std::string reader_name, reader_siov; + std::pair<long long,long long> reader_iov; + for (ReadersDeclatationsType::iterator rd = m_readersDeclatations.begin(); + rd != m_readersDeclatations.end(); ++rd){ + // first step of parsing (split "'name':value" -> "name","value") + sc = Gaudi::Parsers::parse(reader_name,reader_siov,*rd); + if (sc.isSuccess()) { + // second step (only if first passed) + sc = ::parse(reader_iov,reader_siov); + } + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot decode string '" << *rd << "'" << endmsg; + return sc; + } + // Check for overlaps + const bool quiet = true; + ReaderInfo *old = readerFor(reader_iov.first,quiet); + if (!old) old = readerFor(reader_iov.second,quiet); + if (old) { + log << MSG::ERROR << "Conflicting IOVs between '" << old->name << "':(" + << old->since.ns() << "," << old->until.ns() << ") and " + << *rd << endmsg; + return StatusCode::FAILURE; + } + // use "until" as key to be able to search with "upper_bound" + ReaderInfo ri(reader_name, reader_iov.first, reader_iov.second); + m_readers.insert(std::make_pair(ri.until,ri)); + } + if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { + log << MSG::DEBUG << "Configured CondDBReaders:" << endmsg; + ReadersType::iterator r; + for (r = m_readers.begin(); r != m_readers.end(); ++r) { + log << MSG::DEBUG << " " << r->second.since << " - " << r->second.until + << ": " << r->second.name << endmsg; + } + } + // we need to reset it because it got corrupted during the + // check for overlaps + m_latestReaderRequested = 0; + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBTimeSwitchSvc::finalize(){ + if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(), name()); + log << MSG::DEBUG << "Finalize" << endmsg; + } + + // release all the loaded CondDBReader services + m_readers.clear(); + if(m_dds) { + m_dds->release(); + m_dds = 0; + } + m_readersDeclatations.clear(); + m_latestReaderRequested = 0; + + return base_class::finalize(); +} + +//========================================================================= +// find the appropriate reader +//========================================================================= +CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::readerFor(const Gaudi::Time &when, bool quiet) { + MsgStream log(msgSvc(), name()); + + if (!quiet) log << MSG::VERBOSE << "Get CondDBReader for event time " << when << endmsg; + + // TODO: (MCl) if we change service, we may clear the cache of the one + // that is not needed. + if ((!m_latestReaderRequested) || !m_latestReaderRequested->isValidAt(when)){ + // service not valid: search for the correct one + + // Find the element with key ("until") greater that the requested one + ReadersType::iterator reader = m_readers.upper_bound(when); + if (reader != m_readers.end() && reader->second.isValidAt(when)){ + m_latestReaderRequested = &(reader->second); + } else { + m_latestReaderRequested = 0; // reader not found + if (!quiet) log << MSG::WARNING << "No reader configured for requested event time" << endmsg; + } + } + + return m_latestReaderRequested; +} + +//========================================================================= +// get the current time +//========================================================================= +Gaudi::Time CondDBTimeSwitchSvc::getTime() { + if (!m_dds) { + StatusCode sc = service("DetectorDataSvc",m_dds,false); + if (sc.isFailure()) { + MsgStream log(msgSvc(), name()); + log << MSG::WARNING << "Cannot find the DetectorDataSvc," + " using a default event time (0)" << endmsg; + return Gaudi::Time(); + } + } + return m_dds->eventTime(); +} + +//========================================================================= +// get the current reader +//========================================================================= +CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::currentReader() { + if (!m_latestReaderRequested) { + // Let's stay on the safe side if we don't find a reader + if (readerFor(getTime()) == 0) { + throw GaudiException("No reader configured for current event time", + "CondDBTimeSwitchSvc::currentReader",StatusCode::FAILURE); + } + } + return m_latestReaderRequested; +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, + const Gaudi::Time &when, + DataPtr &data, + std::string &descr, + Gaudi::Time &since, + Gaudi::Time &until, + cool::ChannelId channel) { + // get the reader for the requested time + ReaderInfo *ri = readerFor(when); + if (!ri) return StatusCode::FAILURE; + + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); + if (sc.isSuccess()) ri->cutIOV(since,until); + } + return sc; +} +StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, + const Gaudi::Time &when, + DataPtr &data, + std::string &descr, + Gaudi::Time &since, + Gaudi::Time &until, + const std::string &channel) { + // get the reader for the requested time + ReaderInfo *ri = readerFor(when); + if (!ri) return StatusCode::FAILURE; + + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); + if (sc.isSuccess()) ri->cutIOV(since,until); + } + return sc; + +} + +template <typename Channel> +ICondDBReader::IOVList CondDBTimeSwitchSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) +{ + IOVList iovs; + + IOV tmp; + + // get the list of readers valid in the given time IOV + ReadersType::iterator r; + for(r = m_readers.begin(); r != m_readers.end(); ++r) { + if (r->second.until <= iov.since) continue; // ignore readers before... + if (r->second.since >= iov.until) break; // ...and after the request + + tmp.since = std::max(iov.since, r->second.since); + tmp.until = std::min(iov.until, r->second.until); + + IOVList new_iovs = r->second.reader(serviceLocator())->getIOVs(path, tmp, channel); + if (!new_iovs.empty()) { + // trim the IOVs found + new_iovs.front().since = std::max(tmp.since, new_iovs.front().since); + new_iovs.back().until = std::min(tmp.until, new_iovs.back().until); + + iovs.insert(iovs.end(), new_iovs.begin(), new_iovs.end()); + } + } + return iovs; +} + +ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return i_getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return i_getIOVs(path, iov, channel); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { + return getChildNodes(path,node_names,node_names); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) { + // clear the destination vectors + folders.clear(); + foldersets.clear(); + + // delegate to the current Reader (hoping that is good enough) + return currentReader()->reader(serviceLocator())->getChildNodes(path,folders,foldersets); +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBTimeSwitchSvc::exists(const std::string &path) { + return currentReader()->reader(serviceLocator())->exists(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBTimeSwitchSvc::isFolder(const std::string &path) { + return currentReader()->reader(serviceLocator())->isFolder(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBTimeSwitchSvc::isFolderSet(const std::string &path) { + return currentReader()->reader(serviceLocator())->isFolderSet(path); +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBTimeSwitchSvc::disconnect() { + // loop over all readers + ReadersType::const_iterator reader; + for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { + if (reader->second.loaded()) + reader->second.reader(serviceLocator())->disconnect(); + } +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBTimeSwitchSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + // loop over all readers + ReadersType::const_iterator reader; + for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { + reader->second.reader(serviceLocator())->defaultTags(tags); + } +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.h b/Det/DetCond/src/component/CondDBTimeSwitchSvc.h new file mode 100755 index 000000000..c1eecb386 --- /dev/null +++ b/Det/DetCond/src/component/CondDBTimeSwitchSvc.h @@ -0,0 +1,198 @@ +#ifndef COMPONENT_CONDDBTIMESWITCHSVC_H +#define COMPONENT_CONDDBTIMESWITCHSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "GaudiKernel/Map.h" +#include "DetCond/ICondDBReader.h" +#include <vector> +#include <map> + +template <class TYPE> class SvcFactory; +class IDetDataSvc; + +/** @class CondDBTimeSwitchSvc CondDBTimeSwitchSvc.h component/CondDBTimeSwitchSvc.h + * + * + * + * @author Marco Clemencic + * @date 2006-07-10 + */ +class CondDBTimeSwitchSvc: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + + +protected: + /// Standard constructor + CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBTimeSwitchSvc( ); ///< Destructor + + +private: + + /// Internal class to record the readers + struct ReaderInfo { + /// CondDBReader instance name ("type/name") + std::string name; + /// Boundaries of the Interval Of Validity + Gaudi::Time since, until; + /// Default Constructor + ReaderInfo(const std::string &_n, + Gaudi::Time _s = Gaudi::Time::epoch(), + Gaudi::Time _u = Gaudi::Time::max()): + name(_n), + since(_s), + until(_u), + m_reader(0) + {} + /// Default Constructor + ReaderInfo(const std::string &_n, Gaudi::Time::ValueType _s, Gaudi::Time::ValueType _u): + name(_n), + since(_s), + until(_u), + m_reader(0) + {} + /// Copy constructor (for a correct reference counting). + ReaderInfo(const ReaderInfo &_ri): + name(_ri.name), + since(_ri.since), + until(_ri.until), + m_reader(_ri.m_reader) + { + if (m_reader) m_reader->addRef(); + } + /// Destructor (releases the CondDBReader service). + ~ReaderInfo(){ + if (m_reader) m_reader->release(); + } + /// Shortcut to check the validity of the reader + bool isValidAt(const Gaudi::Time &when) const { + return since <= when && until > when; + } + /// Shortcut to retrieve the pointer to the reader service. + ICondDBReader *reader(ISvcLocator *svcloc) const { + if (!m_reader) { + if (!svcloc) + throw GaudiException("ServiceLocator pointer is NULL", + "CondDBTimeSwitchSvc::ReaderInfo::get",StatusCode::FAILURE); + StatusCode sc = svcloc->service(name,m_reader,true); + if (sc.isFailure()) + throw GaudiException("Cannot get ICondDBReader '"+name+"'", + "CondDBTimeSwitchSvc::ReaderInfo::get",sc); + } + return m_reader; + } + /// Shortcut to restrict and IOV to the boundaries defined for the reader + void cutIOV(Gaudi::Time &_since, Gaudi::Time &_until) const { + if ( since > _since ) _since = since; + if ( until < _until ) _until = until; + } + /// convert to a string + std::string toString() const; + /// tell if the reader has already been instantiated + bool loaded() const { + return m_reader; + } + private: + /// Pointer to the CondDBReader instance + mutable ICondDBReader *m_reader; + }; + + /// Get the the CondDBReader valid for a given point in time. + /// Returns 0 if no service is available. + /// The boolean flag is used to avoid messages (during initialization). + ReaderInfo *readerFor(const Gaudi::Time &when, bool quiet = false); + + /// Get the the CondDBReader valid for a given point in time. + /// Returns 0 if no service is available + ReaderInfo *currentReader(); + + /// Get current event time from the detector data svc. + Gaudi::Time getTime(); + + // -------------------- Data Members + typedef std::vector<std::string> ReadersDeclatationsType; + typedef GaudiUtils::Map<Gaudi::Time,ReaderInfo> ReadersType; + + /// Property CondDBTimeSwitchSvc.Readers: list of ICondDBReaders to be used + /// for given intervals of validity. The format is "'Reader': (since, until)", + /// where since and until are doubles defining the time in standard units. + ReadersDeclatationsType m_readersDeclatations; + + /// Container for the alternatives. The ReaderInfo objects are indexed by + /// "until" to allow efficient search with map::upper_bound. + ReadersType m_readers; + + /// Pointer used to cache the latest requested reader. + /// It allows to avoid the search. + ReaderInfo *m_latestReaderRequested; + + /// Pointer to the detector data service, used to get the event time in + /// the methods that do not require it as argument. + /// It used only if there was not a previous request with the time. + IDetDataSvc *m_dds; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBTimeSwitchSvc>; + + /// Internal implementation helper to generalize the channel type. + template <typename Channel> + IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); +}; +#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/IOVListHelpers.cpp b/Det/DetCond/src/component/IOVListHelpers.cpp new file mode 100644 index 000000000..62ede6d93 --- /dev/null +++ b/Det/DetCond/src/component/IOVListHelpers.cpp @@ -0,0 +1,23 @@ +#include "IOVListHelpers.h" + +namespace IOVListHelpers { + ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov) { + + ICondDBReader::IOVList result; + + Gaudi::Time last = iov.since; // keep track of the end of coverage + // loop over covering interval + for (const auto& covered : data ) { + if (covered.since > last) { // hole between the end of coverage and begin of next IOV + result.emplace_back(last, covered.since); + } + last = covered.until; // prepare to look for the next hole + } + if (last < iov.until) { + // we didn't get anything to cover until the end of the requested IOV + result.emplace_back(last, iov.until); + } + + return result; + } +} diff --git a/Det/DetCond/src/component/IOVListHelpers.h b/Det/DetCond/src/component/IOVListHelpers.h new file mode 100644 index 000000000..d660cf962 --- /dev/null +++ b/Det/DetCond/src/component/IOVListHelpers.h @@ -0,0 +1,10 @@ +#ifndef IOVLISTHELPERS_H +#define IOVLISTHELPERS_H +#include "DetCond/ICondDBReader.h" + +namespace IOVListHelpers { + /// Find the intervals in passed interval that are not covered by the provided. + ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov); +} + +#endif diff --git a/Det/DetCond/src/component/LoadDDDB.cpp b/Det/DetCond/src/component/LoadDDDB.cpp new file mode 100755 index 000000000..08beaac28 --- /dev/null +++ b/Det/DetCond/src/component/LoadDDDB.cpp @@ -0,0 +1,101 @@ +// Include files + +// from Gaudi +#include "GaudiKernel/DataStoreItem.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/GaudiException.h" + +// from LHCb +#include "Kernel/ICondDBInfo.h" + +// local +#include "LoadDDDB.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : LoadDDDB +// +// 2005-10-14 : Marco Clemencic +//----------------------------------------------------------------------------- + +// Declaration of the Algorithm Factory +DECLARE_ALGORITHM_FACTORY( LoadDDDB ) + + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +LoadDDDB::LoadDDDB( const std::string& name, + ISvcLocator* pSvcLocator) + : GaudiAlgorithm ( name , pSvcLocator ) +{ + declareProperty("Node", m_treeToLoad = "/dd*"); +} +//============================================================================= +// Destructor +//============================================================================= +LoadDDDB::~LoadDDDB() {} + +//============================================================================= +// Initialization +//============================================================================= +StatusCode LoadDDDB::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Initialize" << endmsg; + + std::vector<LHCb::CondDBNameTagPair> tmp; + svc<ICondDBInfo>("CondDBCnvSvc",true)->defaultTags(tmp); + + std::vector<LHCb::CondDBNameTagPair>::iterator db; + for ( db = tmp.begin(); db != tmp.end(); ++db ) { + info() << "Database " << db->first << " tag " << db->second << endmsg; + } + + updMgrSvc(); // trigger the initialization of the Condition Update sub-system + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode LoadDDDB::execute() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Execute" << endmsg; + + info() << "Loading the DDDB" << endmsg; + + try { + detSvc()->addPreLoadItem(m_treeToLoad); + detSvc()->preLoad(); + } catch (GaudiException &x) { + fatal() << "Gaught GaudiException" << endmsg; + int i = 0; + for ( GaudiException *ex = &x; 0 != ex; ex = ex->previous() ) { + fatal() << std::string(i++,' ') << " ==> " << ex->what() << endmsg; + } + return StatusCode::FAILURE; + } catch (std::exception &x) { + fatal() << "Gaught exception '" << System::typeinfoName(typeid(x)) << "'" + << endmsg; + fatal() << " ==> " << x.what() << endmsg; + return StatusCode::FAILURE; + } catch (...) { + fatal() << "Gaught unknown exception!!" << endmsg; + return StatusCode::FAILURE; + } + info() << "done." << endmsg; + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode LoadDDDB::finalize() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Finalize" << endmsg; + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +//============================================================================= diff --git a/Det/DetCond/src/component/LoadDDDB.h b/Det/DetCond/src/component/LoadDDDB.h new file mode 100755 index 000000000..584e4f0ac --- /dev/null +++ b/Det/DetCond/src/component/LoadDDDB.h @@ -0,0 +1,35 @@ +#ifndef LOADDDDB_H +#define LOADDDDB_H 1 + +// Include files +// from Gaudi +#include "GaudiAlg/GaudiAlgorithm.h" + + +/** @class LoadDDDB LoadDDDB.h + * + * Load entries in the detector transient store using IDataSvc::preLoad(). + * The node to be loaded is set with the option LoadDDDB.Node. + * + * @author Marco Clemencic + * @date 2005-10-14 + */ +class LoadDDDB : public GaudiAlgorithm { +public: + /// Standard constructor + LoadDDDB( const std::string& name, ISvcLocator* pSvcLocator ); + + virtual ~LoadDDDB( ); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization + +protected: + +private: + + std::string m_treeToLoad; + +}; +#endif // LOADDDDB_H diff --git a/Det/DetCond/src/component/RelyConverter.cpp b/Det/DetCond/src/component/RelyConverter.cpp new file mode 100755 index 000000000..f9b5b8a11 --- /dev/null +++ b/Det/DetCond/src/component/RelyConverter.cpp @@ -0,0 +1,479 @@ +// Include files +#include "RelyConverter.h" + +#include "GaudiKernel/IConversionSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/IOpaqueAddress.h" +#include "GaudiKernel/IRegistry.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/DataObject.h" +#include "GaudiKernel/Time.h" +#include "GaudiKernel/IDataManagerSvc.h" + +#include "DetDesc/ValidDataObject.h" + +#include "CoolKernel/IObject.h" +#include "CoolKernel/IRecord.h" +#include "CoolKernel/RecordException.h" + +#include <string> +#include <sstream> + +// local + +//----------------------------------------------------------------------------- +// Implementation file for class : RelyConverter +// +// 2004-12-03 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------- +// Instantiation of a static factory class used by clients to create +// instances of this service +// ----------------------------------------------------------------------- +DECLARE_CONVERTER_FACTORY(RelyConverter) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +RelyConverter::RelyConverter(ISvcLocator* svc): + CondDBGenericCnv(svc,RelyConverter::classID()), + m_detPersSvc(NULL) +{} +//============================================================================= +// Destructor +//============================================================================= +RelyConverter::~RelyConverter() {} + +//========================================================================= +// Initialization +//========================================================================= +StatusCode RelyConverter::initialize() { + // Initializes the grand father + StatusCode sc = CondDBGenericCnv::initialize(); + + sc = serviceLocator()->service("DetectorPersistencySvc", m_detPersSvc, true); + if ( !sc.isSuccess() ) { + MsgStream log(msgSvc(),"RelyConverter"); + log << MSG::ERROR << "Cannot locate IConversionSvc interface of DetectorPersistencySvc" << endmsg; + return sc; + } else { + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved IConversionSvc interface of DetectorPersistencySvc" << endmsg; + } + return sc; +} + +//========================================================================= +// Finalization +//========================================================================= +StatusCode RelyConverter::finalize() { + m_detPersSvc->release(); + return CondDBGenericCnv::finalize(); +} + +//========================================================================= +// Create the transient representation +//========================================================================= +StatusCode RelyConverter::createObj (IOpaqueAddress* pAddress, DataObject *&pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering createObj" << endmsg; + + StatusCode sc = i_delegatedCreation(pAddress,pObject,CreateObject); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot create the object " << pAddress->registry()->identifier() << endmsg; + return sc; + } + + return StatusCode::SUCCESS; +} + +//========================================================================= +// Fill references of the transient representation +//========================================================================= +StatusCode RelyConverter::fillObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering fillObjRefs" << endmsg; + + StatusCode sc = i_delegatedCreation(pAddress,pObject,FillObjectRefs); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot fill object's refs" << endmsg; + return sc; + } + + return StatusCode::SUCCESS; +} + +//========================================================================= +// Update transient representation from persistent one +//========================================================================= +StatusCode RelyConverter::updateObj (IOpaqueAddress* pAddress, DataObject* pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Method updateObj starting" << endmsg; + + DataObject* pNewObject; // create a new object and copy it to the old version + StatusCode sc = i_delegatedCreation(pAddress,pNewObject,CreateObject); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot create the new object" << endmsg; + return sc; + } + + // do the real update + // + // Since DataObject::operator= operator is not virtual, dynamic cast first! + // Overloaded virtual method Condition::update() must be properly defined! + // The memory pointed to by the old pointer must contain the new object + // Andrea Valassi + + ValidDataObject* pVDO = dynamic_cast<ValidDataObject*>(pObject); + ValidDataObject* pNewVDO = dynamic_cast<ValidDataObject*>(pNewObject); + if ( 0 == pVDO || 0 == pNewVDO ) { + log << MSG::ERROR + << "Cannot update objects other than ValidDataObject: " + << "update() must be defined!" + << endmsg; + return StatusCode::FAILURE; + } + // Deep copy the new Condition into the old DataObject + pVDO->update( *pNewVDO ); + + // Delete the useless Condition + delete pNewVDO; + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Object successfully updated" << endmsg; + return StatusCode::SUCCESS; +} + +//========================================================================= +// Update references of the transient representation +//========================================================================= +StatusCode RelyConverter::updateObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering updateObjRefs" << endmsg; + + StatusCode sc = i_delegatedCreation(pAddress,pObject,UpdateObjectRefs); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot update object's refs" << endmsg; + return sc; + } + + return StatusCode::SUCCESS; +} + +//========================================================================= +// Create the persistent representation +//========================================================================= +StatusCode RelyConverter::createRep (DataObject* /*pObject*/, IOpaqueAddress*& /*pAddress*/) +{ + MsgStream log(msgSvc(),"RelyConverter"); + log << MSG::WARNING << "createRep() not implemented" << endmsg; + return StatusCode::SUCCESS; +} + +//========================================================================= +// Update the persistent representation +//========================================================================= +StatusCode RelyConverter::updateRep (IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) +{ + MsgStream log(msgSvc(),"RelyConverter"); + log << MSG::WARNING << "updateRep() not implemented" << endmsg; + return StatusCode::SUCCESS; +} + +//========================================================================= +// Create an object by delegation +//========================================================================= +StatusCode RelyConverter::i_delegatedCreation(IOpaqueAddress* pAddress, DataObject *&pObject, Operation op){ + StatusCode sc; + + MsgStream log(msgSvc(),"RelyConverter"); + + ICondDBReader::DataPtr data; + std::string description; + Gaudi::Time since,until; + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Entering \"i_delegatedCreation\"" << endmsg; + + std::string path = pAddress->par()[0]; + std::string data_field_name = "data"; + + // Extract the COOL field name from the condition path + std::string::size_type at_pos = path.find('@'); + if ( at_pos != path.npos ) { + std::string::size_type slash_pos = path.rfind('/',at_pos); + if ( slash_pos+1 < at_pos ) { // item name is not null + data_field_name = path.substr(slash_pos+1,at_pos - (slash_pos +1)); + } // if I have "/@", I should use the default ("data") + // always remove '@' from the path + path = path.substr(0,slash_pos+1) + path.substr(at_pos+1); + } + + sc = getObject(path, pAddress->ipar()[0], data, description, since, until); + if ( !sc.isSuccess() ) return sc; + + if ( !data ) { + switch (op) { + case CreateObject: + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Path points to a FolderSet: create a directory" << endmsg; + + // I hit a FolderSet!!! I handle it here (at least for the moment, since it's the only CondDB real converter) + pObject = new DataObject(); + + break; + + case FillObjectRefs: + { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Create addresses for sub-folders" << endmsg; + + // find subnodes + std::vector<std::string> children; + + sc = getChildNodes(path,children); + if ( !sc.isSuccess() ) return sc; + + // add registries for the sub folders + for ( std::vector<std::string>::iterator c = children.begin(); c != children.end(); ++c ) { + + IOpaqueAddress *childAddress; + std::string par[2]; + // in current implementation, the child folders have a '/' in front. + // So I need to treat in a different way the case of a parent COOL root folderset + // to avoid thing like "//folder" + if ( path == "/" ) { + par[0] = *c; + } else { + par[0] = path + *c; + } + par[1] = *c; + unsigned long ipar[2] = { 0,0 }; + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Create address for " << par[0] << endmsg; + sc = conversionSvc()->addressCreator()->createAddress(CONDDB_StorageType, + CLID_Catalog, + par, + ipar, + childAddress); + if ( !sc.isSuccess() ) return sc; + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Address created" << endmsg; + + sc = dataManager()->registerAddress(pAddress->registry(), *c, childAddress); + if ( !sc.isSuccess() ) return sc; + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Address registered" << endmsg; + } + } + break; + + case UpdateObjectRefs: + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Update references not supported for FolderSet" << endmsg; + break; + } + + return StatusCode::SUCCESS; + } + + long storage_type = getStorageType(path,description); + if (storage_type <= 0) { + log << MSG::ERROR << + "Folder description does not contain a valid storage type: " << endmsg; + log << MSG::ERROR << "desc = \"" << description << "\"" << endmsg; + return StatusCode::FAILURE; + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "delegate to DetectorPersistencySvc" << endmsg; + + std::string xml_data; + try { + xml_data = (*data.get())[data_field_name].data<std::string>(); + } catch (cool::RecordSpecificationUnknownField &e) { + log << MSG::ERROR << "I cannot find the data inside COOL object: " << e.what() << endmsg; + return StatusCode::FAILURE; + } + + // for XML string temporary address, I need a way to know which is the originating href + std::ostringstream src_href; + src_href << "conddb:" << pAddress->par()[0] << ":" << pAddress->ipar()[0]; + + // Create temporary address for the relevant type and classID + IOpaqueAddress *tmpAddress = createTmpAddress(src_href.str(), + storage_type, + pAddress->par()[1], + pAddress->clID(), + xml_data, + log, + conversionSvc()->addressCreator()); + if (!tmpAddress) return StatusCode::FAILURE; + + tmpAddress->addRef(); + if ( pAddress->registry() ){ + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "register tmpAddress to registry " << pAddress->registry()->identifier() + << endmsg; + } else { + log << MSG::WARNING << "the address does not have a registry" << endmsg; + } + tmpAddress->setRegistry(pAddress->registry()); + if (tmpAddress->registry()) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "tmpAddress registered to registry " << tmpAddress->registry()->identifier() + << endmsg; + } else { + log << MSG::WARNING << "tmpAddress not registered!" << endmsg; + } + + switch (op) { + case CreateObject: + sc = m_detPersSvc->createObj ( tmpAddress, pObject ); + break; + case FillObjectRefs: + sc = m_detPersSvc->fillObjRefs ( tmpAddress, pObject ); + break; + case UpdateObjectRefs: + sc = m_detPersSvc->updateObjRefs ( tmpAddress, pObject ); + break; + } + + tmpAddress->release(); + if ( sc.isFailure() ) { + log << MSG::ERROR + << "Persistency service could not create a new object" << endmsg; + return sc; + } + + if (op == CreateObject){ + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Setting object validity" << endmsg; + setObjValidity(since,until,pObject); + + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "New object successfully created" << endmsg; + + return StatusCode::SUCCESS; +} + +//============================================================================= + +long RelyConverter::getStorageType(const std::string &path, const std::string &desc){ + // the description string should contain a substring of the form (regexp) + // "< *storage_type *= *[0-9]+ *>" + + if ( path.rfind(".xml") != path.npos ) return XML_StorageType; + + const char delimiter_begin = '<'; + const char delimiter_end = '>'; + const char delimiter_sep = '='; + const std::string delimiter_keyword = "storage_type"; + + std::string::size_type pos_start; + std::string::size_type pos_end; + std::string::size_type pos_max; + + pos_start = pos_end = pos_max = desc.size(); + + std::string::size_type tmp_pos = 0; + + while ( pos_start == pos_max || pos_end <= pos_start ){ + // find the next occurrence of '<' + tmp_pos = desc.find(delimiter_begin,tmp_pos); + if (tmp_pos >= pos_max) break; // not found + + // skip spaces + ++tmp_pos; + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // check for the keyword + if (desc.compare(tmp_pos, delimiter_keyword.size(), delimiter_keyword) != 0) continue; + + // skip spaces + tmp_pos += delimiter_keyword.size(); + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // check for the separator + if ( desc[tmp_pos] != delimiter_sep ) continue; + + // skip spaces + ++tmp_pos; + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // here should start the "int" + pos_start = tmp_pos; + + // "count" the digits + while ( desc[tmp_pos] >= '0' && desc[tmp_pos] <= '9' ) ++tmp_pos; + + // here should be just after the "int" + pos_end = tmp_pos; + + if ( pos_start == pos_end ) continue; // no number found + + // skip spaces + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // check for the delimiter_end + if ( desc[tmp_pos] != delimiter_end ) { + // force another loop even if the number was found; + pos_start = pos_end = pos_max; + continue; + } + } + + if ( pos_start == pos_max || pos_end <= pos_start ) { // not found + return -1; + } + + std::istringstream i(desc.substr(pos_start, pos_end-pos_start)); + + long st; + i >> st; + + return st; +} + +IOpaqueAddress *RelyConverter::createTmpAddress(const std::string &src, + long storageType, + const std::string &name, + const CLID &clId, + const std::string &data, + MsgStream &log, + SmartIF<IAddressCreator>& creator) { + + if (storageType <= 0) { + log << MSG::ERROR << "invalid storage type " << storageType << endmsg; + return 0; + } + + // Create temporary address for the relevant type and classID + IOpaqueAddress *tmpAddress; + + // for XML string temporary address, I need a way to know which is the originating href + const std::string par[3] = { data, + name, + src }; + unsigned long ipar[2] = { 1,0 }; + StatusCode sc = creator->createAddress(storageType, clId , par, ipar, tmpAddress); + if (sc.isFailure()){ + log << MSG::ERROR + << "Persistency service could not create a new address" << endmsg; + return 0; + } + + return tmpAddress; +} diff --git a/Det/DetCond/src/component/RelyConverter.h b/Det/DetCond/src/component/RelyConverter.h new file mode 100755 index 000000000..0af71524c --- /dev/null +++ b/Det/DetCond/src/component/RelyConverter.h @@ -0,0 +1,148 @@ +#ifndef COMPONENT_RELYCONVERTER_H +#define COMPONENT_RELYCONVERTER_H 1 + +// Include files +#include "DetCond/CondDBGenericCnv.h" + +// Forward and external declarations +class ISvcLocator; +template <class TYPE> class CnvFactory; + +/** @class RelyConverter RelyConverter.h component/RelyConverter.cpp + * + * ConditionsDBCnvSvc rely on the functionalities provided by the XmlCnvSvc. + * RelyConverter delegate the creation of the object to the XmlCnvSvc + * (via DetectorPersistencySvc). + * + * @author Marco CLEMENCIC + * @date 2004-12-03 + */ +class RelyConverter: public CondDBGenericCnv { + + /// Friend needed for instantiation + friend class CnvFactory<RelyConverter>; + +public: + + /// Operations that can be performed by delegation + enum Operation { + CreateObject, + FillObjectRefs, + UpdateObjectRefs + }; + + /** + * Initializes the converter + * @return status depending on the completion of the call + */ + virtual StatusCode initialize(); + + /** + * Finalizes the converter + * @return status depending on the completion of the call + */ + virtual StatusCode finalize(); + + /** + * Creates the transient representation of an object. + * @param pAddress the address of the object representation + * @param pObject the object created + * @return status depending on the completion of the call + */ + virtual StatusCode createObj (IOpaqueAddress *pAddress, + DataObject *&pObject); + /** + * Resolve the references of the created transient object. + * @param pAddress the address of the object representation + * @param pObject the object created + * @return status depending on the completion of the call + */ + virtual StatusCode fillObjRefs (IOpaqueAddress *pAddress, + DataObject *pObject); + /** + * Resolve the references of the just updated transient object. + * @param pAddress the address of the object representation + * @param pObject the object created + * @return status depending on the completion of the call + */ + virtual StatusCode updateObjRefs (IOpaqueAddress *pAddress, + DataObject *pObject); + /** + * Updates the transient object from the other representation (not implemented). + * @param pAddress the address of the object representation + * @param pObject the object updated + * @return status depending on the completion of the call + */ + virtual StatusCode updateObj (IOpaqueAddress *pAddress, + DataObject *pObject); + + /** + * Converts the transient object to the requested representation (not implemented). + * @param refpAddress the address of the object representation + * @param pObject the object to convert + * @return status depending on the completion of the call + */ + virtual StatusCode createRep (DataObject* pObject, + IOpaqueAddress*& refpAddress); + + /** + * Updates the converted representation of a transient object. + * @param pAddress the address of the object representation + * @param pObject the object whose representation has to be updated + * @return status depending on the completion of the call + */ + virtual StatusCode updateRep (IOpaqueAddress* pAddress, + DataObject* pObject); + + /** + * Accessor to the type of elements that this converter converts. + * @return the classID for this type + */ + static const CLID& classID () { return CLID_Any; } + +protected: + /// Standard constructor + RelyConverter(ISvcLocator* svc); + virtual ~RelyConverter( ); ///< Destructor + +private: + + /** + * Do the needed steps to perform a creation by delegation. + */ + StatusCode i_delegatedCreation(IOpaqueAddress* pAddress, + DataObject *&pObject, + Operation op = CreateObject); + +public: + /** + * Extract the storage_type from the folder or description. + */ + static long getStorageType(const std::string &path, const std::string &desc); + + /** Generate a temporary IOpaqueAddress to be passed to a PersistencySvc for + * the actual conversion. + * + * @param src originating URL (required by the XML format) + * @param storageType storage type ID (@see getStorageType) + * @param name name of the object inside the storage container + * @param data data to embed in the address + * @param log MsgStream instance to report errors + * @param creator IAdressCreator to use + * + * @return an IOpaqueAddress pointer in case of success, 0 in case of failure. + */ + static IOpaqueAddress *createTmpAddress(const std::string &src, + long storageType, + const std::string &name, + const CLID &clId, + const std::string &data, + MsgStream &log, + SmartIF<IAddressCreator>& creator); + +private: + /// Handle to the IConversionSvc interface of the DetectorPersistencySvc + IConversionSvc* m_detPersSvc; + +}; +#endif // COMPONENT_XMLRELYCNV_H diff --git a/Det/DetCond/src/component/RunStampCheck.cpp b/Det/DetCond/src/component/RunStampCheck.cpp new file mode 100644 index 000000000..ee7d310d0 --- /dev/null +++ b/Det/DetCond/src/component/RunStampCheck.cpp @@ -0,0 +1,140 @@ +#include "GaudiKernel/Service.h" +#include "GaudiKernel/IIncidentListener.h" +#include "GaudiKernel/IIncidentSvc.h" +#include "GaudiKernel/Kernel.h" +#include "GaudiKernel/IDetDataSvc.h" +#include "GaudiKernel/IEventProcessor.h" +#include "DetCond/ICondDBReader.h" + +/** Simple service to check if the run stamp condition exists for the current + * event. + * + * To ensure that the content of the conditions database includes alignments + * and calibrations for the event being processed, when these conditions are + * stored we also store a special condition with closed Interval Of Validity + * (IOV) covering only the run for which they are valid (RunStamp condition). + * + * The time line of the RunStamp conditions is not completely covered, and the + * holes in the time line implicitly flag the events for which the alignments + * are not available. + * + * When RunStampCheck is instantiated in a Gaudi application, it checks for + * each event time if the RunStamp condition exists or not, in which case the + * application is terminated with an error code. + * + * So, to enable the check, it is enough to add to the options: + * \code{.py} + * from Configurables import ApplicationMgr, RunStampCheck + * ApplicationMgr().ExtSvc.append(RunStampCheck()) + * \endcode + * + * \see https://its.cern.ch/jira/browse/LBCORE-831 + * \see https://its.cern.ch/jira/browse/LHCBPS-1421 + */ +class RunStampCheck: public extends1<Service, IIncidentListener> { +public: + /// Constructor. Declares properties. + RunStampCheck(const std::string& name, ISvcLocator* svcloc): + base_class(name, svcloc) { + declareProperty("RunStamp", m_runStampCondition, + "Path in the conditions database of the RunStamp condition."); + declareProperty("CondDBReader", m_condDBReaderName, + "Name of the ICondDBReader instance to query for the RunStamp."); + } + /// Connect to the required services and register as BeginEvent listener. + StatusCode start() override { + StatusCode sc = Service::start(); + if (UNLIKELY(!sc)) return sc; + + // ensure that we have the EventClocksvc (to get the current event time in + // the DetectorDataSvc). + if (UNLIKELY(!serviceLocator()->service("EventClockSvc"))) { + error() << "Cannot get EventClockSvc" << endmsg; + return StatusCode::FAILURE; + } + + m_incSvc = serviceLocator()->service("IncidentSvc"); + if (UNLIKELY(!m_incSvc)) { + error() << "Cannot get IncidentSvc" << endmsg; + return StatusCode::FAILURE; + } + m_incSvc->addListener(this, IncidentType::BeginEvent); + + m_condDBReader = serviceLocator()->service(m_condDBReaderName); + if (UNLIKELY(!m_condDBReader)) { + error() << "Cannot get " << m_condDBReaderName << endmsg; + return StatusCode::FAILURE; + } + + m_detSvc = serviceLocator()->service("DetectorDataSvc"); + if (UNLIKELY(!m_detSvc)) { + error() << "Cannot get DetectorDataSvc" << endmsg; + return StatusCode::FAILURE; + } + + m_evtProc = serviceLocator(); + if (UNLIKELY(!m_detSvc)) { + error() << "Cannot get IEventProcessor" << endmsg; + return StatusCode::FAILURE; + } + + // reset the IOV for the current run (to something not valid) + m_currentRunIOV = {Gaudi::Time::epoch(), Gaudi::Time::epoch()}; + return sc; + } + /// Deregister as BeginEvent listener and release reference to services. + StatusCode stop() override { + m_incSvc->removeListener(this, IncidentType::BeginEvent); + m_incSvc.reset(); + m_condDBReader.reset(); + m_detSvc.reset(); + m_evtProc.reset(); + return Service::stop(); + } + /// Handle the BeginEvent incident to check if the RunStamp condition exists. + void handle(const Incident&) override { + auto when = m_detSvc->eventTime(); + // run the check only if the current event time falls outside the boundaries + // of the current run + if (when < m_currentRunIOV.since || when >= m_currentRunIOV.until) { + if (UNLIKELY(msgLevel(MSG::DEBUG))) + debug() << "Checking '" << m_runStampCondition + << "' for event time " << when << endmsg; + ICondDBReader::DataPtr p; + std::string desc; + StatusCode sc = m_condDBReader->getObject(m_runStampCondition, when, + p, desc, + m_currentRunIOV.since, m_currentRunIOV.until); + if (!sc) { + // we didn't manage to get the entry from the DB: we do not have data + // for this run + error() << "Database not up-to-date. No valid data for run at " + << when.format(false, "%Y-%m-%d %H:%M:%S") + << "." << when.nanoformat() << " UTC" << endmsg; + m_evtProc->stopRun(); + } else if (UNLIKELY(msgLevel(MSG::DEBUG))) { + debug() << "Found '" << m_runStampCondition + << "' valid in [" << m_currentRunIOV.since + << ", " << m_currentRunIOV.until << ")" << endmsg; + } + } + } +private: + /// Path in the conditions database of the RunStamp condition. + std::string m_runStampCondition = "/Conditions/Online/LHCb/RunStamp.xml"; + /// Path in the conditions database of the RunStamp condition. + std::string m_condDBReaderName = "CondDBCnvSvc"; + /// reference to the incident service. + SmartIF<IIncidentSvc> m_incSvc; + /// reference to the CondDB reader. + SmartIF<ICondDBReader> m_condDBReader; + /// reference to the detector transient store. + SmartIF<IDetDataSvc> m_detSvc; + /// reference to the event processor. + SmartIF<IEventProcessor> m_evtProc; + + /// IOV of the current RunStamp. + ICondDBReader::IOV m_currentRunIOV; +}; + +DECLARE_COMPONENT(RunStampCheck) diff --git a/Det/DetCond/src/dict/DetCondDict.h b/Det/DetCond/src/dict/DetCondDict.h new file mode 100755 index 000000000..48ebf7619 --- /dev/null +++ b/Det/DetCond/src/dict/DetCondDict.h @@ -0,0 +1,38 @@ +// ============================================================================ +#ifndef DETCOND_DETCONDDICT_H +#define DETCOND_DETCONDDICT_H 1 +// ============================================================================ +// Hack to get round gccxml parsing problem (SEAL bug 9704) +// ============================================================================ +#ifdef _WIN32 +#define LONG_LONG_MAX 0x7fffffffffffffffLL /*maximum signed __int64 value */ +#define LONG_LONG_MIN 0x8000000000000000LL /*minimum signed __int64 value */ +#define ULONG_LONG_MAX 0xffffffffffffffffLL /*maximum unsigned __int64 value */ +#endif +// ============================================================================ +// GaudiKernel +// ============================================================================ +#include "GaudiKernel/Time.h" +// ============================================================================ +// DetCond +// ============================================================================ +#include "DetCond/ICondDBAccessSvc.h" +#include "DetCond/ICondDBEditor.h" +#include "DetCond/ICondDBReader.h" +#include "DetCond/ICOOLConfSvc.h" +// ============================================================================ +// CORAL (not available through PyCool) +// ============================================================================ +#include "RelationalAccess/ConnectionService.h" +#include "RelationalAccess/IConnectionServiceConfiguration.h" +#include "RelationalAccess/IReplicaSortingAlgorithm.h" +// ============================================================================ +namespace _instantiations { + struct Instantiations { + ICondDBReader::IOVList _i1; + }; +} +// ============================================================================ +#endif // DETCOND_DETCONDDICT_H +// ============================================================================ + diff --git a/Det/DetCond/src/dict/DetCondDict.xml b/Det/DetCond/src/dict/DetCondDict.xml new file mode 100755 index 000000000..f77b7e2a3 --- /dev/null +++ b/Det/DetCond/src/dict/DetCondDict.xml @@ -0,0 +1,14 @@ +<lcgdict> + + <class name="ICondDBReader" /> + <class name="ICondDBReader::IOV" /> + <class name="ICondDBReader::IOVList" /> + <class name="ICondDBEditor" /> + <class name="ICondDBAccessSvc" /> + <class name="ICOOLConfSvc" /> + + <class name="coral::IReplicaSortingAlgorithm" /> + <class name="coral::IConnectionService" /> + <class name="coral::IConnectionServiceConfiguration" /> + +</lcgdict> diff --git a/Det/DetCond/tests/data/DQFLAGS.db b/Det/DetCond/tests/data/DQFLAGS.db new file mode 100644 index 0000000000000000000000000000000000000000..3d22d8afaf1d4504118821a0ce9ea7e18272305a GIT binary patch literal 48128 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/HBTEST.db b/Det/DetCond/tests/data/HBTEST.db new file mode 100644 index 0000000000000000000000000000000000000000..9f920f0ad02fe5b7fa8eb3bd9665321079dd0863 GIT binary patch literal 76800 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/RSTEST.db b/Det/DetCond/tests/data/RSTEST.db new file mode 100644 index 0000000000000000000000000000000000000000..3515b986f69afa926d429fed453e8b8ec2bccefd GIT binary patch literal 48128 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 RI0E+s0c!at2=p7{{{!*sn#TYD literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB0.db b/Det/DetCond/tests/data/TESTDB0.db new file mode 100755 index 0000000000000000000000000000000000000000..8b4accc2b6482e618dd4f1a4f2889ca964a149c4 GIT binary patch literal 183296 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 OmqP}+Lj*P-f&UM@pb-H8 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB1.db b/Det/DetCond/tests/data/TESTDB1.db new file mode 100755 index 0000000000000000000000000000000000000000..58d9abbd4b60ffef0f56a298db91069aaf558389 GIT binary patch literal 79872 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB2.db b/Det/DetCond/tests/data/TESTDB2.db new file mode 100755 index 0000000000000000000000000000000000000000..85025de79ca3b6799d245910308c24dd3edbe17d GIT binary patch literal 79872 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 baEUHTlnyT0JlQ$E|DD4fpAmumgTVg->-`Q9 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB3.db b/Det/DetCond/tests/data/TESTDB3.db new file mode 100755 index 0000000000000000000000000000000000000000..2c58dab3ef0a1e0c3e6e9e95300a73ab98c08d0d GIT binary patch literal 183296 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/genDQFLAGS.py b/Det/DetCond/tests/data/genDQFLAGS.py new file mode 100644 index 000000000..3d343c185 --- /dev/null +++ b/Det/DetCond/tests/data/genDQFLAGS.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +""" +Small script to generate the test database for the heart beat test. +(kept for reference) +""" + +from CondDBUI import CondDB +from PyCool import cool +from datetime import datetime, timedelta + +def toTimeStamp(dt): + t = dt - datetime(1970, 1, 1, 0) + return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 + +db = CondDB("sqlite_file:DQFLAGS.db/DQFLAGS", readOnly = False, create_new_db = True) + +db.createNode("/Conditions", storageType = "NODE") +db.createNode("/Conditions/DQ", storageType = "NODE") +db.createNode("/Conditions/DQ/Flags", versionMode = "SINGLE") + +def cond(d): + data = ['<item key="%s" value="%d"/>' % i for i in d.items()] + return """<?xml version='1.0' encoding='ISO-8859-1'?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> + <condition name="Flags"> + <map keytype="string" name="map" valuetype="int"> + %s + </map> + </condition> +</DDDB> +""" % ("\n ".join(data)) + +for since, until, d in [(datetime(2012, 1, 1, 0), datetime(2012, 1, 2, 0), {"DET1": 1}), + (datetime(2012, 1, 2, 0), datetime(2012, 1, 3, 0), {"DET2": 1}), + (datetime(2012, 1, 3, 0), datetime(2012, 1, 4, 0), {}), + (datetime(2012, 1, 5, 0), datetime(2012, 1, 6, 0), {"DET3": 1})]: + since, until = map(toTimeStamp, (since, until)) + db.storeXMLString("/Conditions/DQ/Flags", cond(d), since, until) diff --git a/Det/DetCond/tests/data/genHBTEST.py b/Det/DetCond/tests/data/genHBTEST.py new file mode 100644 index 000000000..9544d8d17 --- /dev/null +++ b/Det/DetCond/tests/data/genHBTEST.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +""" +Small script to generate the test database for the heart beat test. +(kept for reference) +""" + +from CondDBUI import CondDB +from PyCool import cool + +base_time = 1262304000 # (2010, 1, 1, 0, 0, 0, 4, 1, 0) GMT +unit = 60 + +db = CondDB("sqlite_file:HBTEST.db/HBTEST", readOnly = False, create_new_db = True) + +db.createNode("/Conditions", storageType = "NODE") +db.createNode("/Conditions/Online", storageType = "NODE") +db.createNode("/Conditions/Online/HeartBeatTest", storageType = "NODE") +db.createNode("/Conditions/Online/HeartBeatTest/Condition1", versionMode = "SINGLE") +db.createNode("/Conditions/Online/HeartBeatTest/Condition2", versionMode = "SINGLE") +db.createNode("/Conditions/Online/HeartBeatTest/Tick", versionMode = "SINGLE") + +cond = """<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> + <condition name = "Condition%d"> + <param name = "Data" type = "int"> %d </param> + </condition> +</DDDB> +""" + +db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, 0), 0, cool.ValidityKeyMax) +for t in [20, 40]: + db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) + +db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, 0), 0, cool.ValidityKeyMax) +for t in [20, 40, 80]: + db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) + +hb = """<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> +<condition name="Tick"> +<param name="Alive" type="int">1</param> +</condition> +</DDDB> +""" +db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, 0, cool.ValidityKeyMax) +db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, (base_time + 60 * unit) * 1000000000, cool.ValidityKeyMax) diff --git a/Det/DetCond/tests/data/genRSTEST.py b/Det/DetCond/tests/data/genRSTEST.py new file mode 100755 index 000000000..b20f67c00 --- /dev/null +++ b/Det/DetCond/tests/data/genRSTEST.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +""" +Small script to generate the test database for the run stamp test. +(kept for reference) +""" + +from CondDBUI import CondDB +from PyCool import cool + +def ts(*args): + from datetime import datetime + epoch = datetime(1970, 1, 1) + return int((datetime(*args) - epoch).total_seconds() * 1000000000) + +db = CondDB("sqlite_file:RSTEST.db/RSTEST", readOnly = False, create_new_db = True) + +db.createNode("/Conditions", storageType = "NODE") +db.createNode("/Conditions/Online", storageType = "NODE") +db.createNode("/Conditions/Online/LHCb", storageType = "NODE") +db.createNode("/Conditions/Online/LHCB/RunInfo", versionMode = "SINGLE") +db.createNode("/Conditions/Online/LHCb/RunStamp.xml", versionMode = "SINGLE") + +rs = """<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> +<condition name="RunStamp"> +<param name="RunNumber" type="int">1</param> +</condition> +</DDDB> +""" +db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 9), ts(2015, 6, 10)) +db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 11), ts(2015, 6, 12)) diff --git a/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt b/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt new file mode 100755 index 000000000..3d63ec802 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt @@ -0,0 +1,60 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") + +from Configurables import DetCondTest__bug_80076 +alg = DetCondTest__bug_80076("Bug80076") +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1"] +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 3) +#MessageSvc(OutputLevel = 1) + +#from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +</text></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check that we find the expected lines in the right order +expected = [ + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 0.0 -> 1262305200.0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262305200.0 -> 1262306400.0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + ] + +regexp = r"^---|^Validity" + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt b/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt new file mode 100755 index 000000000..3ccd88fd5 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt @@ -0,0 +1,4 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/check_db_reading.py</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt b/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt new file mode 100755 index 000000000..75e6f9405 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt @@ -0,0 +1,4 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/configuration_module_test.py</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt b/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt new file mode 100644 index 000000000..1a70fb044 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt @@ -0,0 +1,11 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/connection_timeout.py</text></argument> +<argument name="validator"><text> +findReferenceBlock(""" +TEST ===> start +DDDB.TimeOutChe... INFO Disconnect from database after being idle for 5s (will reconnect if needed) +TEST ===> end +""") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt new file mode 100755 index 000000000..94bc9a6d0 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt @@ -0,0 +1,22 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>1</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/ObjectA +/dd/AutoMap/FolderSet2/ObjectB +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt new file mode 100755 index 000000000..fe3b24ca6 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt @@ -0,0 +1,25 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>2</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +/dd/AutoMap/FolderSet3 +/dd/AutoMap/FolderSet3/Object1 +/dd/AutoMap/FolderSet3/Object2 +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt new file mode 100755 index 000000000..e7c6714a0 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt @@ -0,0 +1,23 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>3</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +/dd/AutoMap/FolderSet2/ObjectA +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt new file mode 100755 index 000000000..965dce340 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt @@ -0,0 +1,19 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>0</text></set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt new file mode 100755 index 000000000..ea4f3ebcf --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt @@ -0,0 +1,27 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>4</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +/dd/AutoMap/FolderSet2/ObjectA +/dd/AutoMap/FolderSet2/ObjectB +/dd/AutoMap/FolderSet3 +/dd/AutoMap/FolderSet3/Object1 +/dd/AutoMap/FolderSet3/Object2 +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt new file mode 100755 index 000000000..90cc2a5a8 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt @@ -0,0 +1,63 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import DetCondTest__DQScanTest as DQScanTest +from Configurables import CondDBDQScanner, DDDBConf, CondDB, EventClockSvc, FakeEventTime + +from datetime import datetime, timedelta +def toTimeStamp(dt): + if isinstance(dt, timedelta): + t = dt + else: + t = dt - datetime(1970, 1, 1, 0) + return (t.days * 60 * 60 * 24 + t.seconds) + +def toTimeStampNS(dt): + return toTimeStamp(dt) * 1000000000 + +dddbConf = DDDBConf() + +cdb = CondDB() +cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" +cdb.Tags["DQFLAGS"] = "" + +ecs = EventClockSvc(InitialTime=toTimeStampNS(datetime(2012,1,1,12))) +ecs.addTool(FakeEventTime, "EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = ecs.InitialTime +ecs.EventTimeDecoder.TimeStep = toTimeStampNS(timedelta(days=1)) + +alg = DQScanTest() +alg.DQScanner = CondDBDQScanner() + +tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0)), + (datetime(2012,1,1,12), datetime(2012,1,3,12)), + (datetime(2012,1,2,12), datetime(2012,1,5,12)), + (datetime(2012,1,4,12), datetime(2012,1,6,12)), + (datetime(2012,1,3,12), datetime(2012,1,4,12)), + ] + +alg.IOVs = [(toTimeStamp(a), toTimeStamp(b)) for a, b in tests] + +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) +MessageSvc(OutputLevel = WARNING) + +</text></argument> +<argument name="validator"><text> +findReferenceBlock(""" +ApplicationMgr INFO Application Manager Started successfully +DetCondTest::DQ...SUCCESS Process IOV 1325376000.0 -> 1325635200.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325419200.0 -> 1325592000.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325505600.0 -> 1325764800.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET2: 1, DET3: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325678400.0 -> 1325851200.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET3: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325592000.0 -> 1325678400.0 +DetCondTest::DQ...SUCCESS -> Flags: {} +ApplicationMgr INFO Application Manager Stopped successfully +""") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt b/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt new file mode 100644 index 000000000..22a8fb7c8 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt @@ -0,0 +1,20 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/force_disconnect.py</text></argument> +<argument name="validator"><text> +findReferenceBlock(""" +TEST ===> start +LHCBCOND DEBUG Forced disconnect from database (will reconnect automatically) +LHCBCOND.TimeOu...VERBOSE Stopping +DQFLAGS DEBUG Database already disconnected +ONLINE_2008 DEBUG Forced disconnect from database (will reconnect automatically) +ONLINE_2008.Tim...VERBOSE Stopping +DDDB DEBUG Forced disconnect from database (will reconnect automatically) +DDDB.TimeOutChe...VERBOSE Stopping +TEST ===> reconnect +ONLINE_2008.Tim...VERBOSE Starting +DDDB.TimeOutChe...VERBOSE Starting +TEST ===> end +""") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt new file mode 100755 index 000000000..14360891b --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt @@ -0,0 +1,4 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/getIOVs.py</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt b/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt new file mode 100755 index 000000000..3542de97d --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt @@ -0,0 +1,79 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +import GaudiKernel.SystemOfUnits as Units +Units.hours = Units.s * 3600 +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" +HBTEST.QueryGranularity = 1 * Units.hours +HBTEST.OutputLevel = DEBUG + +MessageSvc().setDebug.append("HBTEST.Cache") + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") +CondDB().QueryGranularity = 1 * Units.hours + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] +alg.LoadDuringInitialize = True +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) +#MessageSvc(OutputLevel = 1) + +from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] +UpdateManagerSvc().OutputLevel = DEBUG +MessageSvc().setDebug += ["UpdateManagerSvc::Item"] +</text></argument> +<argument name="exit_code"><integer>0</integer></argument> +<argument name="validator"><text> +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 MISSING +HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 0 - 1262305200000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262306400000000000 - 9223372036854775807, channel : 0 +HBTEST.Cache DEBUG Conflict found: item not inserted +HBTEST.Cache DEBUG IOV : 1262306400000000000 - 9223372036854775807 +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 FOUND +''', signature_offset = 1, id = "first_cond1") + +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 MISSING +HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 0 - 1262305200000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262306400000000000 - 1262308800000000000, channel : 0 +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 FOUND +''', signature_offset = 1, id = "first_cond2") + +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262305800000000000 channel 0 FOUND +''', signature_offset = 1, id = "second_cond1") + +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262305800000000000 channel 0 FOUND +''', signature_offset = 1, id = "second_cond2") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt b/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt new file mode 100644 index 000000000..f7bbfbeb5 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt @@ -0,0 +1,105 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] +alg.LoadDuringInitialize = True +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 4) +#MessageSvc(OutputLevel = 1) + +from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] +UpdateManagerSvc().OutputLevel = DEBUG +MessageSvc().setDebug += ["UpdateManagerSvc::Item"] +</text></argument> +<argument name="exit_code"><integer>4</integer></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check for bug #66497 (Velo motion system updated several times during initialization) +# 'marker1' must appear only once before 'maker2' +marker1 = "Condition2 from data provider" +marker2 = "Conditions loaded at initialize" +count = 0 +for l in outputlines: + if marker2 in l: + break + if marker1 in l: + count += 1 +if count != 1: + causes.append("bug #66497") + result["GaudiTest.marker.value"] = result.Quote(marker1) + result["GaudiTest.marker.count"] = result.Quote(str(count)) + result["GaudiTest.marker.count_expected"] = result.Quote("1") + +## Check that we find the expected lines in the right order +expected = [ + 'DetCondTest::Te... INFO Conditions loaded at initialize', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262308800.0 -> 1262307600.0', + '(int) Data = 80', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + 'HBTEST ERROR Database not up-to-date. Latest known update is at 2010-01-01 01:00:00.0 UTC, event time is 2010-01-01 01:10:00.0 UTC' + ] + +regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Conditions loaded at initialize|HBTEST.*ERROR" + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt b/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt new file mode 100644 index 000000000..d35694016 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt @@ -0,0 +1,35 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc() +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = 5 +ecs.EventTimeDecoder.TimeStep = 10 + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/Conditions/This/Does/Not/Exist"] +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) +#MessageSvc(OutputLevel = 1) + +</text></argument> +<argument name="exit_code"><integer>4</integer></argument> +<argument name="validator"><text> +## Find the error message about the problematic condition +import re +regexp = r"ERROR.*Conditions/This/Does/Not/Exist" +if not re.findall(regexp, stdout): + causes.append("output") + result["GaudiTest.output.expected_regexp"] = result.Quote(regexp) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt b/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt new file mode 100644 index 000000000..f92224120 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt @@ -0,0 +1,59 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + UpdateManagerSvc, CondDBAccessSvc, RunStampCheck) + +def ts(*args): + from datetime import datetime + epoch = datetime(1970, 1, 1) + return int((datetime(*args) - epoch).total_seconds() * 1000000000) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = ts(2015, 6, 10, 12, 00)) # no RunStamp for this time +ecs.addTool(FakeEventTime, "EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = ts(2015, 6, 9, 12, 00) +ecs.EventTimeDecoder.TimeStep = 24 * 60 * 60 * 1000000000 # 1 day + +RSTEST = CondDBAccessSvc("RSTEST", ConnectionString="sqlite_file:../data/RSTEST.db/RSTEST") + +CondDB().addAlternative(RSTEST, "/Conditions/Online/LHCb/RunStamp.xml") +CondDB().EnableRunStampCheck = True +RunStampCheck(OutputLevel=DEBUG) + +algMgr = ApplicationMgr(EvtSel = "NONE", EvtMax = 4) +#MessageSvc(OutputLevel = 1) +</text></argument> +<argument name="exit_code"><integer>4</integer></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check that we find the expected lines in the right order +expected = ''' +RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433851200.0 +RunStampCheck DEBUG Found '/Conditions/Online/LHCb/RunStamp.xml' valid in [1433808000.0, 1433894400.0) +RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433937600.0 +RunStampCheck ERROR Database not up-to-date. No valid data for run at 2015-06-10 12:00:00.0 UTC +EventLoopMgr SUCCESS Terminating event processing loop due to a stop scheduled by an incident listener +EventLoopMgr SUCCESS Terminating event processing loop due to scheduled stop +'''.strip().splitlines() + +regexp = '^(RunStampCheck.*(Checking|Found|Database)|.*Terminating event processing)' +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt b/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt new file mode 100755 index 000000000..7f49cd9bd --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt @@ -0,0 +1,71 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc() +ecs.addTool(FakeEventTime, "EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = 5 +ecs.EventTimeDecoder.TimeStep = 10 + +DBs = [] +for i in [0,3]: + data = { "name": "TESTDB%d"%i } + DBs.append(CondDBAccessSvc(data["name"], + ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) +readers = [] +for i in range(len(DBs)): + readers.append("'%s':(%d,%d)"%(DBs[i].getFullName(),i*10,(i+1)*10)) + +CondDB().addLayer(CondDBTimeSwitchSvc(Readers = readers, OutputLevel = DEBUG)) + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/AutoMap/FolderSet1/Object1"] +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) +#MessageSvc(OutputLevel = 1) + +</text></argument> +<argument name="validator"><text> +## 1st check: Find reference block +reference_block = """ +CondDBTimeSwitc... DEBUG Configured CondDBReaders: +CondDBTimeSwitc... DEBUG 0.0 - 0.00000001: CondDBAccessSvc/TESTDB0 +CondDBTimeSwitc... DEBUG 0.00000001 - 0.00000002: CondDBAccessSvc/TESTDB3 +""" +findReferenceBlock(reference_block) + +## 2nd check: find data +expected = [ + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/AutoMap/FolderSet1/Object1', + 'Validity: 0.0 -> 0.00000001', + '(int) Data = 1', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/AutoMap/FolderSet1/Object1', + 'Validity: 0.00000001 -> 0.00000002', + '(int) Data = 2'] + +regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions" +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt b/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt new file mode 100755 index 000000000..45a455863 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt @@ -0,0 +1,82 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") + +from Configurables import DetCondTest__FinalizationEvtLoop +alg = DetCondTest__FinalizationEvtLoop() +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] +alg.InitialTime = ecs.EventTimeDecoder.StartTime +alg.Step = ecs.EventTimeDecoder.TimeStep +alg.FinalTime = alg.InitialTime + 3 * alg.Step +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) +#MessageSvc(OutputLevel = 1) + +#from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +</text></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check that we find the expected lines in the right order +expected = [ + 'DetCondTest::Fi... INFO Update for event time 1262304600.0', + 'DetCondTest::Fi... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + 'DetCondTest::Fi... INFO Update for event time 1262305800.0', + 'DetCondTest::Fi... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + 'DetCondTest::Fi... INFO Update for event time 1262307000.0', + 'DetCondTest::Fi... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + + ] + +regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Update for event time" + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/scripts/check_db_reading.py b/Det/DetCond/tests/scripts/check_db_reading.py new file mode 100755 index 000000000..b3f23c080 --- /dev/null +++ b/Det/DetCond/tests/scripts/check_db_reading.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +import unittest + +import sys + +#import string +#import random + +class DetCondReadingTest(unittest.TestCase): + +# def assertEqualsConfig(self, lhs, rhs): +# self.assertEquals(lhs.getFullName(), rhs.getFullName()) + + def setUp(self): + unittest.TestCase.setUp(self) + self.testDB = 'sqlite_file:../data/TESTDB3.db/TESTDB3' + self.testFolder = '/lhcb.xml' + self.testout = '<?xml version="1.0" encoding="ISO-8859-1"?>\n<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd">\n<DDDB>\n <catalog name="dd">\n <catalogref href="AutoMap" />\n </catalog> \n</DDDB> \n' + self.Nmethods = 1 # number of methods + + def readDB(self): + from CondDBUI import CondDB + db = CondDB(self.testDB) + s = self.testFolder + if not db.db.existsFolder(s): return "" + data = db.getPayload(s,0,0) + if 'data' not in data: return "" + return data['data'] + +# def tearDown(self): +# unittest.TestCase.tearDown(self) + + def test_reading(self): + """Check CondDB reading """ + ret = self.readDB() + self.assertEquals(self.testout, ret) + +if __name__ == '__main__': + unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/configuration_module_test.py b/Det/DetCond/tests/scripts/configuration_module_test.py new file mode 100755 index 000000000..36276a6d7 --- /dev/null +++ b/Det/DetCond/tests/scripts/configuration_module_test.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python + +import unittest + +from Gaudi.Configuration import * +import GaudiKernel.Configurable +from GaudiKernel.Configurable import purge, applyConfigurableUsers +from Configurables import CondDB, DDDBConf +from Configurables import (CondDBCnvSvc, + CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc) + +#import logging +#from GaudiKernel.ProcessJobOptions import InstallRootLoggingHandler +#InstallRootLoggingHandler(level = logging.DEBUG) + +orig_reader = None +orig_dict = None +def equalConfigurable(lhs, rhs): + return lhs.getFullName() == rhs.getFullName() + +class DetCondConfigurationTest(unittest.TestCase): + + def assertEqualsConfig(self, lhs, rhs): + self.assertEquals(lhs.getFullName(), rhs.getFullName()) + + def setUp(self): + unittest.TestCase.setUp(self) + self.DDDB = DDDBConf() + self.CondDB = CondDB() + + def tearDown(self): + self.DDDB = self.CondDB = None + purge() + GaudiKernel.Configurable._appliedConfigurableUsers_ = False + unittest.TestCase.tearDown(self) + + def checkHeartBeat(self, conf, chkstr = ""): + conf = allConfigurables[eval(conf.split(':')[0]).split("/")[1]] + if isinstance(conf, CondDBLayeringSvc): + conf = conf.Layers[-1]# Only check the bottom layer + self.assertEquals(conf.getProp("HeartBeatCondition"), chkstr) + + + def test_000_originalConfiguration(self): + """Check the default configuration""" + applyConfigurableUsers() + global orig_reader, orig_dict + orig_reader = allConfigurables["CondDBCnvSvc"].CondDBReader + self.assertEquals(orig_reader.__class__.__name__, + "CondDBDispatcherSvc") + orig_dict = dict(orig_reader.Alternatives) + + def test_010_addCondDBLayer_1(self): + """Add one layer from CondDBAccessSvc instance""" + # Add the layer + layer = CondDBAccessSvc("layer") + self.CondDB.addLayer(layer) + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # check if we have a layering svc + self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") + # check for the new layer... + self.assertEqual(reader.Layers[0], layer) + # ... plus the original one + self.assertEqualsConfig(reader.Layers[1], orig_reader) + + def test_010_addCondDBLayer_2(self): + """Add layers from allowed Configurable instances""" + # Add the layers (one per type) + types = [CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc] + layers = [] + for i in range(len(types)): + layer = types[i]("layer_%d"%i) + layers.append(layer) + self.CondDB.addLayer(layer) + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # check if we have a layering svc + self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") + # correct size? + self.assertEquals(len(reader.Layers), len(layers) + 1) + # correct order (inverse of insertion order)... + layers.reverse() + for i in range(len(types)): + self.assertEqual(reader.Layers[i], layers[i]) + # ... plus the original one + self.assertEqualsConfig(reader.Layers[len(layers)], orig_reader) + + def test_020_addCondDBAlternative_1(self): + """Add one alternative from CondDBAccessSvc instance""" + # Add the alternative + alternative = CondDBAccessSvc("alternative") + self.CondDB.addAlternative(alternative, "/Test") + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # the reader should not have changed + self.assertEqualsConfig(reader, orig_reader) + # correct size? + self.assertEquals(len(reader.Alternatives), len(orig_dict) + 1) + # check the previous alternatives + for k in orig_dict: + self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) + # plus the new one + self.assertEqualsConfig(reader.Alternatives["/Test"], alternative) + + def test_020_addCondDBAlternative_2(self): + """Replace one alternative from CondDBAccessSvc instance""" + path = orig_dict.keys()[0] + + # Add the alternative + alternative = CondDBAccessSvc("alternative") + self.CondDB.addAlternative(alternative, path) + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # the reader should not have changed + self.assertEqualsConfig(reader, orig_reader) + # correct size? + self.assertEquals(len(reader.Alternatives), len(orig_dict)) + # check the previous alternatives + for k in orig_dict: + if k != path: + self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) + else: + self.assertEqualsConfig(reader.Alternatives[k], alternative) + + def test_030_heartbeat(self): + """HeartBeat condition (off-line, Oracle, default)""" + self.CondDB.Online = False + self.CondDB.UseOracle = True + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") + + def test_031_heartbeat(self): + """HeartBeat condition (off-line, Oracle, ignore)""" + self.CondDB.Online = False + self.CondDB.UseOracle = True + self.CondDB.IgnoreHeartBeat = True + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "") + + def test_032_heartbeat(self): + """HeartBeat condition (off-line, SQLite, default)""" + self.CondDB.Online = False + self.CondDB.UseOracle = False + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers[:-1]: + self.checkHeartBeat(conf, "") + conf = online.Readers[-1] + self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") + + def test_033_heartbeat(self): + """HeartBeat condition (off-line, SQLite, ignore)""" + self.CondDB.Online = False + self.CondDB.UseOracle = False + self.CondDB.IgnoreHeartBeat = True + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers: + self.checkHeartBeat(conf, "") + + def test_040_heartbeat(self): + """HeartBeat condition (on-line, Oracle, not ignore)""" + self.CondDB.Online = True + self.CondDB.UseOracle = True + self.CondDB.IgnoreHeartBeat = False + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") + + def test_041_heartbeat(self): + """HeartBeat condition (on-line, Oracle, default)""" + self.CondDB.Online = True + self.CondDB.UseOracle = True + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "") + + def test_042_heartbeat(self): + """HeartBeat condition (on-line, SQLite, not ignore)""" + self.CondDB.Online = True + self.CondDB.UseOracle = False + self.CondDB.IgnoreHeartBeat = False + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers[:-1]: + self.checkHeartBeat(conf, "") + conf = online.Readers[-1] + self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") + + def test_043_heartbeat(self): + """HeartBeat condition (on-line, SQLite, default)""" + self.CondDB.Online = True + self.CondDB.UseOracle = False + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers: + self.checkHeartBeat(conf, "") + +if __name__ == '__main__': + unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/connection_timeout.py b/Det/DetCond/tests/scripts/connection_timeout.py new file mode 100644 index 000000000..aac17167b --- /dev/null +++ b/Det/DetCond/tests/scripts/connection_timeout.py @@ -0,0 +1,22 @@ +## @file +# Small script forcing a time-out in the access to the +from Gaudi.Configuration import * +from Configurables import CondDB, CondDBAccessSvc, DDDBConf + +DDDBConf() + +DDDB = CondDBAccessSvc("DDDB") +DDDB.ConnectionTimeOut = 5 + +#MessageSvc(OutputLevel = ERROR) + +import GaudiPython +app = GaudiPython.AppMgr() +app.initialize() +app.start() + +import time +app.detSvc()["/dd"] # access the DB +print "TEST ===> start" +time.sleep(6) # wait enough +print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/direct_mapping_test.py b/Det/DetCond/tests/scripts/direct_mapping_test.py new file mode 100755 index 000000000..10515b6fe --- /dev/null +++ b/Det/DetCond/tests/scripts/direct_mapping_test.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +""" +Script for the test of possible use-cases of the direct mapping between +the COOL hierarchy and the transient store one. +Use-cases: + 0) basic mapping (CondDBAccessSvc) + 1) alternative for a folderset in the main DB + 2) alternative for a folderset _not_ in the main DB + 3) alternative for a folder _not_ in the main DB + 4) layers +""" +__author__ = "Marco Clemencic" + +def configure(version): + from Gaudi.Configuration import (importOptions, + ApplicationMgr, + MessageSvc) + from Configurables import DDDBConf, CondDB, CondDBAccessSvc + dddbConf = DDDBConf() + cdb = CondDB() + + DBs = [] + for i in range(3): + data = { "name": "TESTDB%d"%i } + DBs.append(CondDBAccessSvc(data["name"], + ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) + + cdb.PartitionConnectionString["DDDB"] = DBs[0].ConnectionString + cdb.Tags["DDDB"] = "" + if version == 1: + cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2') + elif version == 2: + cdb.addAlternative(DBs[2],'/AutoMap/FolderSet3') + elif version == 3: + cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2/ObjectA') + elif version == 4: + cdb.addLayer(DBs[1]) + cdb.addLayer(DBs[2]) + elif version != 0: + raise RuntimeError("Invalid version number") + + ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") + #MessageSvc(OutputLevel = 1) + +def datastore_walk(ds, top = "/"): + if top == "/": + top = ds._idm.rootName() + obj = ds[top] + if obj is not None: + yield ds[top] + nodes = [ i.identifier() for i in ds.leaves(ds[top]) ] + for n in nodes: + for obj in datastore_walk(ds,n): + yield obj + +def node_names(ds, top = "/"): + return [ obj.registry().identifier() for obj in datastore_walk(ds,top) ] + +def main(conf): + configure(conf) + + from Gaudi.Configuration import configurationDict + from pprint import pprint + import GaudiPython + app = GaudiPython.AppMgr() + pprint(configurationDict()) + app.initialize() + + dds = app.detsvc() + # load everything in the store + nodes = node_names(dds) + nodes.sort() + + print "=== Begin Nodes ===" + for n in nodes: + print n + print "=== End Nodes ===" + +if __name__ == '__main__': + import sys + if len(sys.argv) < 2: + version = 0 + else: + version = int(sys.argv[1]) + + main(version) diff --git a/Det/DetCond/tests/scripts/force_disconnect.py b/Det/DetCond/tests/scripts/force_disconnect.py new file mode 100644 index 000000000..e504010ab --- /dev/null +++ b/Det/DetCond/tests/scripts/force_disconnect.py @@ -0,0 +1,28 @@ +## @file +# Small script forcing a time-out in the access to the +from Gaudi.Configuration import * +from Configurables import CondDB, CondDBAccessSvc, DDDBConf + +DDDBConf(DataType="2008") + +#DDDB = CondDBAccessSvc("DDDB") +#DDDB.ConnectionTimeOut = 5 + +partitions = ['DDDB', 'ONLINE_2008', 'LHCBCOND', 'DQFLAGS'] +msg = MessageSvc(OutputLevel=WARNING) +msg.setDebug.extend(partitions) +msg.setVerbose.extend([p + '.TimeOutChecker' for p in partitions]) + +import GaudiPython +app = GaudiPython.AppMgr() +app.initialize() +app.start() + +import time +app.detSvc()["/dd/Conditions/Online/LHCb"] # access the DB +print "TEST ===> start" +reader = app.service('CondDBCnvSvc', GaudiPython.gbl.ICondDBReader) +reader.disconnect() +print "TEST ===> reconnect" +app.detSvc()["/dd/Conditions/Online/LHCb/Tick"] # access the DB +print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/getIOVs.py b/Det/DetCond/tests/scripts/getIOVs.py new file mode 100755 index 000000000..8aa9c2cd4 --- /dev/null +++ b/Det/DetCond/tests/scripts/getIOVs.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +""" +Script for the test of IOV retrieval +""" +__author__ = "Marco Clemencic" + +import sys +from datetime import datetime, timedelta + +def toTimeStamp(dt): + if isinstance(dt, timedelta): + t = dt + else: + t = dt - datetime(1970, 1, 1, 0) + return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 + +def toDateTime(ts): + return datetime(1970, 1, 1, 0) + timedelta(seconds=ts/1000000000) + +def configure(): + from Gaudi.Configuration import (ApplicationMgr, + MessageSvc, ERROR) + from Configurables import DDDBConf, CondDB, CondDBAccessSvc, EventClockSvc, FakeEventTime + dddbConf = DDDBConf() + cdb = CondDB() + + cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" + cdb.Tags["DQFLAGS"] = "" + + ecs = EventClockSvc(InitialTime=toTimeStamp(datetime(2012,1,1,12))) + ecs.addTool(FakeEventTime, "EventTimeDecoder") + ecs.EventTimeDecoder.StartTime = ecs.InitialTime + ecs.EventTimeDecoder.TimeStep = toTimeStamp(timedelta(days=1)) + + ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") + MessageSvc(OutputLevel = ERROR) + +def checkIOVs(dbReader, since, until, expected): + import GaudiPython + IOV = GaudiPython.gbl.ICondDBReader.IOV + Time = GaudiPython.gbl.Gaudi.Time + + print "Checking %s -> %s ..." % (since, until), + t1 = Time(toTimeStamp(since)) + t2 = Time(toTimeStamp(until)) + iov = IOV(t1, t2) + result = dbReader.getIOVs("/Conditions/DQ/Flags", iov, 0) + + found = [(toDateTime(iov.since.ns()), toDateTime(iov.until.ns())) for iov in result] + + good = found == expected + if not good: + print "ERROR" + print " expected:", [tuple(map(str, iov)) for iov in expected] + print " found: ", [tuple(map(str, iov)) for iov in found] + else: + print "OK" + return good + +def main(): + configure() + + from Gaudi.Configuration import configurationDict + from pprint import pprint + import GaudiPython + app = GaudiPython.AppMgr() + pprint(configurationDict()) + app.initialize() + + dq = app.service("DQFLAGS", GaudiPython.gbl.ICondDBReader) + + dbData = [(datetime(2012,1,1,0), datetime(2012,1,2,0)), + (datetime(2012,1,2,0), datetime(2012,1,3,0)), + (datetime(2012,1,3,0), datetime(2012,1,4,0)), + (datetime(2012,1,5,0), datetime(2012,1,6,0))] + + tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0), dbData[0:3]), + (datetime(2012,1,1,12), datetime(2012,1,3,12), dbData[0:3]), + (datetime(2012,1,2,12), datetime(2012,1,5,12), dbData[1:4]), + (datetime(2012,1,4,12), datetime(2012,1,6,12), dbData[3:4]), + ] + print "\n=== Begin Tests ===" + bad = 0 + for since, until, expected in tests: + if not checkIOVs(dq, since, until, expected): + bad += 1 + print "=== End Tests ===" + + if bad: + print "\nFailed %d tests out of %d\n" % (bad, len(tests)) + sys.exit(1) + + print "" + +if __name__ == '__main__': + main() diff --git a/Det/DetCond/tests/src/DQScanTest.cpp b/Det/DetCond/tests/src/DQScanTest.cpp new file mode 100644 index 000000000..6ff5a6faa --- /dev/null +++ b/Det/DetCond/tests/src/DQScanTest.cpp @@ -0,0 +1,106 @@ +// Local custom parsers must be defined very early in the file. +#include "GaudiKernel/ParsersFactory.h" + +namespace Gaudi { + namespace Parsers { + // Note: to be kept in sync with the property in DetCondTest::DQScanTest + StatusCode parse(std::vector<std::pair<unsigned int, unsigned int> >& result, const std::string& input) { + return Gaudi::Parsers::parse_(result, input); + } + } +} + +// Include files + +#include "DetCond/ICondDBReader.h" + +// local +#include "DQScanTest.h" + +#include "boost/foreach.hpp" + +namespace { + inline long long s2ns(unsigned int s) { + return static_cast<long long>(s) * 1000000000; + } +} + +// ---------------------------------------------------------------------------- +// Implementation file for class: DQScanTest +// +// 31/01/2012: Marco Clemencic +// ---------------------------------------------------------------------------- +DECLARE_NAMESPACE_ALGORITHM_FACTORY(DetCondTest, DQScanTest) + +namespace DetCondTest { +// ============================================================================ +// Standard constructor, initializes variables +// ============================================================================ +DQScanTest::DQScanTest(const std::string& name, ISvcLocator* pSvcLocator) + : GaudiAlgorithm(name, pSvcLocator), m_scanner(0) +{ + declareProperty("DQScanner", + m_DQScannerName = "CondDBDQScanner", + "Type/name of the IDQScanner instance to use."); + declareProperty("IOVs", + m_iovsProp, + "List of IOVs (specified in seconds) to scan."); +} + +// ============================================================================ +// Destructor +// ============================================================================ +DQScanTest::~DQScanTest() {} + +// ============================================================================ +// Initialization +// ============================================================================ +StatusCode DQScanTest::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + + m_scanner = tool<IDQScanner>(m_DQScannerName); + + m_iovs.clear(); + BOOST_FOREACH(IOVPropType &iov, m_iovsProp) { + m_iovs.push_back(ICondDBReader::IOV(Gaudi::Time(s2ns(iov.first)), Gaudi::Time(s2ns(iov.second)))); + } + + return StatusCode::SUCCESS; +} + +// ============================================================================ +// Main execution +// ============================================================================ +StatusCode DQScanTest::execute() { + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; + + info() << "Execute" << endmsg; + + BOOST_FOREACH(ICondDBReader::IOV &iov, m_iovs) { + always() << "Process IOV " << iov.since << " -> " << iov.until << endmsg; + IDQFilter::FlagsType result = m_scanner->scan(iov.since, iov.until); + always() << "-> Flags: " << result << endmsg; + } + + return StatusCode::SUCCESS; +} + +// ============================================================================ +// Finalize +// ============================================================================ +StatusCode DQScanTest::finalize() { + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; + + if (release(m_scanner).isFailure()) { + warning() << "Failed to release tool " << m_DQScannerName << endmsg; + } + m_scanner = 0; + + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +// ============================================================================ +} // namespace DetCondTest diff --git a/Det/DetCond/tests/src/DQScanTest.h b/Det/DetCond/tests/src/DQScanTest.h new file mode 100644 index 000000000..78d13b015 --- /dev/null +++ b/Det/DetCond/tests/src/DQScanTest.h @@ -0,0 +1,51 @@ +#ifndef SRC_DQSCANTEST_H +#define SRC_DQSCANTEST_H 1 +// Include files +// from Gaudi +#include "GaudiAlg/GaudiAlgorithm.h" + +#include "Kernel/IDQScanner.h" + +#include "DetCond/ICondDBReader.h" + +namespace DetCondTest { + +/** @class DQScanTest DQScanTest.h src/DQScanTest.h + * + * Algorithm to test the behavior of an IDQScanner implementation. + * + * @author Marco Clemencic + * @date 31/01/2012 + */ +class DQScanTest: public GaudiAlgorithm { +public: + typedef std::pair<unsigned int, unsigned int> IOVPropType; + typedef std::vector<IOVPropType> IOVListPropType; + + /// Standard constructor + DQScanTest(const std::string& name, ISvcLocator* pSvcLocator); + virtual ~DQScanTest(); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization +protected: +private: + + /// Type/name of the IDQScanner instance. + /// (property DQScanner) + std::string m_DQScannerName; + + /// List of IOVs (with time specified in seconds) to try to retrieve (property). + IOVListPropType m_iovsProp; + + /// List of IOVs to try to retrieve. + ICondDBReader::IOVList m_iovs; + + /// Pointer to the IDQScanner instance. + IDQScanner *m_scanner; +}; + +} + +#endif // SRC_DQSCANTEST_H diff --git a/Det/DetCond/tests/src/TestConditionAlg.cpp b/Det/DetCond/tests/src/TestConditionAlg.cpp new file mode 100755 index 000000000..d749e5d05 --- /dev/null +++ b/Det/DetCond/tests/src/TestConditionAlg.cpp @@ -0,0 +1,287 @@ +// Include files +#include "GaudiKernel/Map.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/IDetDataSvc.h" +#include "DetDesc/Condition.h" + +#include <vector> + +namespace DetCondTest { + +/** @class TestConditionAlg TestConditionAlg.h component/TestConditionAlg.h + * + * Simple algorithm that prints the requested conditions at every event. + * + * @author Marco CLEMENCIC + * @date 2008-06-27 + */ +class TestConditionAlg : public GaudiAlgorithm { +public: + /// Standard constructor + TestConditionAlg( const std::string& name, ISvcLocator* pSvcLocator ); + + virtual ~TestConditionAlg( ); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization + +protected: + + void i_dump(); + + /// Names of the conditions to print + std::vector<std::string> m_condPaths; + + /// Flag to decide if the conditions have to be loaded also during the + /// initialize step. + bool m_loadAtInit; + + /// Container of the conditions to print + std::vector<std::string> m_conditionDeps; + + /// Container of the conditions to print + GaudiUtils::Map<std::string,Condition*> m_conditions; +}; + +//----------------------------------------------------------------------------- +// Implementation file for class : TestConditionAlg +// +// 2008-06-27 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +TestConditionAlg::TestConditionAlg( const std::string& name, + ISvcLocator* pSvcLocator) + : GaudiAlgorithm ( name , pSvcLocator ) +{ + declareProperty("Conditions", m_condPaths, + "list of paths to conditions in the detector transient store"); + declareProperty("LoadDuringInitialize", m_loadAtInit = false, + "load the requested conditions already during the initialization"); + declareProperty("ConditionsDependencies", m_conditionDeps, + "declare dependencies between objects as a list of strings 'A -> B') " + "to indicate that the condition A depends on B."); +} +//============================================================================= +// Destructor +//============================================================================= +TestConditionAlg::~TestConditionAlg() {} + +namespace { + void printDepsError(MsgStream& stream, + size_t lineNo, const std::string& msg, + const std::string& line) { + stream << "Syntax error in item " << lineNo + << " of ConditionsDependencies: " << msg << endmsg; + stream << " '" << line << "'" << endmsg; + } +} +//============================================================================= +// Initialization +//============================================================================= +StatusCode TestConditionAlg::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + + std::vector<std::string>::const_iterator path; + for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ + registerCondition<TestConditionAlg>(*path,m_conditions[*path],NULL); + } + + std::vector<std::string>::const_iterator deps; + for (deps = m_conditionDeps.begin(); deps != m_conditionDeps.end(); ++deps) { + std::string::size_type pos = deps->find("->"); + if (pos == std::string::npos) { + printDepsError(error(), deps - m_conditionDeps.begin(), "missing '->'", *deps); + return StatusCode::FAILURE; + } + std::string::size_type p0, p1; + p0 = deps->find_first_not_of(" \n\r\t"); + p1 = deps->find_last_not_of(" \n\r\t", pos - 1) + 1; + std::string first(*deps, p0, p1 - p0); + if (first.empty()) { + printDepsError(error(), deps - m_conditionDeps.begin(), "missing first argument", *deps); + return StatusCode::FAILURE; + } + p0 = deps->find_first_not_of(" \n\r\t", pos + 2); + p1 = deps->find_last_not_of(" \n\r\t") + 1; + std::string second(*deps, p0, p1 - p0); + if (second.empty()) { + printDepsError(error(), deps - m_conditionDeps.begin(), "missing second argument", *deps); + return StatusCode::FAILURE; + } + info() << "Declaring dependency of '" << first << "' on '" << second << "'" << endmsg; + updMgrSvc()->registerCondition(getDet<Condition>(first), second); + } + + if (m_loadAtInit) { + sc = updMgrSvc()->update(this); + info() << "Conditions loaded at initialize" << endmsg; + if (sc.isSuccess()){ + i_dump(); + } + else return sc; + } + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode TestConditionAlg::execute() { + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; + i_dump(); + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode TestConditionAlg::finalize() { + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; + + updMgrSvc()->unregister(this); + m_conditions.clear(); + m_condPaths.clear(); + + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +//============================================================================= +// Print the conditions +//============================================================================= +void TestConditionAlg::i_dump() +{ + info() << "Requested Conditions:\n"; + GaudiUtils::Map<std::string,Condition*>::iterator it; + for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { + info() << "--- " << it->first << "\n" << *(it->second) << "\n"; + } + info() << endmsg; +} + +//============================================================================= + + +/** Small algorithm that runs a fake event loop during finalize to scan the + * values of the conditions (see bug #74255). + * + * @author Marco CLEMENCIC + * @date 2010-10-25 + */ +class FinalizationEvtLoop: public GaudiAlgorithm { +public: + /// Standard constructor + FinalizationEvtLoop(const std::string& name, ISvcLocator* pSvcLocator): + GaudiAlgorithm(name, pSvcLocator) + { + declareProperty("Conditions", m_condPaths, + "list of paths to conditions in the detector transient store"); + declareProperty("InitialTime", m_initTime = 0, // 1970-01-01 00:00:00UTC + "First event time of the fake event loop"); + declareProperty("FinalTime", m_finalTime = m_initTime + 10000000000LL, // init + 10s + "Final time of the loop"); + declareProperty("Step", m_step = 1000000000LL, // 1s + "Step of the loop"); + } + + virtual ~FinalizationEvtLoop() {} + + virtual StatusCode initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + + std::vector<std::string>::const_iterator path; + for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ + registerCondition<FinalizationEvtLoop>(*path, m_conditions[*path], NULL); + } + + return StatusCode::SUCCESS; + } + + virtual StatusCode execute () { + return StatusCode::SUCCESS; + } + + virtual StatusCode finalize () { + Gaudi::Time t(m_initTime); + const Gaudi::Time fin(m_finalTime); + const Gaudi::TimeSpan step(m_step); + + SmartIF<IDetDataSvc> dds(detSvc()); + for ( ; t < fin; t += step) { + dds->setEventTime(t); + info() << "Update for event time " << t << endmsg; + if (updMgrSvc()->newEvent().isSuccess()) { + info() << "Requested Conditions:\n"; + GaudiUtils::Map<std::string,Condition*>::iterator it; + for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { + info() << "--- " << it->first << "\n" << *(it->second) << "\n"; + } + info() << endmsg; + } + else { + error() << "Failure updating" << endmsg; + return StatusCode::FAILURE; + } + } + + return StatusCode::SUCCESS; + } + +private: + /// First event time of the fake event loop + Gaudi::Time::ValueType m_initTime; + /// First event time of the fake event loop + Gaudi::Time::ValueType m_finalTime; + /// First event time of the fake event loop + Gaudi::Time::ValueType m_step; + + /// Names of the conditions to print + std::vector<std::string> m_condPaths; + + /// Container of the conditions to print + GaudiUtils::Map<std::string,Condition*> m_conditions; +}; + +/** Test algorithm that triggers the bug #80076 + * https://savannah.cern.ch/bugs/?80076 + */ +class bug_80076: public TestConditionAlg { +public: + /// Constructor. + bug_80076(const std::string& name, ISvcLocator* pSvcLocator): + TestConditionAlg(name, pSvcLocator) {} + + /// Override the initialize to ensure that the conditions are already loaded + /// during the initialize. + StatusCode initialize() { + StatusCode sc = TestConditionAlg::initialize(); + if (sc.isFailure()) return sc; + + std::vector<std::string>::const_iterator path; + for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ + // this ensures that the objects are loaded in the transient store + exist<DataObject>(detSvc(), *path); + } + + return sc; + } +}; + +} + +// Declaration of the Algorithm Factory +DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, TestConditionAlg ) +DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, FinalizationEvtLoop ) +DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, bug_80076 ) -- GitLab From 15d77a7e5450bec2e17eb7dfe399f20f275ed73d Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 08:44:26 +0200 Subject: [PATCH 22/37] Add Roel's hack to use fake ONLINE --- Rich/Panoptes/python/Panoptes/Configuration.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Rich/Panoptes/python/Panoptes/Configuration.py b/Rich/Panoptes/python/Panoptes/Configuration.py index 5d8ce2b26..fbcd3dfa8 100755 --- a/Rich/Panoptes/python/Panoptes/Configuration.py +++ b/Rich/Panoptes/python/Panoptes/Configuration.py @@ -105,6 +105,13 @@ class Panoptes(LHCbConfigurableUser): saverSeq.Members += [updateAndReset] ApplicationMgr().TopAlg += [saverSeq] + from Configurables import CondDB + conddb = CondDB() + conddb.EnableRunStampCheck = False + conddb.Tags["ONLINE"] = 'fake' + conddb.IgnoreHeartBeat = True + conddb.UseDBSnapshot = True + #use MonitorSvc self.setProp("UseMonitorSvc", True) -- GitLab From 276be94d8574916057f31c896aca3358215cd3c9 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 09:41:57 +0100 Subject: [PATCH 23/37] remove Det/DetCond (adding by roel at the pit) --- Det/DetCond/CMakeLists.txt | 37 - Det/DetCond/DetCond/CondDBGenericCnv.h | 126 -- Det/DetCond/DetCond/ICOOLConfSvc.h | 36 - Det/DetCond/DetCond/ICondDBAccessSvc.h | 108 -- Det/DetCond/DetCond/ICondDBEditor.h | 75 - Det/DetCond/DetCond/ICondDBReader.h | 110 -- Det/DetCond/cmt/requirements | 79 - Det/DetCond/doc/release.notes | 1247 -------------- Det/DetCond/options/UseOracle.py | 3 - Det/DetCond/python/DetCond/Configuration.py | 788 --------- Det/DetCond/python/DetCond/HistoCond.py | 104 -- Det/DetCond/python/DetCond/__init__.py | 0 Det/DetCond/src/Lib/CondDBGenericCnv.cpp | 139 -- Det/DetCond/src/component/COOLConfSvc.cpp | 281 ---- Det/DetCond/src/component/COOLConfSvc.h | 94 -- Det/DetCond/src/component/CondDBAccessSvc.cpp | 1492 ----------------- Det/DetCond/src/component/CondDBAccessSvc.h | 506 ------ Det/DetCond/src/component/CondDBCache.cpp | 444 ----- Det/DetCond/src/component/CondDBCache.h | 279 --- Det/DetCond/src/component/CondDBCnvSvc.cpp | 197 --- Det/DetCond/src/component/CondDBCnvSvc.h | 123 -- Det/DetCond/src/component/CondDBCommon.cpp | 90 - Det/DetCond/src/component/CondDBCommon.h | 29 - Det/DetCond/src/component/CondDBDQScanner.cpp | 147 -- Det/DetCond/src/component/CondDBDQScanner.h | 56 - .../src/component/CondDBDispatcherSvc.cpp | 294 ---- .../src/component/CondDBDispatcherSvc.h | 109 -- .../src/component/CondDBLayeringSvc.cpp | 288 ---- Det/DetCond/src/component/CondDBLayeringSvc.h | 103 -- Det/DetCond/src/component/CondDBLogger.cpp | 250 --- Det/DetCond/src/component/CondDBLogger.h | 147 -- Det/DetCond/src/component/CondDBReplayAlg.cpp | 162 -- Det/DetCond/src/component/CondDBReplayAlg.h | 60 - .../src/component/CondDBSQLiteCopyAccSvc.cpp | 135 -- .../src/component/CondDBSQLiteCopyAccSvc.h | 55 - .../src/component/CondDBTimeSwitchSvc.cpp | 363 ---- .../src/component/CondDBTimeSwitchSvc.h | 198 --- Det/DetCond/src/component/IOVListHelpers.cpp | 23 - Det/DetCond/src/component/IOVListHelpers.h | 10 - Det/DetCond/src/component/LoadDDDB.cpp | 101 -- Det/DetCond/src/component/LoadDDDB.h | 35 - Det/DetCond/src/component/RelyConverter.cpp | 479 ------ Det/DetCond/src/component/RelyConverter.h | 148 -- Det/DetCond/src/component/RunStampCheck.cpp | 140 -- Det/DetCond/src/dict/DetCondDict.h | 38 - Det/DetCond/src/dict/DetCondDict.xml | 14 - Det/DetCond/tests/data/DQFLAGS.db | Bin 48128 -> 0 bytes Det/DetCond/tests/data/HBTEST.db | Bin 76800 -> 0 bytes Det/DetCond/tests/data/RSTEST.db | Bin 48128 -> 0 bytes Det/DetCond/tests/data/TESTDB0.db | Bin 183296 -> 0 bytes Det/DetCond/tests/data/TESTDB1.db | Bin 79872 -> 0 bytes Det/DetCond/tests/data/TESTDB2.db | Bin 79872 -> 0 bytes Det/DetCond/tests/data/TESTDB3.db | Bin 183296 -> 0 bytes Det/DetCond/tests/data/genDQFLAGS.py | 39 - Det/DetCond/tests/data/genHBTEST.py | 48 - Det/DetCond/tests/data/genRSTEST.py | 32 - .../tests/qmtest/detcond.qms/bug_80076.qmt | 60 - .../qmtest/detcond.qms/check_db_reading.qmt | 4 - .../detcond.qms/configuration_module.qmt | 4 - .../qmtest/detcond.qms/connection_timeout.qmt | 11 - .../detcond.qms/direct_mapping_altern1.qmt | 22 - .../detcond.qms/direct_mapping_altern2.qmt | 25 - .../detcond.qms/direct_mapping_altern3.qmt | 23 - .../detcond.qms/direct_mapping_base.qmt | 19 - .../detcond.qms/direct_mapping_layers.qmt | 27 - .../detcond.qms/dqscanner.qms/basic.qmt | 63 - .../qmtest/detcond.qms/force_disconnect.qmt | 20 - .../qmtest/detcond.qms/get_iovs.qms/basic.qmt | 4 - .../tests/qmtest/detcond.qms/granularity.qmt | 79 - .../tests/qmtest/detcond.qms/heart_beat.qmt | 105 -- .../qmtest/detcond.qms/missing_condition.qmt | 35 - .../tests/qmtest/detcond.qms/run_stamp.qmt | 59 - .../tests/qmtest/detcond.qms/time_switch.qmt | 71 - .../qmtest/detcond.qms/update_in_finalize.qmt | 82 - Det/DetCond/tests/scripts/check_db_reading.py | 40 - .../scripts/configuration_module_test.py | 231 --- .../tests/scripts/connection_timeout.py | 22 - .../tests/scripts/direct_mapping_test.py | 86 - Det/DetCond/tests/scripts/force_disconnect.py | 28 - Det/DetCond/tests/scripts/getIOVs.py | 96 -- Det/DetCond/tests/src/DQScanTest.cpp | 106 -- Det/DetCond/tests/src/DQScanTest.h | 51 - Det/DetCond/tests/src/TestConditionAlg.cpp | 287 ---- 83 files changed, 11521 deletions(-) delete mode 100644 Det/DetCond/CMakeLists.txt delete mode 100755 Det/DetCond/DetCond/CondDBGenericCnv.h delete mode 100755 Det/DetCond/DetCond/ICOOLConfSvc.h delete mode 100755 Det/DetCond/DetCond/ICondDBAccessSvc.h delete mode 100755 Det/DetCond/DetCond/ICondDBEditor.h delete mode 100755 Det/DetCond/DetCond/ICondDBReader.h delete mode 100755 Det/DetCond/cmt/requirements delete mode 100755 Det/DetCond/doc/release.notes delete mode 100644 Det/DetCond/options/UseOracle.py delete mode 100755 Det/DetCond/python/DetCond/Configuration.py delete mode 100644 Det/DetCond/python/DetCond/HistoCond.py delete mode 100644 Det/DetCond/python/DetCond/__init__.py delete mode 100755 Det/DetCond/src/Lib/CondDBGenericCnv.cpp delete mode 100755 Det/DetCond/src/component/COOLConfSvc.cpp delete mode 100755 Det/DetCond/src/component/COOLConfSvc.h delete mode 100755 Det/DetCond/src/component/CondDBAccessSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBAccessSvc.h delete mode 100755 Det/DetCond/src/component/CondDBCache.cpp delete mode 100755 Det/DetCond/src/component/CondDBCache.h delete mode 100755 Det/DetCond/src/component/CondDBCnvSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBCnvSvc.h delete mode 100755 Det/DetCond/src/component/CondDBCommon.cpp delete mode 100755 Det/DetCond/src/component/CondDBCommon.h delete mode 100644 Det/DetCond/src/component/CondDBDQScanner.cpp delete mode 100644 Det/DetCond/src/component/CondDBDQScanner.h delete mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.h delete mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.h delete mode 100755 Det/DetCond/src/component/CondDBLogger.cpp delete mode 100755 Det/DetCond/src/component/CondDBLogger.h delete mode 100755 Det/DetCond/src/component/CondDBReplayAlg.cpp delete mode 100755 Det/DetCond/src/component/CondDBReplayAlg.h delete mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h delete mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.h delete mode 100644 Det/DetCond/src/component/IOVListHelpers.cpp delete mode 100644 Det/DetCond/src/component/IOVListHelpers.h delete mode 100755 Det/DetCond/src/component/LoadDDDB.cpp delete mode 100755 Det/DetCond/src/component/LoadDDDB.h delete mode 100755 Det/DetCond/src/component/RelyConverter.cpp delete mode 100755 Det/DetCond/src/component/RelyConverter.h delete mode 100644 Det/DetCond/src/component/RunStampCheck.cpp delete mode 100755 Det/DetCond/src/dict/DetCondDict.h delete mode 100755 Det/DetCond/src/dict/DetCondDict.xml delete mode 100644 Det/DetCond/tests/data/DQFLAGS.db delete mode 100644 Det/DetCond/tests/data/HBTEST.db delete mode 100644 Det/DetCond/tests/data/RSTEST.db delete mode 100755 Det/DetCond/tests/data/TESTDB0.db delete mode 100755 Det/DetCond/tests/data/TESTDB1.db delete mode 100755 Det/DetCond/tests/data/TESTDB2.db delete mode 100755 Det/DetCond/tests/data/TESTDB3.db delete mode 100644 Det/DetCond/tests/data/genDQFLAGS.py delete mode 100644 Det/DetCond/tests/data/genHBTEST.py delete mode 100755 Det/DetCond/tests/data/genRSTEST.py delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt delete mode 100755 Det/DetCond/tests/scripts/check_db_reading.py delete mode 100755 Det/DetCond/tests/scripts/configuration_module_test.py delete mode 100644 Det/DetCond/tests/scripts/connection_timeout.py delete mode 100755 Det/DetCond/tests/scripts/direct_mapping_test.py delete mode 100644 Det/DetCond/tests/scripts/force_disconnect.py delete mode 100755 Det/DetCond/tests/scripts/getIOVs.py delete mode 100644 Det/DetCond/tests/src/DQScanTest.cpp delete mode 100644 Det/DetCond/tests/src/DQScanTest.h delete mode 100755 Det/DetCond/tests/src/TestConditionAlg.cpp diff --git a/Det/DetCond/CMakeLists.txt b/Det/DetCond/CMakeLists.txt deleted file mode 100644 index 4f314aebe..000000000 --- a/Det/DetCond/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -################################################################################ -# Package: DetCond -################################################################################ -gaudi_subdir(DetCond v12r47) - -gaudi_depends_on_subdirs(Det/DetDesc - GaudiAlg - GaudiKernel - Kernel/LHCbKernel) - -find_package(Boost COMPONENTS system thread filesystem) -find_package(COOL COMPONENTS CoolKernel CoolApplication) -find_package(CORAL COMPONENTS CoralBase CoralKernel RelationalAccess) - -gaudi_add_library(DetCondLib - src/Lib/*.cpp - PUBLIC_HEADERS DetCond - INCLUDE_DIRS Boost COOL CORAL - LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel) - -gaudi_add_module(DetCond - src/component/*.cpp - tests/src/*.cpp - INCLUDE_DIRS Boost COOL CORAL - LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib) - -gaudi_add_dictionary(DetCond - src/dict/DetCondDict.h - src/dict/DetCondDict.xml - INCLUDE_DIRS Boost COOL CORAL - LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib - OPTIONS "-U__MINGW32__") - -gaudi_install_python_modules() - - -gaudi_add_test(QMTest QMTEST) diff --git a/Det/DetCond/DetCond/CondDBGenericCnv.h b/Det/DetCond/DetCond/CondDBGenericCnv.h deleted file mode 100755 index 08f112058..000000000 --- a/Det/DetCond/DetCond/CondDBGenericCnv.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef DETCOND_CONDDBGENERICCNV_H -#define DETCOND_CONDDBGENERICCNV_H 1 - -// Include files -#include <string> -#include <functional> - -#include "GaudiKernel/Converter.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -#include "DetCond/ICondDBReader.h" - -#include "CoolKernel/types.h" - -// Forward and external declarations -class ISvcLocator; -class IDetDataSvc; -class DataObject; - -template <class TYPE> class CnvFactory; - -/** @class CondDBGenericCnv CondDBGenericCnv.h DetCond/CondDBGenericCnv.h - * - * Generic converter for the CondDBCnvSvc. This generic converter - * provides common functions to access the CondDB in order to make it - * easier to write specific converters. - * - * @author Marco CLEMENCIC - * @date December 2004 - */ -class CondDBGenericCnv: public Converter { -public: - /** - * Initializes the converter. - * Here the pointers to common services are taken: - * <ul> - * <li> CondDBCnvSvc - * <li> DetectorDataSvc - * </ul> - * @return status depending on the completion of the call - */ - virtual StatusCode initialize(); - - /** - * Finalizes the converter. - * It releases the pointers to the taken services. - * @return status depending on the completion of the call - */ - virtual StatusCode finalize(); - - /** - * Accessor to the StorageType value - * @return the storage type for this object - */ - static long storageType() { - return CONDDB_StorageType; - } - - /** - * Accessor to the StorageType value - * @return the storage type for this object - */ - virtual long repSvcType() const { - return CONDDB_StorageType; - } - -protected: - - /// Standard constructor - CondDBGenericCnv(ISvcLocator* svc,const CLID& clid); - - virtual ~CondDBGenericCnv( ); ///< Destructor - - /** - * Ask to the DetectorDataSvc the curren event time. - * @return StatusCode::SUCCESS if the event time was defined. - */ - StatusCode eventTime(Gaudi::Time &time) const; - - /** - * Set the validity of the DataObject if it inherits from IValidity. - */ - void setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject); - - /// Pointer to the DetectorDataService. - SmartIF<IDetDataSvc> m_detDataSvc; - /// Pointer to the ICondDBReader interface; - SmartIF<ICondDBReader> m_condDBReader; - - /** - * Get an object from the Conditions DB. It tries all the CondDBReaders - * known by CondDBCnvSvc before returing a failure code. - * @param[in] path the path inside the CondDB - * @param[in] channel CondDB channel id - * @param[out] obj shared pointer to the COOL object - * @param[out] descr folder description string (used to know the storage type by RelyConverter) - * @param[out] since start of the IOV - * @param[out] until end of the IOV - * The IOV is inside the object itself as two cool::ValidityKey, the since and until are - * used to avoid the conversion outside this method.<BR> - * If the path point to a FolderSet, channel is ignored and the boost::shared_ptr obj is - * set to NULL. - */ - StatusCode getObject(const std::string &path, const cool::ChannelId &channel, - ICondDBReader::DataPtr &obj, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until); - - /// Method kept for backward compatibility - inline StatusCode getObject(const std::string &path, - ICondDBReader::DataPtr &obj, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until) - { - return getObject(path,0,obj,descr,since,until); - } - - /// Find the children nodes of a given FolderSet path. - /// When using multiple databases, only the first one which contains - /// this folderset is used, so it must have at least dummy entries for each sub-node - /// (to be changed in the future). - StatusCode getChildNodes(const std::string &path,std::vector<std::string> &node_names); - -private: - -}; -#endif // DETCOND_CONDDBGENERICCNV_H diff --git a/Det/DetCond/DetCond/ICOOLConfSvc.h b/Det/DetCond/DetCond/ICOOLConfSvc.h deleted file mode 100755 index 5636805cf..000000000 --- a/Det/DetCond/DetCond/ICOOLConfSvc.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef DETCOND_ICOOLCONFSVC_H -#define DETCOND_ICOOLCONFSVC_H 1 - -// Include files -#include <GaudiKernel/IInterface.h> - -// Forward declarations -namespace coral { - class IConnectionService; -} -namespace cool { - class IDatabaseSvc; -} - -/** @class ICOOLConfSvc ICOOLConfSvc.h DetCond/ICOOLConfSvc.h - * - * Class used as interface to instantiate a COOL application and configure it - * (and CORAL). - * - * @author Marco CLEMENCIC - * @date 2007-12-07 - */ -class ICOOLConfSvc : virtual public IInterface { -public: - /// InterfaceID - DeclareInterfaceID(ICOOLConfSvc, 3, 0); - - /// Access to the CORAL connection service used by COOL (if needed). - virtual coral::IConnectionService& connectionSvc() = 0; - - /// Get the COOL Database service (used to connect to the databases). - virtual cool::IDatabaseSvc& databaseSvc() = 0; - -}; - -#endif // DETCOND_ICOOLCONFSVC_H diff --git a/Det/DetCond/DetCond/ICondDBAccessSvc.h b/Det/DetCond/DetCond/ICondDBAccessSvc.h deleted file mode 100755 index 85ae8d611..000000000 --- a/Det/DetCond/DetCond/ICondDBAccessSvc.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef DETCOND_ICONDDBACCESSSVC_H -#define DETCOND_ICONDDBACCESSSVC_H 1 - -// Include files -// from STL -#include <string> -#include <vector> -#include <set> -#include <map> - -// from Gaudi -#include <GaudiKernel/IInterface.h> - -// from COOL -#include "CoolKernel/types.h" -#include "CoolKernel/ChannelId.h" -#include "CoolKernel/pointers.h" -#include "CoolKernel/ValidityKey.h" - -// Forward declarations -namespace Gaudi { - class Time; -} -namespace cool { - class IRecord; - class IRecordSpecification; -} - -/** @class ICondDBAccessSvc ICondDBAccessSvc.h DetCond/ICondDBAccessSvc.h - * - * Class used as interface to LCG COOL library API. It should expose as less as - * possible COOL internal details. - * - * CondDBAccessSvc can be operated with only an in-memory CondDB, setting both the options NoBD and useCache to true. The memory - * database can be populated using cacheAddFolder and cacheAddObject (or their XML counter parts). The CondDB folders of the - * memory db are equivalent to COOL single-version folders (see COOL documentation for details). - * - * @author Marco CLEMENCIC - * @date 2005-01-11 - */ -class ICondDBAccessSvc : virtual public IInterface { -public: - /// InterfaceID - DeclareInterfaceID(ICondDBAccessSvc, 2, 0); - - /// Used to obtain direct access to the database. - virtual cool::IDatabasePtr& database() = 0; - - /// Convert from Gaudi::Time class to cool::ValidityKey. - virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const = 0; - - /// Convert from cool::ValidityKey to Gaudi::Time class. - virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const = 0; - - /// Return the currently set TAG to use. - virtual const std::string &tag() const = 0; - - /// Set the TAG to use. - virtual StatusCode setTag(const std::string &_tag) = 0; - - /// Return the connection string used to connect to the database. - virtual const std::string &connectionString() const = 0; - - /// Add a folder to the cache (bypass the DB) - virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec) = 0; - - /// Add a folder-set to the cache (bypass the DB) - virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr) = 0; - - /// Add an XML folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path) = 0; - - /// Add an XML folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) = 0; - - /// Add an object to the cache (bypass the DB) - virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const cool::IRecord &payload, cool::ChannelId channel = 0) = 0; - - /// Deprecated: use ICondDBAccessSvc::cacheAddXMLData instead - inline StatusCode cacheAddXMLObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string &data, cool::ChannelId channel = 0) - { - return cacheAddXMLData(path, since, until, data, channel); - } - - - /// Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string &data, cool::ChannelId channel = 0) = 0; - - /// Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::map<std::string,std::string> &data, cool::ChannelId channel = 0) = 0; - - /// Clear the cache - virtual void clearCache() = 0; - - /// Dump the cache (debug) - virtual void dumpCache() const = 0; - -protected: - -private: - -}; -#endif // DETCOND_ICONDDBACCESSSVC_H diff --git a/Det/DetCond/DetCond/ICondDBEditor.h b/Det/DetCond/DetCond/ICondDBEditor.h deleted file mode 100755 index 0edce1b8b..000000000 --- a/Det/DetCond/DetCond/ICondDBEditor.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef DETCOND_ICONDDBEDITOR_H -#define DETCOND_ICONDDBEDITOR_H 1 - -// Include files -// from STL -#include <string> -#include <map> -#include <set> - -// from Gaudi -#include "GaudiKernel/IInterface.h" - -// from COOL -#include "CoolKernel/types.h" -#include "CoolKernel/ChannelId.h" - -/** @class ICondDBEditor ICondDBEditor.h DetCond/ICondDBEditor.h - * - * - * @author Marco CLEMENCIC - * @date 2006-07-10 - */ -class ICondDBEditor : virtual public IInterface { -public: - /// InterfaceID - DeclareInterfaceID(ICondDBEditor, 2, 0); - - /// Possible recognized node types. - enum StorageType { FOLDERSET, XML, Native }; - /// Known types of leaf nodes (aka Folders). - enum VersionMode { SINGLE, MULTI }; - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - StorageType storage = XML, - VersionMode vers = MULTI) const = 0; - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - const std::set<std::string> &fields, - StorageType storage = XML, - VersionMode vers = MULTI) const = 0; - - /// Deprecated: use ICondDBEditor::storeXMLData instead. - inline StatusCode storeXMLString(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const - { - return storeXMLData(path, data, since, until, channel); - } - - /// Utility function that simplifies the storage of an XML string. - virtual StatusCode storeXMLData(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; - - /// Utility function that simplifies the storage of a set of XML strings. - virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; - - /// Tag the given leaf node with the given tag-name. - virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, - const std::string &description = "") = 0; - - /// Tag the given middle node with the given tag-name, recursively tagging the head - /// of child nodes with automatically generated tag-names. - virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, - const std::string &description = "") = 0; - -protected: - -private: - -}; -#endif // DETCOND_ICONDDBEDITOR_H diff --git a/Det/DetCond/DetCond/ICondDBReader.h b/Det/DetCond/DetCond/ICondDBReader.h deleted file mode 100755 index 0131d2e01..000000000 --- a/Det/DetCond/DetCond/ICondDBReader.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef DETCOND_ICONDDBREADER_H -#define DETCOND_ICONDDBREADER_H 1 - -// Include files -// from STL -#include <string> - -// from Gaudi -#include "GaudiKernel/IInterface.h" -#include "GaudiKernel/Time.h" - -// from LHCb -#include "Kernel/ICondDBInfo.h" - -// from COOL -#include "CoolKernel/types.h" -#include "CoolKernel/pointers.h" -#include "CoolKernel/ChannelId.h" - -// Forward declarations -namespace cool { - class IRecord; -} - -/** @class ICondDBReader ICondDBReader.h DetCond/ICondDBReader.h - * - * Interface to retrieve data from the conditions database. - * - * @author Marco Clemencic - * @date 2006-07-10 - */ -class ICondDBReader : virtual public ICondDBInfo { -public: - /// InterfaceID - DeclareInterfaceID(ICondDBReader, 2, 1); - - /// virtual destructor - virtual ~ICondDBReader() {} - -#ifdef COOL_HAS_CPP11 - typedef std::shared_ptr<const cool::IRecord> DataPtr; -#else - typedef boost::shared_ptr<const cool::IRecord> DataPtr; -#endif - - /// Helper class to easily manage an interval of validity as a pair of Gaudi::Time - /// instances. - struct IOV { - /// Constructor - IOV(Gaudi::Time _since = Gaudi::Time::epoch(), - Gaudi::Time _until = Gaudi::Time::max()): - since(_since), until(_until) - {} - /// Boundaries of the interval. - Gaudi::Time since, until; - /// Define a simple order between two IOV instances. - inline bool operator<(const IOV& rhs) const { - return since < rhs.since; - } - }; - - /// List of IOV instances. - typedef std::vector<IOV> IOVList; - - /// Retrieve data from the condition database. - /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0) = 0; - - /// Retrieve data from the condition database. - /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. - /// (Version with alphanumeric channel id) - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) = 0; - - /// @{ - /// Return the list of occupied IOVs in the given path and channel, for the given IOV. - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0) = 0; - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel) = 0; - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names) = 0; - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) = 0; - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path) = 0; - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path) = 0; - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path) = 0; - - /// Disconnect from the database. - virtual void disconnect() = 0; - -protected: - -private: - -}; - -#endif // DETCOND_ICONDDBREADER_H diff --git a/Det/DetCond/cmt/requirements b/Det/DetCond/cmt/requirements deleted file mode 100755 index 2770d40a8..000000000 --- a/Det/DetCond/cmt/requirements +++ /dev/null @@ -1,79 +0,0 @@ -# ==================================================================== -package DetCond -version v12r47 - -# =========== structure =================================================== -branches DetCond doc cmt src - -# =========== dependencies ================================================ -use GaudiKernel v* -use GaudiAlg v* -use COOL v* LCG_Interfaces -use CORAL v* LCG_Interfaces -use Boost v* LCG_Interfaces -use DetDesc v* Det - -# This one is for the interface ICondDBInfo and IDQScanner -use LHCbKernel v* Kernel - -macro_append Boost_linkopts " $(Boost_linkopts_system) " - - -# =========== own includes ================================================ -apply_pattern install_more_includes more=DetCond - -#===================================================================== -# Needed to resolve external symbols -apply_tag NEEDS_COOL_FACTORY -apply_tag NEEDS_CORAL_RELATIONAL_ACCESS -# Work-around for a problem in COOL/CORAL requirements files (after fix to bug #41579) -macro CORAL_linkopts ' $(CORAL_libs) $(CORAL_relacc_libs) ' - -# =============== LCG Dictionary =========================================== -apply_pattern reflex_dictionary \ - dictionary=DetCond \ - headerfiles=$(DETCONDROOT)/src/dict/DetCondDict.h \ - selectionfile=$(DETCONDROOT)/src/dict/DetCondDict.xml \ - options="-U__MINGW32__" -# Disable some compiler warnings in the automatically generated dict code -macro_append DetCondDict_cppflags "" \ - target-icc " -wd2259" - -# =========== constituents ================================================= -library DetCondLib Lib/*.cpp -library DetCond component/*.cpp ../tests/src/*.cpp - -# =========== standard patterns (the order is essential!) ====================== -apply_pattern component_library library=DetCond -apply_pattern linker_library library=DetCondLib - -private -# DetCond Configurable uses the generated configurables -macro_append DetCondGenConfUser_dependencies DetCondConfDbMerge -# Have to look in local DetCondConf.py, install_python has to come later -path_prepend PYTHONPATH ${DETCONDROOT}/genConf -end_private -apply_pattern install_python_modules - -# ==================================================================== -private - -macro_append DetCond_use_linkopts " $(Boost_linkopts_thread) $(Boost_linkopts_filesystem_mt) $(Boost_linkopts_date_time) " - -apply_pattern QMTest -# ===================================== -# Packages needed for tests -macro DetCond_use_CondDBUI "" QMTest "CondDBUI v* Tools" -use $(DetCond_use_CondDBUI) - -macro DetCond_use_DDDB "" QMTest "DDDB v* Det" -use $(DetCond_use_DDDB) - -macro DetCond_use_DetDescSvc "" QMTest "DetDescSvc v* Det" -use $(DetCond_use_DetDescSvc) - -macro DetCond_use_DetDescCnv "" QMTest "DetDescCnv v* Det" -use $(DetCond_use_DetDescCnv) -# ===================================== - -end_private diff --git a/Det/DetCond/doc/release.notes b/Det/DetCond/doc/release.notes deleted file mode 100755 index 71d560ebc..000000000 --- a/Det/DetCond/doc/release.notes +++ /dev/null @@ -1,1247 +0,0 @@ -!----------------------------------------------------------------------------- -! Package : Det/DetCond -! Responsible : Marco Clemencic -! Purpose : Interface between LHCb and LGC/COOL project -!----------------------------------------------------------------------------- - -! 2016-03-31 - Roel Aaij - - Fix CondDB configuration. The online snapshots were configured even if - UseDBSnapshot was set to True. - -!========================= DetCond v12r47 2016-03-18 ========================= -! 2016-03-18 - Roel Aaij - - Remove configuration of environment variables meant to setup access to the - LHCb online oracle instance. This should be done online as part of the - environment. - -!========================= DetCond v12r46 2016-01-27 ========================= -! 2016-01-06 - Gerhard Raven - - prefer SmartIF over raw pointer to interface - -! 2015-12-17 - Christopher Burr - - Prevent CondDBCache from logging " FOUND" as a warning - -!========================= DetCond v12r45 2015-11-23 ========================= -! 2015-11-02 - Gerhard Raven - - pass sink arguments by value, and std::move them - - replace deprecated std::auto_ptr with std::unique_ptr - - prefer range-based for loops - - prefer emplace_back over push_back - -!========================= DetCond v12r44 2015-10-12 ========================= -! 2015-09-25 - Liang Sun - - Remove references to SQLDDDB*.py option files - - If UseOracle & Online options are both set to True, the Oracle ONLINE db is used, instead of sqlite db files - -! 2015-08-03 - Gerhard Raven - - remove #include of obsolete Gaudi headers - -!========================= DetCond v12r43 2015-07-20 ========================= -! 2015-06-30 - Marco Clemencic - - Fixed LHCBPS-1425: ensure that the "InitialTime" is stable. - -! 2015-06-25 - Eduardo Rodrigues - - Undid the reference update from yesterday as the difference is in fact - *not* expected nor understood, see https://its.cern.ch/jira/browse/LHCBPS-1425. - -! 2015-06-24 - Eduardo Rodrigues - - Updated expected reference block for test force_disconnect. - -!========================= DetCond v12r42 2015-06-17 ========================= -! 2015-06-16 - Marco Clemencic - - LHCBPS-1421: Modified RunStampCheck to instantiate EventClockSvc. - To ensure that it does get a "current event time", RunStampCheck triggers - the instantiation of EventClockSvc, so that it is not needed to explicitly - do it in the configuration. - -! 2015-06-16 - Marco Clemencic - - LHCBPS-1421: Updated CondDB configurable to enable/disable RunStampCheck - The RunStampCheck is enabled by default for "Offline" (i.e. not Online - nor Simulation). - -! 2015-06-11 - Marco Clemencic - - LHCBPS-1421: added a first implementation of RunStampCheck - The optional service RunStampCheck can be instantiated (via - ApplicationManager::ExtSvc) to check if a special "run stamp" - condition exist for the current run. - -! 2015-06-05 - Liang Sun - - Set LoadCALIBDB default value to HLT1 for Simulation option - -! 2015-06-05 - Liang Sun - - Set LoadCALIBDB default value to HLT1 for Online and Upgrade options - - Change in detcond.configuration_module to avoid checking layered ONLINE partition - -! 2015-06-04 - Liang Sun - - Finalized support for CALIBOFF by loading the partition as an additional layer only above every ONLINE snapshot no earlier than 2015 - - Bug fix for mistakenly loading CALIBOFF for upgrade CondDB - -!========================= DetCond v12r41 2015-04-20 ========================= -! 2015-04-16 - Liang Sun - - Further support for loading CALIBOFF.db file as an additional layer above all partitions, for testing purpose only - -! 2015-03-18 - Liang Sun - - Fix the nightlies after the last commit. The XML extensions of the condition files within TESTDB?.db are now removed. - -! 2015-03-12 - Marco Clemencic - - Changed the policy of CondDB::generateXMLCatalog to exclude folders with - names ending with ".xml" from the generated catalog. - This is required to allow mixed content in the Online CondDB partition for - the split Hlt, where the files with ".xml" are not meant to be automatically - mapped. - -!========================= DetCond v12r40p1 2015-01-14 ========================= -! 2015-01-07 - Marco Cattaneo - - Fix gcc49 unused function warning in DQScanTest.cpp - -!========================= DetCond v12r40 2014-12-11 ========================= -! 2014-12-03 - Liang Sun - - In Configuration.py: Fixing the cases without valid DQFLAGS tags - -! 2014-12-02 - Liang Sun - - In Configuration.py: Adding option LatestGlobalTagByDataTypes to allow for multiple datatypes. - - In Configuration.py: Inclusion of DQFLAGS to assign the most recent tag for a given datatype - -!========================= DetCond v12r39 2014-10-14 ========================= -! 2014-10-07 - Gerhard Raven - - DetCond configurable: remove explicit paritition name and defer this to the - keys (i.e. filename) in the RunChangeHandlerCondiions map. - -!========================= DetCond v12r38 2014-09-30 ========================= -! 2014-09-30 - Gerhard Raven - - DetCond configurable: combine the RunChangeHandlerConditions and XMLFilename - properties into a single dictioary of filename -> list of conditions so that - the RunChangeHandler can be configured to use multiple <subsystem>_<runnr>.xml - files. - - avoid a spurios warning about ONLINE tag - -!========================= DetCond v12r37 2014-09-08 ========================= -! 2014-09-02 - Liang Sun - - In Configuration.py: Keep the lines related to the import of SQLDDDB-Oracle.py for the UseOracle option, in order not to fail the nightlies - -! 2014-09-01 - Liang Sun - - Changes in Configuration.py: - - Removal of the support for Oracle by commenting out the lines related to the option "UseOracle" - - Added a layer of CALIBOFF above LHCBCOND when LoadCALIBDB option is OFFLINE - -! 2014-07-24 - Liang Sun - - Added qmtest module "detcond.check_db_reading" to check the db reading functionality in Tools/CondDBUI - - -!========================= DetCond v12r36 2014-05-12 ========================= -! 2014-05-05 - Gerhard Raven - - do not truncate partitionname - -!========================= DetCond v12r35 2014-04-29 ========================= - -!========================= DetCond v12r34 2014-04-29 ========================= - -! 2014-04-28 - Gerhard Raven - - make the conditions which the RunChangeHanderSvc updates a property - - make the (last part of the) filename used by the RunChangeHandlerSvc a property - -! 2014-03-26 - Liang Sun - - CondDB preparation for 2015 in Configuration.py: new CondDB partitions 'CALIB' - and 'CALIBOFF' as additional layers above 'ONLINE' partition. New options for - 'LoadCALIBDB' to enable/disable loading the new layers. The default option is - to add the new layers from $SQLITEDBPATH/CALIB-[YEAR].db and $SQLITEDBPATH/CALIBOFF.db - files automatically if exist. - -!========================= DetCond v12r33 2014-02-17 ========================= -! 2013-12-05 - Marco Clemencic - - Fixed the use of boost::shared_ptr according to the macro COOL_HAS_CPP11 (the - one used in COOL headers). - -! 2013-12-05 - Marco Clemencic - - Do not explicitly use boost::shared_ptr. - See https://sft.its.cern.ch/jira/browse/ROOT-5806 - -! 2013-07-18 - Marco Clemencic - - Minor change. - -!========================= DetCond v12r32 2013-07-17 ========================= -! 2013-06-12 - Marco Cattaneo - - Add virtual destructor to ICondDBReader interface class. Fixes gcc48 warning - virtual-move-assign, see explanation in https://sft.its.cern.ch/jira/CFHEP-87 - -!========================= DetCond v12r31 2013-06-03 ========================= -! 2013-05-07 - Marco Clemencic - - Moved the class CondDBCompression to Tools/CondDBEntityResolver, including - dictionary and tests. - -! 2013-05-02 - Liang Sun - - Removed one defunct line to please Coverity. Added in GaudiException() to handle LZMA errors - -!========================= DetCond v12r30 2013-04-29 ========================= -! 2013-04-26 - Liang Sun - - Removed all references to BZip2. We still need 32Bit machines - -! 2013-04-26 - Marco Clemencic - - Removed the temporary hack used for C++11 (it was needed only because Boost - was not yet built with C++11 enabled). - -! 2013-04-25 - Marco Clemencic - - Fixed an issue with the previous change (the environment variable expansion - was prevented in too many places). - -! 2013-04-24 - Illya Shapoval - - A bug fix: an expansion of the SQLITEUPGRADEDBPATH env. variable is prevented. - -! 2013-04-18 - Liang Sun - - Two redundant variables removed to quell the warning messages. - -! 2013-04-17 - Liang Sun - - Added the compression method of LZMA from ROOT with the assigned method number at 0, the method number for BZip2 now changed to 1. - -! 2013-04-02 - Marco Cattaneo - - Fix UNINIT_CTOR defects - -! 2013-03-21 - Liang Sun - - Minor fix on a few potential memory leaks - - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45083&defectInstanceId=156348385&fileInstanceId=111518946 - - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45084&defectInstanceId=156348386&fileInstanceId=111518946 - -! 2013-03-18 - Vanya Belyaev - - - comment usage of python module from removed package HistoStrings - -! 2013-03-12 - Marco Clemencic - - Added hints to Coverity to fix a few flas positives: - - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45071&defectInstanceId=156278261&fileInstanceId=111423297 - - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45070&defectInstanceId=156277446&fileInstanceId=111423297 - - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45069&defectInstanceId=156277445&fileInstanceId=111423297 - -! 2013-03-12 - Liang Sun - - Minor fix on coverity defects (0&i++) - -! 2013-03-11 - Liang Sun - - Set up prototype to allow multiple compression methods, with an additional byte identifying the method prepended to the compressed string - -! 2013-03-08 - Marco Clemencic - - Fixed compilation on 32 bits with a hack (the 32 bits dev version of bz2 - cannot be installed on lxbuild because of missing templates). - -! 2013-02-27 - Liang Sun - - Fix the type conversions to quell the -pedantic warnings - -! 2013-02-23 - Marco Clemencic - - Forgot to add -lbz2 after removing the 'use' statement. - -! 2013-02-22 - Marco Clemencic - - Added use of BZip2 in CMakeLists.txt and removed the use of LCG_Interfaces/bz2lib - from the requirements (we must pick up the system version because the one in - lcg/externals is obsolete and deprecated). - -! 2013-02-21 - Liang Sun - - Added functionalities of compression and decompression on CondDB with new class CondDBCompression - -!========================= DetCond v12r29 2013-02-04 ========================= -! 2012-12-20 - Marco Clemencic - - Stop the TimeOutChecker thread when explicitly disconnected. The thread is - restarted automatically when we reconnect. - -!========================= DetCond v12r28 2012-11-26 ========================= -! 2012-11-21 - Marco Clemencic - - Modified the ICondDBReader interface to allow explicit disconnection from - databases (useful after a fork). - -! 2012-11-15 - Marco Clemencic - - Added CMake configuration file. - -!========================= DetCond v12r27 2012-09-28 ========================= -! 2012-09-26 - Marco Clemencic - - Removed comments from __init__.py - -! 2012-09-21 - Marco Clemencic - - Temporary hack to compile with -std=c++11 (-std=c++0x). - -! 2012-08-09 - Marco Clemencic - - Workaround for bug #96673. - -! 2012-08-08 - Marco Clemencic - - Added python/DetCond/__init__.py. - -!========================= DetCond v12r26 2012-07-24 ========================= -! 2012-07-10 - Patrick Koppenburg - - Bug: https://savannah.cern.ch/bugs/?94454 - . Allow _configureDBSnapshot to work without UseOracle = True statement - . Remove MagneticFieldSvc().UseSetCurrent = True that should be set - in the application's configuration. - -!========================= DetCond v12r25 2012-06-25 ========================= -! 2012-06-12 - Illya Shapoval - - Configuration.py: - + new property is added. "CondDB().Upgrade = True" will switch the CondDB - machinery to talk to the Upgrade database. - + three new properties are added: - CondDB().LatestGlobalTagByDataType = "DataType0" - CondDB().LatestLocalTagsbyDataType = ["DataType1","DataType2",...] - CondDB().AllLocalTagsbyDataType = ["DataType1","DataType2",...] - Setting this will launch the SAX machinery to fetch and set the latest - global tags, latest locals tags, and all local tags, respectively, marked - with requested DataType(s). This is an extension to the previous configuration - machinery (CondDB().UseLatestTags = ["DataType"]) which is still supported. - -!========================= DetCond v12r24 2012-05-02 ========================= -! 2012-04-26 - Patrick Koppenburg - - Configuration: add properties allowing to configure from online_RunNumber.xml - snapshots. For Online Brunel. This is stolen from Moore. - -!========================= DetCond v12r23 2012-02-01 ========================= -! 2012-02-01 - Marco Clemencic - - Modified DQScanTest to work around a small problem in the configuration on - 32 bits builds. - -! 2012-01-31 - Marco Clemencic - - Implemented CondDBDQScanner: a tool to collect (merge) the DQ flags from the - Conditions Database in a given IOV. - - Added a test to validate the output of CondDBDQScanner. - -! 2012-01-31 - Marco Clemencic - - Fixed a couple of compilation warnings. - -! 2012-01-30 - Marco Clemencic - - Added new methods to the ICondDBReader interface (getIOVs), to retrieve the - list of IOVs in a folder for an IOV. - - Added a test for the implementation of getIOVs in CondDBAccessSvc, and fixes. - -! 2012-01-06 - Marco Clemencic - - Modified LoadDDDB to trigger the initialization of the UpdateManagerSvc in - the initialize (to avoid that is gets triggered in the middle of an event). - -! 2012-01-05 - Marco Clemencic - - Fixed ICC warning (Boost 1.48). - -!========================= DetCond v12r22 2011-12-14 ========================= -! 2011-12-09 - Marco Cattaneo - - Add explicit Boost_linkopts for compatibility with Gaudi v23 - -!========================= DetCond v12r21 2011-08-30 ========================= -! 2011-08-26 - Alexander Mazurov - - Update of parser function in CondDBTimeSwitchSvc. This version works only with - Gaudi version > v22r2 (where the new parser model is provided) - -!========================= DetCond v12r20 2011-07-25 ========================= -! 2011-07-20 - Marco Cattaneo - - Create MSG::VERBOSE and MSG::DEBUG messages only when output level requires - it, also using UNLIKELY macro - -!========================= DetCond v12r19 2011-06-14 ========================= -! 2011-06-06 - Illya Shapoval - - Another minor add-on for the 'UseLatestTags' warning output case. - -! 2011-06-03 - Illya Shapoval - - Added a missing configuration bit for the case of per-year-made ONLINE - snapshots: if per-year scheme is met 'CondDBAccessSvc' services are also - created per-year (before they were created per-month but pointing to a single - per-year ONLINE snapshot). SQLDDDB needs a minor change to enable this - configuration change. - - Warnings about latest tags usage are made more meaningful. - -!========================= DetCond v12r18 2011-04-04 ========================= - **** requires LHCbKernel > v12r8 **** -! 2011-03-31 - Marco Clemencic - - Modified the interfaces to use the pattern of Gaudi v21. - - Fixed a few Eclipse warnings. - - Removed CVS keywords. - - Added the possibility to fetch condition for a range of times instead of - only for the current event time. The CondDBAccessSvc property QueryGranularity - can be used to define the width of the time range (around the event time) to - use. The boundaries are rounded so that the requested range is stable. For - example, with a granularity of one hour, the event times 19:10:00, 19:23:15, - 19:56:10 will all fetch the same range 19:00:00-20:00:00. - The set the QueryGranularity property in a standard configuration: - - import GaudiKernel.SystemOfUnits as Units - Units.hours = Units.s * 3600 - - from Configurables import CondDB - CondDB(QueryGranularity = 2 * Units.hours) - -! 2011-03-28 - Marco Clemencic - - Added a test to expose bug #80076 (wrong condition used on first event). - -!========================= DetCond v12r17 2011-01-31 ========================= -! 2011-01-28 - Illya Shapoval - - Configuration machinery is upgraded to load DQFLAGS partition (implemeted in - standalone SQLite file in SQLDDDB) to populate '/Conditions/DQ/Flags' - condition of LHCBCOND partition. SIMCOND has a placeholder for this condition - too but remains empty (there is no need in DQ flags in simulations). - -! 2011-01-10 - Marco Cattaneo - - Fix icc warnings and remarks - -!========================= DetCond v12r16 2010-10-28 ========================= - -! 2010-10-28 - Marco Clemencic - - Fixed a 32bit compilation problem in some new test code. - -! 2010-10-25 - Marco Clemencic - - Added a test to expose bug #74255 - (fake event loop during finalize doesn't work). - -! 2010-10-17 - Illya Shapoval - - CondDBAccessSvc method getChildNodes is modified to load only those Online - folders in SIMCOND which are tagged with a tag being set to load db. - Modification is done in a binary backwards compatible way. - -!===================== Det/DetCond v12r15 2010-09-28 ========================= -! 2010-09-28 - Marco Clemencic - - Updated tests to expect the return codes of Gaudi (v21r11). - -! 2010-09-24 - Marco Clemencic - - Added a test to verify that a failure to load a condition in the - UpdateManagerSvc is properly reported. - -!===================== Det/DetCond v12r14 2010-08-25 ========================= -! 2010-08-06 - Marco Clemencic - - Improved DetCondTest::TestConditionAlg to allow testing artificial - dependencies between conditions. - - Modified test detcond.heart_beat to expose bug #66497 (velo motor positions - updated several times). - -!===================== Det/DetCond v12r13 2010-05-21 ========================= -! 2010-05-18 - Marco Clemencic - - Fixed few Windows warnings. - -! 2010-05-12 - Marco Clemencic - - Modified the message printed in case of a failure of the heart-beat check to - show the time in human-readable format (UTC). - -!===================== Det/DetCond v12r12 2010-04-09 ========================= -! 2010-03-27 - Illya Shapoval - - CondDB configurable is tuned to override all default and user tags settings - by the latest tags for defined DataType if the 'UseLatestTags' property is - set (before an exception was thrown if found multiple definitions). - -! 2010-03-26 - Illya Shapoval - - Added new CondDB().UseLatestTags = [DataType,OnlyGlobalTags=False] property. - Previous CondDB().useLatestTags(DataType,OnlyGlobalTags=False) method is - preserved. Now it is possible to set the latest tags also for the simulation - case. - -!===================== Det/DetCond v12r11 2010-03-17 ========================= -! 2010-03-17 - Marco Clemencic - - Changes to the CondDB configurable - - in the online environment (Online == True) the IgnoreHeartBeat property is - defaulted to True - - added the property HeartBeatCondition to set the location of the heart-beat - condition - -! 2010-03-05 - Marco Clemencic - - Fixed a problem in the CondDB configurable for the usage of Oracle in the - PIT. - -! 2010-02-25 - Marco Clemencic - - Removed the dependency on rx (obsolete). - -!===================== Det/DetCond v12r10 2010-02-12 ========================= -! 2010-02-12 - Illya Shapoval - - Minor change to the CondDB.useLatestTags(DataType) function. Added the - mode for it to find and set only the latest global tag for a - particular DataType, dropping the latest local tags on top of it. - New syntax: CondDB.useLatestTags(DataType,OnlyGlobalTags = False). - -! 2010-02-05 - Marco Clemencic - - Added the function CondDB.useLatestTags(DataType) to automatically select - the latest local and global tags for a given data type from the SQLDDDB - release notes. - -!===================== Det/DetCond v12r9 2010-01-20 ========================== -! 2010-01-19 - Marco Clemencic - - Fixes to the first implementation of task #13270. - - Handle properly cool and coral exceptions when retrieving the heart beat - condition to be able to issue a meaningful error. - - Modified the automatic setting of the HeartBeatCondition property for the - readers of CondDBTimeSwitchSvc. The property is added only to the last - reader because the other readers are (by construction) accessing limited - partitions. - -! 2010-01-12 - Marco Clemencic - - Completed task #13270: Block access to conditions in ONLINE partition if - validity interval is not closed - - Modified CondDBAccessSvc to accept a new property (HeartBeatCondition). The - property specified the path in the database to be used as heart beat, i.e. - the partition is considered not up-to-date if the latest update of that - condition is less recent than the event time being processed. - Since the test is done only when actually accessing the CondDBAccessSvc, - to ensure that we get there when the event exceeds the validity of the - database, the returned validities are artificially cut at the latest heart - beat. - - Modified the ConfigurableUser CondDB to set the HeartBeatCondition for the - Online partition and snapshots (can be disabled with the property - IgnoreHeartBeat). - - Removed the OnlineDBValidatorSvc because it is not needed anymore. - - Adapted the TestCondition algorithm to test the new feature and added the - relative test. - NOTE: In the special case when there are conditions with initial validity - after the latest heart beat, there may be problem during the initialize - if exposed validity (artificially cut) is checked (the UpdateManagerSvc - and the DetectorDataSvc are not doing it). - - Added the properties "DisableLFC" and "Online" to the ConfigurableUser CondDB - to be able to ignore the LFC when using Oracle and enable special - configuration for the Online environment (Oracle). - -!===================== Det/DetCond v12r8 2009-12-11 ========================== -! 2009-12-11 - Marco Cattaneo - - Remove obsolete file DetCond_dll.cpp - -! 2009-12-05 - Dmitry GOLUBKOV - - python/DetCond/HistoCond.py: new python module to decorate the Condition - object with functions which extract the histograms from the parameters and to - define functions which convert histograms to Condition parameter xml strings. - - cmt/requirements: version increment to v12r8 - -!===================== Det/DetCond v12r7 2009-06-16 ========================== -! 2009-06-03 - Marco Clemencic - - Changes in the CondDB ConfigurableUser: - - Fixed a bug causing a failure when using SQLite local copies and - CondDBTimeSwitchSvc. - - Changed the policy when both UseOracle and SQLiteLocalCopiesDir are active: - issue a warning and ignores SQLiteLocalCopiesDir instead of raising an - exception. - -!===================== Det/DetCond v12r6 2009-05-28 ========================== -! 2009-04-28 - Marco Cattaneo - - In Configurable, do not access MessageSvc() directly, use instead - getConfigurable("MessageSvc"), allow to replace MessageSvc instance online - -! 2009-05-27 - Marco Clemencic - - Modified the way CondDBAccessSvc::finalize() synchronizes with the second - thread. - - Updated the usage of the Boost Thread module (use more recent classes). - - Added a test triggering the connection time-out. - -!===================== Det/DetCond v12r5p3 2009-05-06 ======================== -! 2009-04-17 - Marco Cattaneo - - Replace endreq by endmsg - -!===================== Det/DetCond v12r5p2 2009-03-09 ======================== -! 2009-03-09 - Marco Cattaneo - - Add options/UseOracle.py: additional options for gaudirun.py command line - to get conditions from Oracle DB - -!===================== Det/DetCond v12r5p1 2009-02-18 ======================== -! 2009-01-29 - Marco Cattaneo - - Fix compilation warning from Boost 1.38 - -!===================== Det/DetCond v12r5 2009-01-08 ========================== -! 2009-01-07 - Marco Clemencic - - Improvements to the CondDB configurable: - - added the possibility to use local copies of the SQLite databases (through - CondDBSQLiteCopyAccSvc) - - added the possibility of specifying alternatives and layers with only the - connection string or the SQLite filename - -!===================== Det/DetCond v12r4 2008-11-17 ========================== -! 2008-11-17 - Marco Cattaneo - - Fix to requirements avoid warnings when making configurables database - - Add LoadDDDB algorithm, moved from DetDescChecks to avoid tests dependency - on DetDescChecks package - - Add missing dependencies for QMTest - -! 2008-11-14 - Marco Cattaneo - - In Configurable, set up VFSSvc, e.g. for use by ParticlePropertySvc - -! 2008-11-11 - Marco Clemencic - - Fixed configuration problems in the test after the changes in DDDB. - -! 2008-11-06 - Marco Clemencic - - Added the ConfigurableUser CondDB for the high level configuration of the - conditions database. The old configuration function (addCondDBLayer etc.) are - still available for backward compatibility, but implemented using the new - configurable which allows to specify local tags too. - -! 2008-10-31 - Marco Cattaneo - - Fix for gcc 4.3 - - NEEDS: LCGCMT > 55a - -! 2008-10-10 - Marco Clemencic - - Modified the requirements file following the changes in the CORAL interface - package (see bug #41579). - -!===================== Det/DetCond v12r3 2008-09-30 ========================== -! 2008-09-29 - Marco Clemencic - - Fixed a bug in CondDBCommon::generateXMLCatalog, failing for folders with - names shorter than 4 chars. - -!===================== Det/DetCond v12r2 2008-07-30 ========================== -! 2008-07-30 - Marco Clemencic - - Changed the name of the configurables for online partition from ONLINE-YYYYMM - to ONLINE_YYYYMM. - -! 2008-07-28 - Marco Cattaneo - - Fix windows compilation - -! 2008-07-23 - Marco Clemencic - - Changed the type of CondDBDispatcherSvc.Alternatives from list of strings - to map<string,string>. - - Added tests for DetCond.Configuration. - - Fixed a problem with conversion between 'double' and 'long long' in - CondDBTimeSwitchSvc. - -! 2008-07-21 - Marco Clemencic - - Added a function to DetCond.Configuration (configureOnlineSnapshots) to - prepare the configuration using monthly snapshots of the ONLINE partition. - The first and last snapshot used extend their validity to 0 and +infinity - respectively. - -!===================== Det/DetCond v12r1 2008-07-16 ========================== -! 2008-07-10 - Marco Clemencic - - Fixed a tiny memory leak introduced in COOLConfSvc during the deSEALing. - -!===================== Det/DetCond v12r0 2008-06-30 ========================== -! 2008-07-02 - Marco Clemencic - - Introduced a work-around for COOL bug #38422, which was preventing the usage - of local tags as overlays. - - Removed a left-over in the requirements file needed for some tests. - (It was breaking compilation on win32) - -! 2008-06-27 - Marco Clemencic - - Introduced the ICondDBReader implementation CondDBTimeSwitch. - - it allows to use different partitions for different IOVs - - added a simple test for it (using a test algorithm added to the package: - DetCondTest::TestConditionAlg). - -! 2008-06-26 - Marco Clemencic - - Improved direct mapping between the COOL hierarchy and the transient store - one: - - direct mapping enabled by default (can be turned off via options to improve - the performances of CondDBLayeringSvc and CondDBDispatcherSvc) - - correct mapping in CondDBDispatcherSvc and CondDBLayeringSvc: - - CondDBDispatcherSvc: add entries implied by alternatives - - CondDBLayeringSvc: expose all the possible entries - - modified ICondDBReader (needed for a generic implementation of the mapping) - - added tests for foreseen use-cases - - the code to generate the XML catalog has been moved to a separate file to - be shared among the implementations of ICondDBReader - - Added dictionaries for few CORAL interfaces that are not available through - COOL. - -! 2008-06-24 - Marco Clemencic - - Fixed a bug in the direct mapping between the hierarchy of the COOL - database and the transient store one. - -! 2008-06-10 - Marco Clemencic - - Adapted to the new SEAL-less COOL and CORAL. Needs LCG_55 (Gaudi v20r0) - -!===================== Det/DetCond v11r11 2008-05-19 ========================= -! 2008-05-19 - Marco Clemencic - - Added the possibility of direct mapping between the hierarchy of the COOL - database and the transient store one. - Disabled by default, but needed to use the Online partition of the condition - database. - The implementation still lacks few features: - - does not work if the cache is not enabled - - it is implemented only at the CondDBAccessSvc (it should work at the - CondDBDispatcherSvc and CondDBLayeringSvc level too) - -!===================== Det/DetCond v11r10 2008-04-24 ========================= -! 2008-04-24 - Marco Clemencic - - Improved the algorithm to select the closest replica of the database when - using LFCReplicaSvc. The local site (preferred replica), can be specified, in - order of priority, with job option (of COOLConfSvc), the environment - variables DIRACSITE and LHCBPRODSITE or the hard-coded default "CERN.ch". The - value of local site can be any substring (case insensitive) to be matched in - the "host" field of the CORAL LFC entries. The fall-back servers are used in - random order. - -! 2008-04-22 - Marco Clemencic - - Fixed a problem in CondDBAccessSvc related to the usage of local tags. - -! 2008-04-09 - Marco Clemencic - - Modified default idle connection time-out in CondDBAccessSvc from 600s to - 120s. - -!===================== Det/DetCond v11r9 2008-03-03 ========================== -! 2008-03-03 - Marco Clemencic - - Added the function "useCondDBLogger" to DetCond.Configuration. - - Modified DetCond.Configuration to expose the configurables provided by the - package when imported. - -! 2008-02-29 - Marco Clemencic - - Added the Python module DetCond.Configuration to provide useful functions - for the configuration of the CondDB: - - addCondDBLayer - - addCondDBAlternative - -! 2008-02-22 - Marco Cattaneo - - Remove hacks in requirements no longer needed with Gaudi v19r7 - -! 2008-02-12 - Marco Clemencic - - Fixed a problem occurring when trying to retrieve a folder which is not in - the database (typical case for CondDBLayeringSvc), due to an uninitialized - variable. - -!===================== Det/DetCond v11r8 2008-01-28 ========================== - NEEDS: LCGCMT >= 54 -! 2008-01-26 - Marco Clemencic - - Added the service CondDBLogger (implementation of ICondDBReader) that, if put - between a user and a provider of the ICondDBReader interface, stores in a - file all the requests that were made to the CondDBReader, with the time of - the request. - The class allows to generate some history of the CondDB traffic to be able to - analyze and replay it afterward. - - Added the algorithm CondDBReplayAlg. It can read a file produced with - CondDBLogger to replay the requests to the database. - - Modified ICondDBReader and CondDBAccessSvc to allow the retrieval of objects - from the conditions database using the channel name (available since COOL - 2.3.0, LCGCMT 54). - -! 2008-01-21 - Marco Clemencic - - Improved error messages in case of CORAL exceptions. - -! 2007-12-20 - Marco Clemencic - - Allow to use tags that are not global in CondDBAccessSvc. - - Added a service (COOLConfSvc/ICOOLConfSvc) dedicated to the instantiation and - configuration of COOL/CORAL. The options to configure COOL and CORAL have - been moved from CondDBAccessSvc to the new service. - -! 2007-12-20 - Marco Cattaneo - - Replace homemade linkopts with new Boost_linkopts_filesystem_mt - - Remove slc3 specific set, no longer supported in LCG_54 - -!===================== Det/DetCond v11r7 2007-12-03 ========================== -! 2007-11-29 - Marco Clemencic - - Added two options to CondDBAccessSvc to control the retrial period and - retrial time-out of CORAL. - -!===================== Det/DetCond v11r6 2007-09-04 ========================== -! 2007-08-01 - Marco Clemencic - - Fixed a bug connected to "lazy connection" feature. I was using an instance - of a cool object to call a static member function. - -! 2007-07-31 - Marco Clemencic - - Fixed a bug with the "lazy connection" feature. The thread to disconnect from - the database was started even if we never connect. - Now it is started only at the first connection. - -!===================== Det/DetCond v11r5 2007-07-05 ========================== -! 2007-07-05 - Marco Clemencic - - Added the possibility to connect to the database only when needed (and made - it the default), so a job does not need the database does not need to be - able to connect to it or to be reconfigured. - To restore the old behavior (connection at initialize) use the option: - CondDBAccessSvc.LazyConnect = False; - -!===================== Det/DetCond v11r4 2007-06-15 ========================== - NEEDS: LCGCMT >= 52 -! 2007-06-06 - Marco Clemencic - - Removed the check on macro CORAL_1_8_x (use always the new CORAL feature). - -!===================== Det/DetCond v11r3 2007-05-16 ========================== - NEEDS: LHCbKernel >= v7r3 (ICondDBInfo) - LCGCMT >= 51 (if macro CORAL_1_8_x is set, - for CORAL 1.8.0) - -! 2007-05-16 - Marco Clemencic - - The parts that depend on CORAL 1.8.0 API are now enclosed in #ifdef/#endif - directives, so that DetCond can be compiled with the old version of CORAL. - -! 2007-05-11 - Marco Clemencic - - Extended ICondDBReader with the interface ICondDBInfo from LHCbKernel and - implemented the new function in all the ICondDBReader's (CondDBCnvSvc, - CondDBAccessSvc, CondDBLayeringSvc, CondDBDispatcherSvc). - NOTE: this introduce a dependency on LHCbKernel. - -! 2007-05-03 - Marco Clemencic - - Added service OnlineDBValidatorSvc to check if the Online CondDB replica - is recent enough. (see doxygen documentation) - -! 2007-05-02 - Marco Clemencic - - First implementation of the algorithm to sort DB replicas extracted from - LFC. - -!===================== Det/DetCond v11r2 2007-04-23 ========================== -! 2007-04-20 - Marco Clemencic - - Added ICondDBAccessSvc::connectionString() to be able to find the - connection string that was used without looking in the options. - - Use a static std::auto_ptr instead of a basic pointer and a counter of - instances (for CondDBAccessSvc::s_XMLstorageSpec). - - Added class CondDBSQLiteCopyAccSvc to copy an SQLite file and connect to - the copy. - -!===================== Det/DetCond v11r1 2007-03-22 ========================== -! 2007-03-22 - Marco Clemencic - - Small improvement to the database disconnect message. - -! 2007-03-16 - Marco Clemencic - - Added an option to enable CORAL LFCReplicaService (off by default). - - Added an option to enable CORAL automatic connection purge. - - Added a check on the database in CondDBAccessSvc::i_checkTag to avoid - segmentation possible faults. - - Disable some compiler optimizations in libstdc++ on slc3, because it seems - that on SLC3 there are problems with multithreaded applications. - -!===================== Det/DetCond v11r0 2007-03-05 ========================== - NEEDS LCGCMT >= 50 - -! 2007-03-05 - Marco Cattaneo - - Removed obsolete DetCond_load.cpp file - -! 2007-02-28 - Marco Clemencic - - Removed a work-around for missing library in LCG_Interfaces/COOL - -! 2007-02-22 - Marco Clemencic - - Fixed a bug (segfault) occurring when requiring the time-out task without - a connection (pure memory cache). - - Moved few message from DEBUG to INFO and added few more messages (like - the connection string and the tag used). - - Activated by default the disconnect on time-out feature (with time out set - to 10 min.) - -! 2007-02-19 - Marco Clemencic - - Minor change in RelyConverter.cpp (removed a useless line) - -! 2007-02-14 - Marco CLEMENCIC - - Updated to changes in COOL API - - Added to CondDBAccessSvc a function to clear the cache - -!================ Det/DetCond v10r0 2007-01-31 ============================= -! 2007-01-31 - Marco Cattaneo - - Fix and retag requirements to link on Windows. - -! 2006-12-06 - Florence RANJARD - - apply_pattern install_more_includes - - fixes for new plugins (P.Mato) - -!================= Det/DetCond v9r1 2006-09-04 ============================== -! 2006-09-04 - Marco Clemencic - - Modified the way of specifying one of the element of the condition. Now the - path to a condition in XML is: - - "conddb:/path/to/condition/[attribute@]Folder.xml[:channel][#Name]" - -! 2006-08-31 - Marco Clemencic - - Added the possibility of using one CondDB condition to store more than one - file using elements of the attribute list. - Backward compatible chages in the API (with deprecated functions). - -! 2006-08-31 - Marco Clemencic - - Added the possibility of disconnection from the DB after an inactivity - period defined by CondDBAvvessSvc.ConnectionTimeOut. - (The feature is implemented using Boost.Thread) - -! 2006-08-30 - Marco Clemencic - - Fixed a bug in CondDBDispatcherSvc: the correct alternative database was - never selected - - Fixed a bug in RelyConverter that was causing a segmentation fault if the - retreived XML string didn't start with "<?xml" (it is not a valid XML - string, but it does not justfy a segfault ;) - -!================= Det/DetCond v9r0 2006-07-18 ============================== -! 2006-07-18 - Marco CLEMENCIC - - Added to CondDBAccessSvc the possibility of chosing between read-only and - read-write connections to the database. (default is read-only) - -! 2006-07-17 - Marco CLEMENCIC - - Using Gaudi random generator service instad of the posix one in - CondDBAccessSvc (needed for recursive tagging) - -! 2006-07-14 - Marco CLEMENCIC - - Removed interface ICondDBCnvSvc. Now CondDBCnvSvc is an ICondDBReader and - the layering of databases is delegated to the class CondDBLayeringSvc. - - Removed the obsolete method ICondDBEditor::createFolder - -! 2006-07-12 - Marco CLEMENCIC - - Fixed a small bug in the code for the selection of the alternative in - CondDBDispatcherSvc. - -! 2006-07-11 - Marco CLEMENCIC - *** will be v9r0 *** - - Completely redesigned the support for alternative DBs: - - Reverted to previous implementation of CondDBAccessSvc - - Splitted ICondDBAccessSvc in 3: - 1) ICondDBReader: read only functions - 2) ICondDBEditor: write functions (storeXML, createNode, etc.) - 3) ICondDBAccessSvc: access function (setTag, etc.) - - Added the class CondDBDispatcherSvc as an implementation of ICondDBReader. - This one is selecting the appropriate alternative AccessSvc to use. - The alternative is declared with something like: - CondDBDispatcherSvc.Alternatives += { "/OnLine=CondDBAccessSvc/OnlineAccSvc" }; - The new functionality is not tested, but it is backward compatible even using - CondDBDispatcherSvc with only the default access service (CondDBAccessSvc). - - Dictionary updated to include the 2 new interfaces. - - Removed dependency on PCRE (not needed anymore) - - Documentation still to be updated. - -! 2006-07-07 - Marco CLEMENCIC - - Added the possibility of specifying alternative databases for certain - sub trees to a CondDBAccessSvc. - Now you have a default DB (backward compatible) and you can use a different - COOL DB for all the directories under e.g. "/OnLine", with an option like - CondDBAccessSvc.AlternativeDBs += { "/OnLine=<connectionString>" }; - Note: it still has to be tested, but it is backward compatible. - - Added dependency on PCRE (used to parse the string to specify alternative DB) - -! 2006-06-16 - Marco CLEMENCIC - - Removed some code used for debugging which is not needed. - - Added the possibility to wait that the requested tag appears - (configurable number of trials and time between trials) - -! 2006-06-12 - Marco CLEMENCIC - - Many API changes - - remamed ICondDBAccessSvc::createFolder to ICondDBAccessSvc::createNode - - removed the version of ICondDBAccessSvc::storeXMLString taking two doubles - because it was obsolete and confunding - - replaced ICondDBAccessSvc::tagFolder with the two functions - ICondDBAccessSvc::tagLeafNode and ICondDBAccessSvc::recursiveTag - (the first for Folders, the second for sub-trees) - - removed obsolete properties: HostName, User, Password, HidePassword, - Database, Schema, BackEnd - - property TAG renamed to DefaultTAG - - default value for property UseCache set to true (it was false) - - Enabled tagging functionalities (based on COOL HVS) - -!================= Det/DetCond v8r0 2006-04-25 ============================== -! 2006-04-25 - Marco Clemencic - **** requires LCGCMT_43 **** - - Updated to COOL_1_3_x - -! 2006-04-13 - Marco Clemencic - - Fixed a problem with uninitialized variables just affecting the case of - a FolderSet stored in the CondDB cache. - -!================= Det/DetCond v7r10p1 2006-03-29 ============================ -! 2006-03-29 - Marco Cattaneo - - Trivial fix in requirements for GCCXML+Boost on Windows with LCG_v42a - -!================= Det/DetCond v7r10 2006-03-22 ============================== -! 2006-03-22 - Marco Cattaneo - - Add DetCondDict (to remove dependency on DetCond in DetSys) - -!================= Det/DetCond v7r9 2006-02-03 =============================== -! 2006-02-01 - Marco Clemencic - - Updated to Gaudi v18r2 (use Gaudi::Time instead of ITime+TimePoint) - - Added Boost and SEAL to the dependencies because they are not inherited - from other packages anymore - -! 2006-01-25 - Nicolas Gilardi - - Allow to use a COOL connection string instead of the splitted credentials - - Modified Function CondDBAccessSvc::createFolder() to use large (16M) - strings by default in the CondDB folders. - -! 2006-01-22 - Marco Clemencic + Nicolas Gilardi - - Updated to improved COOL API. - -================= Det/DetCond v7r8 2006-01-20 ================================ -! 2006-01-20 - Marco Cattaneo - - Add use CORAL to requirements. N.B.: this is temporary, should be done - directly in COOL interface package - -! 2005-12-08 - Marco Clemencic - - Use GaudiUtils::HashMap in CondDBCache.h - -================= Det/DetCond v7r7 2005-11-04 ================================ -! 2005-10-18 - Marco Clemencic - - Cosmetic improvements - (RelyConverter, CondDBGenericCnv, CondDBAccessSvc, CondDBCnvSvc) - - Added `#include <vector>' in ICondDBAccessSvc.h and ICondDBCnvSvc.h - -! 2005-10-05 - Marco Clemencic - - Minimal update to follow API changes from COOL_1_1_0 to COOL_1_2_4 - -================= Det/DetCond v7r6 2005-09-19 ================================ -! 2005-09-18 - Marco Clemencic - - Allow direct mapping of the CondDB structure to the DetectorDataSvc tree - (no need to pass through an XML file/string with only catalogs) - - Use the 3rd string of the GenericAddress to store the origin of the XML - string (needed for self referencing XML string with DetDescCnv > v2r8) - -! 2005-08-31 - Marco Clemencic - - Implemented RelyConverter::updateObjRefs in order to re-initialize - correctly the updated conditions. - -! 2005-08-30 - Marco Clemencic - - Added support to cool::ChannelId (needs DetDescCnv > v2r8) - - Fixed a bug in CondDBCache - (the search of conflicts in the IOVs worked only in a well defined case, - the one tested!) - -================= Det/DetCond v7r5 2005-07-21 ================================ -! 2005-07-21 - Marco Clemencic - - Apply always tag NEEDS_COOL_FACTORY (is needed by Windows and Python) - -! 2005-07-11 - Marco Clemencic - - Removed unused pointers from CondDBCnvSvc - -! 2005-07-07 - Marco Cattaneo - - Fix a doxygen warning - -! 2005-07-07 - Marco Clemencic - - Abstract interfaces moved to DetDesc (to allow python bindings) - - Added CondDBAccessSvc::dumpCache(), it prints (level=DEBUG) the content - of the cache. - -! 2005-06-30 - Marco Clemencic - - Added RelyConverter::fillObjectRefs (was missing, but needed for - initialization of objects) - -================= Det/DetCond v7r4 2005-06-23 ================================ -! 2005-06-23 - Marco Clemencic - - Added the possibility of having an in-memory copy of the CondDB. - -! 2005-06-14 - Marco Clemencic - - Renamed ConditionsDBCnvSvc to CondDBCnvSvc and added the interface - ICondDBCnvSvc - -================= Det/DetCond v7r3 2005-06-14 ================================ -! 2005-06-14 - Marco Cattaneo - - Move ConditionsDbCnvSvc and RelyConverter to component library. - -! 2005-06-14 - Marco Clemencic - - CondDBAccessSvc does not complain anymore if the user is not specified - (adapted to POOL XML authentication service, COOL > 1.1.0) - -! 2005-06-08 - Marco Clemencic - - Changed from "component library" to "component + link library" - -================= Det/DetCond v7r2 =========================================== -! 2005-05-27 - Marco Clemencic - - fixed compilation issue for Windows - -! 2005-05-25 - Marco Clemencic - - Adapted to COOL 1.1.0 (LCG_35) - -================= Det/DetCond v7r1 =========================================== -! 2005-05-12 - Marco Clemencic - - Fixed the compilation on WIN32 - - Added support to multiple databases through option - ConditionsDBCnvSvc.CondDBAccessServices - -================= Det/DetCond v7r0 =========================================== -! 2005-04-25 - Marco CLEMENCIC - - Upgrade to COOL_1_0_0 (first production release) - - Works with LHCb v18r3 - -================= Det/DetCond v6r1 =========================================== -! 2005-04-22 - Marco CLEMENCIC - - Upgrade to COOL_0_1_0-pre2 - - Support for tagging - - almost all the technicalities (POOL/COOL) moved to CondDBAccessSvc - - some clean up - - commit before the first production release - -============================================================================== -! 2005-02-09 - Marco CLEMENCIC - - Upgrade to first public preliminary version of COOL (COOL_0_0_3-pre1) - - Renamed XMLRelyCnv to RelyConverter (it can use, in principle, any - conversion service). - - Moved CondDBGenericCnv to the public interface in order to allow public - usage of RelyConverter. - -============================================================================== -! 2005-01-27 - Marco CLEMENCIC - - Upgrade to first preliminary version of the Conditions Database API: - COOL_0_0_1 - -============================================================================== -! 2004-12-08 - Marco Clemencic - - Upgrade to latest stable version of CondDB (CONDDB_0_2_0) and fixed for the -changes in Gaudi/LHCb - - Moved and modified part of the ConditionsDBCnvSvc to a dedicated converter -(XmlRelyCnv) + a generic CondDB converter to put common Converter functions in -one place - - Implemented the possibility to use a fall back Converter (the one relying on -DetectorPersistencySvc) if no dedicated converter is found. -Requirements v5r0 - -============================================================================== -!20030131 - Andrea Valassi -Upgrade to DetDesc v11r8. -Only change is in recommended CMTPATH. -- DetDesc is included in LHCB_v11r5 for all of rh61dbx, rh73dbx and Windows -- This makes it easier to distribute as DetDesc does not need to be recompiled -Requirements v4r3, private tag h20030131 - -============================================================================== -!20021203 - Andrea Valassi -Include the MySQL implementation for both RH73 and WIN32 -- DetCond on RH73/WIN32 now depends on both Oracle and MySQL implementations - > multiple "use..." in the requirements - > if the "use..." statement is removed, some code is #ifndef'd away - (as the base packages propagate to DetCond the relevant cppflags) - > to make the code more readable, implementation-specific init() and - i_buildCondDBInfo() have been introduced (#ifdef'd in only if necessary!) - > I assume RH61 is always Objy only -- Implementation is read at runtime from the job options - > ConditionsDBGate.condDBImpl = one of CondDBObjy, CondDBOracle, CondDBMySQL -- Remove CondDBKey.h from DetCond (I forgot to remove it on h20020301!) -Requirements v4r2, private tag h20021203 - -============================================================================== -!20021125 - Andrea Valassi -Upgrade to CondDBOracle v4r16, Gaudi v11r2 and DetDesc v11r2. -Upgrade to RedHat73 on lxplus7. -- no major change to DetCond code - > disable WIN32 compilation warning 4786 in ConditionsDBGate.cpp - > print out ORA_NLS33 and NLS_LANG to keep track of their values -- dependency on Det/CondDBOracle changed from v4r15 to v4r16 (RH7,WIN) -- dependency on Gaudi changed to v13r* (tested with v13r2) -- dependency on GaudiSvc changed to v10r* (tested with v10r1) -- dependency on Det/DetDesc changed to v11r* (tested with v11r2) -Modify CMT requirements to allow for runtime choice between Oracle and MySQL. -- precompiler directives are inherited from CondDB package(s) -- dependency on CONDDB (using Objectivity) changed to v3r02p3 (RH6) -Requirements v4r1, private tag h20021125 - -============================================================================== -!20020725 - Andrea Valassi -Upgrade to CondDBOracle v4r15 and Gaudi v10r4. -- no change to DetCond code -- dependency on Det/CondDBOracle changed from v3r10p1 to v4r15 (RH7,WIN) -- dependency on CONDDB (using Objectivity) remains v3r02p2 (RH6) -- dependency on Gaudi tested with GaudiKernel v12r3 and GaudiSvc v8r3 -- dependency on Det/DetDesc (v10r*) tested with v10r3 -Requirements v4r0, private tag h20020725 - -============================================================================== -!20020417 - Andrea Valassi -Upgrade to Gaudi v10 -- use RedHat7.2 tag rh72_gcc2952 (not rh72_gcc29521), defined in GaudiPolicy -- dependency on Det/CondDBOracle changed from v3r10 to v3r10p1 -- dependency on CONDDB changed from v3r02p1 to v3r02p2 (bug fix) -- adapt to new version of MsgStream.h in GaudiKernel for longlong printout -- dependency on Det/DetDesc changed from v9r* to v10r* -Requirements v3r0, private tag h20020417 - -============================================================================== -!20020405 - Andrea Valassi -Minor modifications to requirements -- dependency on CONDDB changed from v3r02 to v3r02p1 -- env. variable CONDDB_implementation is defined in CONDDB or Det/CondDBOracle -Requirements v2r1, private tag h20020405 - -============================================================================== -!20020328 - Andrea Valassi -First Oracle implementation ported to Linux (RedHat 7.2 only) -See doc/README.RedHat72 in Ex/DetCondExample for more details -Corresponds to Emil's first official release of ConditionsDB (0.3.1.0) -- change WIN32 dependency on Det/CondDBOracle package to version v3r10 -- add rh72_gcc29521 dependency on Det/CondDBOracle v3r10 -- keep rh61_gcc29521 dependency on CONDDB v3r02 -Requirements v2r1, private tag h20020328. - -============================================================================== -!20020308 - Andrea Valassi -Change dependency on CondDBOracle package to version v2r10 (0.2.1.0). -Requirements v2r1, private tag h20020308. - -============================================================================== -!20020301 - Andrea Valassi -First version supported on Windows using an Oracle implementation of CondDB. -- Platform-specific support - > remove CondDBKey.h from DetCond: use that from the ConditionsDB package - > interchange the contents of DetCond_dll and DetCond_load - > remove #ifdef's with dummy failure codes for non-Linux platforms -- Support of Oracle (needed also to suppport Oracle under Linux) - > implementation specified in the requirements is propagated via #ifdef's - > new init string for the Oracle database including host, user and password - > CondDBOracleMgrFactory or CondDBObjyDBMgrFactory called in either case -Requirements v2r1, private tag h20020301. - -============================================================================== -!20020110 - Flr - requirements - apply packageShr instead of ld_library_path pattern because - it is a component library. - do not apply package_Lshlibflags, there is no linker library. - -!20011220 - Andrea Valassi -Simplify dependencies on the Gaudi framework. - -============================================================================== -!20011216 - Andrea Valassi -Major changes due to tighter coordination with DetDesc and XmlDDDB packages. -- Update cannot be delegated to XmlCnvSvc until major changes in DetDes - > code creating and interpreting DOM trees in each Xml converter should be - executed also in updateObj(): to avoid duplicating code, a solution is - to move it from createObj() to updateObj() or better updateObjRefs(), - which should be called internally from createObj() - > my (temporary?) solution is to create a new object using the address, and - deep copy part of it into the old one by a Condition::update(Condition&) - method to deep copy only those properties of a DataObject that refer - to a Condition (eg validity and parameters); the registry, address, - reference counts and other DataObject properties should not be deep - copied instead (hence an overloaded operator= is not introduced) - > update of DataObjects is only possible for Conditions (and derived classes) - because this method exists only for Conditions - > this is the only reason to have a dependency on DetDesc - > however, DataObjects not implementing IValidity are now assumed valid - (previously, an error was returned when updating them) -- Changes in folder description - > classID are removed from all XML refs: remove it from folder description - > assume that secondary storage type is always read from folder description -- Remove ConditionsDBAddress (a GenericAddress of type CONDDB is enough) - > par[0] is still the COndDB folder name - > the tag name is not anymore in the CONDDB address - > par[1] is now the name of the element (e.g. the name of an XML element) - > the string storage type is not in the CONDDB address - (it is now assumed that it is always read from the folder description) - > ipar{0,1] are not used anymore -- Registry entry (can be 0) is used in creating and updating Conditions - > for instance: this is needed for catalog conversion - > it is set in the secondary temporary address (e.g. an XML catalog address) -- Minor changes in messaging: use VERBOSE tag for verbose comments -- Overload methods for writing representations in ConditionsDBCnvSvc - > they must be overloaded because this CnvSvc has no converters - > they are empty for the moment (not yet implemented) -- Upgrade to CMT v1r10: remove scripts and hacks needed to cure a bug in CMT -Requirements v2r0, private tag h20011216. - -============================================================================== -!20011130 - Andrea Valassi -Modified version of DetDataSvc in GaudiSvc committed to CVS -- Contains main features of ConditionDataSvc and ConditionsDBDataSvc -- Remove ConditionDataSvc and ConditionsDBDataSvc from this package - -============================================================================== -!20011129 - Andrea Valassi -- Remove the IConditionsDBDataSvc special interface - > ConditionsDBDataSvc now does little more than ConditionDataSvc -- Implement a dummy IIncidentListener interface in ConditionDataSvc -- Redefine ConditionsDBAddress_undefinedClassID = CLID_NULL (it will disappear) - -============================================================================== -!20011128 - Andrea Valassi -Move the global tag from the ConditionsDBDataSvc to the ConditionsDBCnvSvc -- Use IAddressCreator interface of CnvSvc to create addresses with global tag - > "DEFAULT" becomes a reserved word to indicate the global tag -- Remove method setGlobalTag (the tag can only be set in the job options) - -============================================================================== -!20011127 - Andrea Valassi -A few more changes before including my detector data service in GaudiSvc -- The event time is not passed in an address from the DataSvc to the CnvSvc - > remove IConditionAddress - > ConditionsDBCnvSvc now reads the event time from the DetDataSvc - > ConditionDataSvc::updateObject now just checks validity before delegating -- Move interface IDetDataSvc (formerly IConditionDataSvc) to GaudiKernel - > needed to retrieve the event time within the ConditionsDBCnvSvc - > the setEventTime method is temporary (eventually: use the IncidentService) -- Store ConditionsDBAddress private data as GenericAddress private data - -============================================================================== -!20011126 - Andrea Valassi -A few changes before including my data service in GaudiSvc. -- Move ConditionData from DetCond/src/Lib to DetCondExample - > only DataObjects are manipulated, with dynamic casts to IValidity - > no Lib anymore in DetCond/src -- Manipulate ITime and TimePoint objects rather than ITime pointers - > add bool method to check if the event time is defined in ConditionDataSvc - -============================================================================== -!20011123 - Andrea Valassi -Upgrade to Gaudi v9 -- Addresses now inherit from GenericAddress (which has been simplified a lot) -- There are no address factories any more -- Adapt to changes in RegistryEntry (which now implements IRegistry) -- Add dummy methods fillObjRefs and updateObjRefs in ConditionsDBCnvSvc -- Notify (by flag "true") ServiceLocator to create services not existing yet -Requirements v2, private tag h20011123. - -============================================================================== -!20010914 - Andrea Valassi -New package. -Requirements v1, private tag v1. - diff --git a/Det/DetCond/options/UseOracle.py b/Det/DetCond/options/UseOracle.py deleted file mode 100644 index 142aec20d..000000000 --- a/Det/DetCond/options/UseOracle.py +++ /dev/null @@ -1,3 +0,0 @@ -# Additional options for accessing Oracle conditions DB. -from Configurables import CondDB -CondDB(UseOracle = True) diff --git a/Det/DetCond/python/DetCond/Configuration.py b/Det/DetCond/python/DetCond/Configuration.py deleted file mode 100755 index 038fa6b7e..000000000 --- a/Det/DetCond/python/DetCond/Configuration.py +++ /dev/null @@ -1,788 +0,0 @@ -""" -High level configuration tools for Conditions Database. -""" -__author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>" - -from Gaudi.Configuration import allConfigurables, ConfigurableUser, importOptions, getConfigurable, log -from Configurables import ( CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBCnvSvc, - CondDBSQLiteCopyAccSvc, - CondDBLogger, - COOLConfSvc, - ApplicationMgr ) - -import os, re -from os.path import exists, join - -class CondDB(ConfigurableUser): - """ - Configurable user to allow high-level configuration of the access to the - conditions database. - """ - __slots__ = { "Tags" : {}, - "Simulation" : False, - "Upgrade" : False, - "UseOracle" : False, - "LocalTags" : {}, - "LogFile" : "", - "Overrides" : [], - "PartitionConnectionString": {}, - "SQLiteLocalCopiesDir": "", - "OverwriteSQLiteLocalCopy": False, - "DisableLFC" : False, - "Online" : False, - "IgnoreHeartBeat": False, - "HeartBeatCondition" : "/Conditions/Online/LHCb/Tick", - "EnableRunStampCheck": False, - "RunStampCondition": "", - "LatestGlobalTagByDataType" : "", - "LatestGlobalTagByDataTypes" : [], - "LatestLocalTagsByDataType": [], - "AllLocalTagsByDataType": [], - "UseLatestTags" : [], - "QueryGranularity" : 0, - "UseDBSnapshot" : False , - "DBSnapshotDirectory" : "/group/online/hlt/conditions" , - 'EnableRunChangeHandler' : False, - 'RunChangeHandlerConditions' : { 'online_%d.xml' : [ "Conditions/Online/LHCb/Magnet/Set" - , "Conditions/Online/Velo/MotionSystem" - , "Conditions/Online/LHCb/Lumi/LumiSettings" - , "Conditions/Online/LHCb/LHCFillingScheme" - , "Conditions/Online/LHCb/RunParameters" - , "Conditions/Online/Rich1/R1HltGasParameters" - , "Conditions/Online/Rich2/R2HltGasParameters" ] }, - 'LoadCALIBDB' : "OFFLINE" - } - _propertyDocDct = { - 'Tags' : """ Dictionary of tags (partition:tag) to use for the COOL databases """, - 'Simulation' : """ Boolean flag to select the simulation or real-data configuration """, - 'Upgrade' : """ Boolean flag to select the Upgrade simulation configuration """, - 'UseOracle' : """ Boolean flag to enable the usage of the CondDB from Oracle servers. NB: Obsolete as Oracle support is now dropped""", - 'LocalTags' : """ Dictionary with local tags to use to override the global ones (partition: list of local tags) """, - 'LogFile' : """ Record the requests to the database the specified file """, - 'Overrides' : """ Internal property used to add layers or alternatives """, - 'PartitionConnectionString' : """ Dictionary with alternative connection strings for the CondDB partitions """, - 'SQLiteLocalCopiesDir' : """ The directory where to copy the SQLite files before accessing them """, - 'OverwriteSQLiteLocalCopy' : """ When using SQLite local copies, overwrite existing files """, - 'DisableLFC' : """ Do not use LFC lookup even if we are connecting to Oracle """, - 'Online' : """ Flag to activate configuration options specific for the Online environment """, - 'IgnoreHeartBeat' : """ Do not set the HeartBeatCondition for the Online partition """, - 'HeartBeatCondition' : """ Location of the heart-beat condition in the database """, - 'EnableRunStampCheck': """ Enable the check for the special RunStamp condition """, - 'RunStampCondition': """ Path (in the CondDB) to the special RunsTamp condition. """, - 'LatestGlobalTagByDataType' : """ Use latest CondDB global tag marked with the data type""", - 'LatestGlobalTagByDataTypes' : """ Use latest CondDB global tag marked with the data type, will override LatestGlobalTagByDataType if set""", - 'LatestLocalTagsByDataType' : """ Use all latest CondDB local tags marked with the data type """, - 'AllLocalTagsByDataType' : """ Use all CondDB local tags marked with the data type """, - 'UseLatestTags' : """ List of the form [DataType, OnlyGlobalTags = False] to turn on the usage of the latest tags """, - 'QueryGranularity': """Granularity of the query in the database (in time units)""", - 'LoadCALIBDB': """ Load CALIB*.db file as additional layers on top of ONLINE-*.db file, could be either "HLT1" (w/o layering, ONLINE only), or "OFFLINE" (Layer CALIBOFF above CALIB & ONLINE ), Do not set it for the Online environment""", - } - LAYER = 0 - ALTERNATIVE = 1 - # List of known implementations of ICondDBReader (str is used for backward compatibility) - __CondDBReaders__ = [ CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc, - str ] - - def _checkOverrideArgs(self, accessSvc, connStr, dbFile, dbName): - """ - Check if the accessSvc is a valid CondDBReader or build one using the - other arguments. - """ - kwargs = { "accessSvc": accessSvc, "connStr": connStr, "dbFile": dbFile, "dbName": dbName } - if accessSvc is None: - if not connStr: - if dbFile: - if not dbName: - dbName = os.path.basename(dbFile) - m = re.match(r'([A-Z][A-Z0-9_]{0,7})(_\w+)?.db', dbName) - if m: - dbName = m.group(1) - else: - raise ValueError('invalid arguments %r' % kwargs) - connStr = "sqlite_file:%s/%s" % (dbFile, dbName) - else: - raise ValueError('invalid arguments %r' % kwargs) - name = dbName - else: - name = connStr.rsplit('/')[-1] - if not re.match(r'[A-Z][A-Z0-9_]{0,7}', name): - name = 'CondDBAccessSvc' - # make a unique name for the configurable - name = "automatic_" + name - name_format = name + '_%d' - i = 0 - while name in allConfigurables: - i += 1 - name = name_format % i - accessSvc = CondDBAccessSvc(name, ConnectionString = connStr) - elif type(accessSvc) not in __CondDBReaders__: # Check for supported types - raise TypeError("'%s' not supported as CondDBReader"%accessSvc.__class__.__name__) - return accessSvc - - def addLayer(self, accessSvc = None, connStr = None, dbFile = None, dbName = None): - """ - Add the given CondDBReader as a layer on top of the existing configuration. - - Example: - CondDB().addLayer(myDB) - """ - # Check the arguments and/or prepare a valid access svc - accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) - self.Overrides.append((self.LAYER, accessSvc)) - def _addLayer(self, accessSvc): - cnvSvc = allConfigurables["CondDBCnvSvc"] - - originalReader = cnvSvc.CondDBReader - if type(originalReader) == CondDBLayeringSvc: - # If the original reader is already a layering svc, we can extend the - # configuration. - originalReader.Layers.insert(0,accessSvc) - else: - # We have to create a new layering svc. - name = "CondDBLayeringSvc" - i = 0 - while name in allConfigurables: - i += 1 - name = "CondDBLayeringSvc_%d"%i - cnvSvc.CondDBReader = CondDBLayeringSvc(name, - Layers = [accessSvc, - originalReader]) - - def addAlternative(self, accessSvc = None, path = None, connStr = None, dbFile = None, dbName = None): - """ - Add the given CondDBReader as an alternative to the existing configuration - for the specified path. - - Example: - CondDB().addAlternative(myDB,"/Conditions/MyDetector/Alignment") - """ - if path is None: - raise ValueError("'path' must be specified") - # Check the arguments and/or prepare a valid access svc - accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) - self.Overrides.append((self.ALTERNATIVE, accessSvc, path)) - - def _addAlternative(self, accessSvc, path): - cnvSvc = allConfigurables["CondDBCnvSvc"] - - originalReader = cnvSvc.CondDBReader - if type(originalReader) == CondDBDispatcherSvc: - # If the original reader is already a dispatcher, we can extend the - # configuration: - originalReader.Alternatives[path] = accessSvc - else: - # We have to create a new dispatcher - name = "CondDBDispatcherSvc" - i = 0 - while name in allConfigurables: - i += 1 - name = "CondDBDispatcherSvc_%d"%i - cnvSvc.CondDBReader = CondDBDispatcherSvc(name, - MainAccessSvc = originalReader, - Alternatives = { path: accessSvc } - ) - - def useLatestTags(self, DataType, OnlyGlobalTags = False): - self.UseLatestTags = [DataType, OnlyGlobalTags] - - def _useLatestTags(self, DataTypes, OnlyGlobalTags = False, OnlyLocalTags = False): - """ - Configure the conditions database to use the latest local tags on top of the latest global tag for a given data type. - """ - # Check arguments - if type(DataTypes) is not list: - DataTypes = [DataTypes] - - # Check if the latest tags should be set for simulation or not - if not self.getProp("Simulation"): - partitions = ["DDDB", "LHCBCOND", "DQFLAGS"] - if os.environ['LoadCALIBDB'] is "OFFLINE": - partitions += ["CALIBOFF"] - else: - partitions = ["DDDB", "SIMCOND"] - - # Set the latest tags - from CondDBUI.Admin.TagsFilter import last_gt_lts - rel_notes = None - if self.getProp('Upgrade'): - rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') - - for partition in partitions: - gt, lts = None, [] - for dt in DataTypes: - tags = last_gt_lts(partition, dt, rel_notes) - if not tags: - # Allowing absence of valid tags for DQFLAGS - if partition == 'DQFLAGS': continue - # Allowing absence of valid tags for CALIBOFF before 2015 - elif partition == 'CALIBOFF' and dt.isdigit() and int(dt)<2015: continue - else: - raise RuntimeError("Cannot find tags for partition '%s'," - " data type '%s'" % (partition, dt)) - if not gt: - gt = tags[0] - lts += tags[1] - - if not OnlyLocalTags and gt: # Only for partitions with available global tags - self.Tags[partition] = gt - if not OnlyGlobalTags and lts: - if partition in self.LocalTags: self.LocalTags[partition] += lts - else: self.LocalTags[partition] = lts - - def _useAllLocalTags(self, DataTypes): - """ - Configure the conditions database to use all local tags for a given data type. - """ - - # Check arguments - if type(DataTypes) is not list: - DataTypes = [DataTypes] - - # Check if the latest tags should be set for simulation or not - if not self.getProp("Simulation"): - partitions = ["DDDB", "LHCBCOND"] - if os.environ['LoadCALIBDB'] is "OFFLINE": - partitions += ["CALIBOFF"] - else: - partitions = ["DDDB", "SIMCOND"] - - # Set the latest tags - from CondDBUI.Admin.TagsFilter import all_lts - rel_notes = None - if self.getProp('Upgrade'): - rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') - - for partition in partitions: - local_tags = [] - for dt in DataTypes: - lts = all_lts(partition, dt, rel_notes) - if lts: local_tags += lts - if partition in self.LocalTags: self.LocalTags[partition] += local_tags - else: self.LocalTags[partition] = local_tags - - def __make_sqlite_local_copy__(self, accsvc, local_dir = None, force_copy = None): - if isinstance(accsvc, str): - # convert the string in an actual configurable instance - # This is both for backward compatibility and CondDBTimeSwitchSvc - if "/" in accsvc: - tp, name = accsvc.split("/",1) - else: - tp = name = accsvc - accsvc = getConfigurable(name, tp) - if local_dir is None: - local_dir = self.getProp("SQLiteLocalCopiesDir") - if force_copy is None: - force_copy = self.getProp("OverwriteSQLiteLocalCopy") - # If the directory for the local copies is not specified, we do nothing - if not local_dir: - return accsvc - # Check if we are using Oracle or SQLite -# if self.getProp("UseOracle"): -# log.warning("Conflicting properties in CondDB Configurable: " -# "ignoring SQLiteLocalCopiesDir because UseOracle is set to True") -# return accsvc - # Modify partitions to use local copies of the DBs - newaccsvc = accsvc # fallback return value (no change) - if isinstance(accsvc, CondDBAccessSvc): - # replace the reader with another - m = re.match(r"^sqlite_file:(.*)/([_0-9A-Z]{1,8})$", - accsvc.getProp("ConnectionString")) - if not m: # not SQLite connection string - return accsvc - newaccsvc = CondDBSQLiteCopyAccSvc(accsvc.name() + "_local") - newaccsvc.OriginalFile = m.group(1) - newaccsvc.DestinationFile = os.path.join(local_dir, - os.path.basename(m.group(1))) - newaccsvc.DBName = m.group(2) - newaccsvc.ForceCopy = force_copy - newaccsvc.IgnoreCopyError = not force_copy # ignore copy errors if we do not overwrite (needed for local tags) - if hasattr(accsvc, "CacheHighLevel"): - newaccsvc.CacheHighLevel = accsvc.CacheHighLevel - elif isinstance(accsvc, CondDBDispatcherSvc): - # use the same dispatcher replacing its content - mainAccSvc = accsvc.getProp("MainAccessSvc") - accsvc.MainAccessSvc = self.__make_sqlite_local_copy__(mainAccSvc, local_dir) - alternatives = accsvc.getProp("Alternatives") - for alt in alternatives.keys(): - accsvc.Alternatives[alt] = \ - self.__make_sqlite_local_copy__(alternatives[alt], local_dir) - elif isinstance(accsvc, CondDBLayeringSvc): - # use the same layering service replacing its content - new_layers = [] - for layer in accsvc.getProp("Layers"): - new_layers.append(self.__make_sqlite_local_copy__(layer, local_dir)) - accsvc.Layers = new_layers - elif isinstance(accsvc, CondDBTimeSwitchSvc): - # use the same time switcher replacing its content, - # but we need to parse its options (in format "'%s':(%d,%d)") - readers_list = accsvc.getProp("Readers") - new_readers = [] - for line in readers_list: - # Parse the line for the reader (it looks like "'name':(0,1)") - r, iov = map(eval, line.rsplit(":")) - new_reader = self.__make_sqlite_local_copy__(r, local_dir) - new_readers.append("'%s':(%d,%d)" % - (new_reader.getFullName(), iov[0], iov[1])) - accsvc.Readers = new_readers - elif isinstance(accsvc, CondDBLogger): - # use the same logger replacing its content - logged = accsvc.getProp("LoggedReader") - accsvc.LoggedReader = self.__make_sqlite_local_copy__(logged, local_dir) - elif isinstance(accsvc, CondDBCnvSvc): - # use the same conversion service replacing its content - reader = accsvc.getProp("CondDBReader") - accsvc.CondDBReader = self.__make_sqlite_local_copy__(reader, local_dir) - return newaccsvc - - def _configureDBSnapshot(self): - - baseloc = self.getProp( "DBSnapshotDirectory" ) - self.DisableLFC = True - - # Set alternative connection strings and tags - # if simulation is False, we use DDDB, LHCBCOND and ONLINE - # True DDDB, SIMCOND - # (see Det/DetCond's configurable... ) - dbPartitions = { False : [ "DDDB", "LHCBCOND", "ONLINE" ] - , True : [ "DDDB", "SIMCOND" ] - } - - tag = self.getProp("Tags") - for part in dbPartitions[ self.getProp('Simulation') ] : - if tag[part] is 'default' : raise KeyError('must specify an explicit %s tag'%part) - self.PartitionConnectionString[part] = "sqlite_file:%(dir)s/%(part)s_%(tag)s.db/%(part)s" % {"dir": baseloc, - "part": part, - "tag": tag[part]} - self.Tags[part] = tag[part] - - # Set the location of the Online run-by-run conditions - if self.getProp('EnableRunChangeHandler') : - from Configurables import RunChangeHandlerSvc - rch = RunChangeHandlerSvc() - rch.Conditions = dict( (c,'/'.join([baseloc,f])) for f,cs in self.getProp("RunChangeHandlerConditions").iteritems() for c in cs ) - ApplicationMgr().ExtSvc.append(rch) - - def __apply_configuration__(self): - """ - Converts the high-level information passed as properties into low-level configuration. - """ - # special case for online - if self.getProp('UseDBSnapshot') : self._configureDBSnapshot() - - # In the Online/Upgrade/Simulation environment, LoadCALIBDB should be defaulted to HLT1 - if self.getProp("Online") or self.getProp('Upgrade') or self.getProp('Simulation'): - self._properties["LoadCALIBDB"].setDefault("HLT1") - # Set up environment variables for loading CALIBOFF layers, must be before loading any tags - LoadCALIBDB = self.getProp('LoadCALIBDB') - loadcaliboptions = ["HLT1", "OFFLINE"] - if LoadCALIBDB not in loadcaliboptions: - raise ValueError("'%s' is not a valid LoadCALIBDB value. Allowed: %s" %(LoadCALIBDB, loadcaliboptions)) - if LoadCALIBDB is "OFFLINE" and not exists(join(os.environ["SQLITEDBPATH"], "CALIBOFF.db")): - LoadCALIBDB = "HLT1" # When CALIBOFF.db is not there, reset the option - os.environ['LoadCALIBDB'] = LoadCALIBDB - - # Set the usage of the latest global/local tags - old_latest_Tags_prop = self.getProp("UseLatestTags") # it is deprecated - latest_GTags_prop = self.getProp("LatestGlobalTagByDataTypes") - if not latest_GTags_prop: # if property not set - latest_GTags_prop = self.getProp("LatestGlobalTagByDataType") - latest_LTags_prop = self.getProp("LatestLocalTagsByDataType") - all_LTags_prop = self.getProp("AllLocalTagsByDataType") - - if old_latest_Tags_prop: - if latest_GTags_prop or latest_LTags_prop: - log.warning("The property 'UseLatestTags' is deprecated:" - "'LatestGlobalTagByDataType(s)' and 'LatestLocalTagsByDataType'" - " will be used instead.") - else: - latest_GTags_prop = old_latest_Tags_prop[0] - if type(old_latest_Tags_prop[-1]) != bool or \ - (type(old_latest_Tags_prop[-1]) == bool and not old_latest_Tags_prop[1]): - latest_LTags_prop = old_latest_Tags_prop[0] - - if latest_GTags_prop: - datatype = latest_GTags_prop - if self.getProp("Tags"): - self.Tags = {} - self._useLatestTags(datatype, OnlyGlobalTags = True) - log.warning("Default global tags will be overridden with the latest ones" - " available for '%s' data type: %s"%(datatype, self.getProp("Tags")) ) - - if latest_LTags_prop: - datatypes = latest_LTags_prop - #if self.getProp("LocalTags"): - # self.LocalTags = {} - self._useLatestTags(datatypes, OnlyLocalTags = True) - log.warning("Latest unbound local tags on top of the latest global tags" - " of %s data type(s) are added: %s" - %(datatypes, self.getProp("LocalTags"))) - - if all_LTags_prop: - datatypes = all_LTags_prop - self._useAllLocalTags(datatypes) - log.warning("ALL local tags of %s data type(s) are added: %s" - %(datatypes, self.getProp("LocalTags"))) - - # Import SQLDDDB specific info - if self.getProp("UseOracle"): - CondDBAccessSvc("ONLINE", ConnectionString = "CondDBOnline/ONLINE") - if self.getProp("DisableLFC"): - COOLConfSvc(UseLFCReplicaSvc = False) - elif self.getProp('UseDBSnapshot'): - CondDBAccessSvc("ONLINE") - else: - configureOnlineSnapshots() -# importOptions("$SQLDDDBROOT/options/SQLDDDB.py") - - ######################################################################### - # Access to ConditionsDB - ########################################################################## - conns = self.getProp("PartitionConnectionString") - tags = self.getProp("Tags") - # DB partitions - partition = {} - parttypes = [ ("DDDB", CondDBAccessSvc), - ("LHCBCOND", CondDBAccessSvc), - ("ONLINE", CondDBTimeSwitchSvc), - ("SIMCOND", CondDBAccessSvc), - ("DQFLAGS", CondDBAccessSvc)] - if LoadCALIBDB is "OFFLINE": - # CALIBOFF not needed for the upgrade - parttypes += [("CALIBOFF", CondDBAccessSvc)] - - for (p ,t) in parttypes: - partition[p] = getAnyDBReader(p, t) - # Override connection strings: - if p in conns: - if type(partition[p]) is CondDBAccessSvc: - partition[p].ConnectionString = conns[p] - del conns[p] - - # Override connection strings for Upgrade case - if self.getProp('Simulation') and self.getProp('Upgrade') and type(partition[p]) is CondDBAccessSvc: - partition[p].ConnectionString = os.path.join('sqlite_file:$SQLITEUPGRADEDBPATH', p + '.db', p) - # Override tags - if p in tags and p != "ONLINE": - partition[p].DefaultTAG = tags[p] - del tags[p] - # Set the query granularity - if p != "CALIBOFF": self.propagateProperty("QueryGranularity", partition[p]) - if type(partition[p]) is CondDBTimeSwitchSvc: # also online - for r in partition[p].Readers: - config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] - if isinstance(config, CondDBAccessSvc): - self.propagateProperty("QueryGranularity", config) - # Pass along the configuration for the layered DBs - elif isinstance(config, CondDBLayeringSvc): - for ly in config.Layers: - if isinstance(ly, CondDBAccessSvc): - self.propagateProperty("QueryGranularity", ly) - - if conns: - log.warning("Cannot override the connection strings of the partitions %r", conns.keys()) - if tags and tags.keys()!=['ONLINE']: - log.warning("Cannot set the tag for partitions %r", tags.keys()) - - # In the Online environment, IgnoreHeartBeat should be defaulted to True - if self.getProp("Online"): - self._properties["IgnoreHeartBeat"].setDefault(True) - if not self.getProp("IgnoreHeartBeat"): - if isinstance(partition["ONLINE"], CondDBAccessSvc): - self.propagateProperty("HeartBeatCondition", partition["ONLINE"]) - elif isinstance(partition["ONLINE"], CondDBTimeSwitchSvc): - # Add the heart beat conditions to the latest snapshot only since the - # others are limited but valid by construction. - if partition["ONLINE"].Readers: - latest = partition["ONLINE"].Readers[-1] - config = allConfigurables[eval(latest.split(':')[0]).split("/")[1]] - if isinstance(config, CondDBAccessSvc): - self.propagateProperty("HeartBeatCondition", config) - # Pass along the configuration for the layered DBs - elif isinstance(config, CondDBLayeringSvc): - for ly in config.Layers: - #Only apply HeartBeatCondition for ONLINE - if isinstance(ly, CondDBAccessSvc) and ly.getName().startswith("ONLINE_"): - self.propagateProperty("HeartBeatCondition", ly) - - if not self.getProp("Simulation"): - # Standard configurations - # - Reconstruction / analysis - disp = CondDBDispatcherSvc("MainCondDBReader", - MainAccessSvc = partition["DDDB"], - Alternatives = { - "/Conditions": partition["LHCBCOND"], - "/Conditions/Online": partition["ONLINE"], - "/Conditions/DQ": partition["DQFLAGS"] - }) - else: - # - Simulation - disp = CondDBDispatcherSvc("SimulationCondDBReader", - MainAccessSvc = partition["DDDB"], - Alternatives = { - "/Conditions": partition["SIMCOND"] - }) - CondDBCnvSvc( CondDBReader = disp ) - - if not (self.getProp("Online") or self.getProp("Simulation")): - self._properties["EnableRunStampCheck"].setDefault(True) - if self.getProp("EnableRunStampCheck"): - from Configurables import RunStampCheck - rsc = RunStampCheck() - self.propagateProperty("RunStampCondition", rsc) - ApplicationMgr().ExtSvc.append(rsc) - - # Load the CALIBOFF layer above everything if it exists -# if len([x for x in parttypes if x[0] == 'CALIBOFF']): -# self._addLayer(getAnyDBReader('CALIBOFF')) - - localTags = self.getProp("LocalTags") - not_applied = [] - for p in localTags: - if p in partition: - taglist = list(localTags[p]) - taglist.reverse() # we need to stack the in reverse order to use the first as on top of the others - i = 0 # counter - if p is "CALIBOFF": - if LoadCALIBDB is not "OFFLINE": - raise ValueError("invalid argument LoadCALIBDB set at '%s' instead of 'OFFLINE' for accessing local tags for CALIBOFF.db" % LoadCALIBDB) - pcolayers = [] - for t in taglist: - pcolayers.append(partition[p].clone("CALIBOFF_%d" %i, DefaultTAG = t)) - i += 1 - for r in partition["ONLINE"].Readers: - config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] - if isinstance(config, CondDBLayeringSvc): - config.Layers = pcolayers + config.Layers - elif type(partition[p]) is not CondDBTimeSwitchSvc: - for t in taglist: - self._addLayer(partition[p].clone("%s_%d" % (p, i), - DefaultTAG = t)) - i += 1 - else: - not_applied.append(p) - else: - not_applied.append(p) - if not_applied: - log.warning("Cannot set the local tags for partitions %r", not_applied) - - # Modify partitions to use local copies of the DBs - # before adding user layers and alternatives, which should be already local. - # This is a no-operation if the property is not set - self.__make_sqlite_local_copy__(CondDBCnvSvc()) - - # Add layers and alternatives - call = { self.LAYER : self._addLayer, - self.ALTERNATIVE : self._addAlternative } - for override in self.getProp("Overrides"): - apply(call[override[0]], override[1:]) - - # Add the logger - filename = self.getProp("LogFile") - if filename: - cnvSvc = allConfigurables["CondDBCnvSvc"] - cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader, - LogFile = filename) - - # Suppress pointless warning from COOL_2_5_0 - msgSvc = getConfigurable("MessageSvc") - msgSvc.setError.append("RelationalDatabase") - - # Set up Virtual File System service, can be used by ParticlePropertySvc - from Gaudi.Configuration import VFSSvc - from Configurables import CondDBEntityResolver - VFSSvc().FileAccessTools.append(CondDBEntityResolver()) - - -# Exported symbols -__all__ = [ "addCondDBLayer", "addCondDBAlternative", "useCondDBLogger", - "configureOnlineSnapshots" ] -# Configurables provided by the package -__all__ += [ "CondDBAccessSvc", - "CondDBDispatcherSvc", "CondDBLayeringSvc", "CondDBTimeSwitchSvc", - "CondDBSQLiteCopyAccSvc", "CondDBLogger", - "CondDBCnvSvc", - "CondDB" ] - -# List of known implementations of ICondDBReader (str is used for backward compatibility) -__CondDBReaders__ = [ CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc, - str ] - -def _assertConfig(funcname): - """ - Check if the default configuration has been loaded. - """ - if "CondDBCnvSvc" not in allConfigurables: - raise RuntimeError("You cannot call '%s' before the standard CondDB configuration"%funcname) - -def addCondDBLayer(accessSvc): - """ - Add the given CondDBReader as a layer on top of the existing configuration. - - Example: - addCondDBLayer(myDB) - """ - DetCond().addLayer(accessSvc) - -def addCondDBAlternative(accessSvc, path): - """ - Add the given CondDBReader as an alternative to the existing configuration - for the specified path. - - Example: - addCondDBAlternative(myDB,"/Conditions/MyDetector/Alignment") - """ - DetCond().addAlternative(accessSvc, path) - -def useCondDBLogger(filename = None, logger = None): - """ - Add the CondDBLogger to the chain of CondDBReaders. - - The simplest usage is to call the function without options (use defaults), or - pass a file name. - """ - _assertConfig('useCondDBLogger') - cnvSvc = allConfigurables["CondDBCnvSvc"] - if logger is None: - # use the default configuration - cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader) - elif type(logger) is CondDBLogger: - # use the user-provided configurable - logger.LoggedReader = cnvSvc.CondDBReader - cnvSvc.CondDBReader = logger - else: - raise TypeError("useCondDBLogger does not support '%s'"%logger.__class__.__name__) - # Use the user specified filename, if any - if filename: - cnvSvc.CondDBReader.LogFile = filename - -def _timegm(t): - """Inverse of time.gmtime. Implementation from Gaudi::Time.""" - import time - if t[8] != 0: # ensure that dst is not set - t = tuple(list(t[0:8]) + [0]) - t1 = time.mktime(t) - gt = time.gmtime(t1) - t2 = time.mktime(gt) - return t1 + (t1 - t2) - -def defConnStrFunc(ym_tuple): - return self.connStrOnline(ym_tuple) - -def connStrOnline(ym_tuple): - dbpath = os.environ["SQLITEDBPATH"] - if exists(join(dbpath, "ONLINE-%04d%02d.db" % ym_tuple)): - return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d%02d.db/ONLINE" % ym_tuple - return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d.db/ONLINE" % ym_tuple[0] - -def getAnyDBReader(layer = 'CALIBOFF', svc = CondDBAccessSvc): - CacheHighLevel = 200 - if layer == 'DDDB' : CacheHighLevel = 1700 - # Put the discovered layer on top - cfg = getConfigurable(layer, svc) - if svc is not CondDBAccessSvc: return cfg - try: cfg.ConnectionString - except AttributeError: # Set up connection for the 1st time - connstr = "sqlite_file:$SQLITEDBPATH/%s.db/%s" % (layer, layer) - if layer == 'DQFLAGS' : - cfg = CondDBAccessSvc(layer, ConnectionString = connstr, - CacheLowLevel = 5, CacheHighLevel = 10) - else: - cfg = CondDBAccessSvc(layer, ConnectionString = connstr, - CacheHighLevel = CacheHighLevel) - return cfg - -def getOnlineDBReader(ym_tuple, granularity = 'YEARLY', connStrFunc = None): - cnstr = '' - ymstr = '' - if granularity == 'YEARLY': - ymstr = "%04d" %ym_tuple[0] - cnstr = connStrFunc((ym_tuple[0],13)) - else: - ymstr = "%04d%02d" %ym_tuple - cnstr = connStrFunc(ym_tuple) - - ptnm = "ONLINE_" + ymstr - accSvc = CondDBAccessSvc(ptnm, ConnectionString = cnstr) - dblayers = [ accSvc ] - LoadCALIBDB = os.environ.get('LoadCALIBDB') - if ym_tuple[0] < 2015 or LoadCALIBDB is not "OFFLINE": # For datatype before 2015, no CALIBOFF layer is needed - return accSvc - dbpath = os.environ["SQLITEDBPATH"] - layer = 'CALIBOFF' - if exists(join(dbpath, layer + '.db')): - # Put the discovered layer on top - cfg = getConfigurable(layer, CondDBAccessSvc) - try: cfg.ConnectionString - except AttributeError: # Set up connection for the 1st time - cfg = CondDBAccessSvc("CALIBOFF", ConnectionString = - cnstr.replace('ONLINE-%s.db/ONLINE' %ymstr, "%s.db/%s" % (layer, layer)), CacheHighLevel = 200) - dblayers.insert(0, cfg) - - if (len(dblayers) == 1): return accSvc # In case no CALIBOFF.db is found - return CondDBLayeringSvc("ONLINELAYER_"+ymstr, Layers = dblayers ) - -def configureOnlineSnapshots(start = None, end = None, connStrFunc = None): - if connStrFunc is None: - connStrFunc = connStrOnline - - # prepare the configurable instance - ONLINE = CondDBTimeSwitchSvc("ONLINE") - - # Default snapshots granularity - granularity = 'YEARLY' - - # Set the first available snapshot pair: per-year by default - if start is None: - first_snapshot = (2008, None) - else: - first_snapshot = start - - # Set the last available snapshot pair: current year by default - if end is None: - import time - last_snapshot = (time.gmtime()[0], None) - else: - last_snapshot = end - - # If last snapshot is per-month switch the first one to be also per-month - if last_snapshot[1]: - granularity = 'MONTHLY' - first_snapshot = (2008, 6) - - # reset the list of readers, for safety - ONLINE.Readers = [] - # loop from first to last-1 - i = first_snapshot - until = 0 # this makes the first service used from times starting from 0 - while i < last_snapshot: - accSvc = getOnlineDBReader(i, granularity, connStrFunc) - since = until - # increment - if granularity == 'YEARLY': - i = (i[0]+1, None) - until = int(_timegm(tuple([i[0], 1, 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 - else: - if i[1] == 12: i = (i[0]+1,1) - else: i = (i[0],i[1]+1) - until = int(_timegm(tuple([i[0], i[1], 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 - descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) - ONLINE.Readers.append(descr) - - # append the last database with validity extended to the maximum validity - accSvc = getOnlineDBReader(i, granularity, connStrFunc) - since = until - until = 0x7fffffffffffffffL # Defined in PyCool.cool as ValidityKeyMax - descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) - ONLINE.Readers.append(descr) diff --git a/Det/DetCond/python/DetCond/HistoCond.py b/Det/DetCond/python/DetCond/HistoCond.py deleted file mode 100644 index c89d49911..000000000 --- a/Det/DetCond/python/DetCond/HistoCond.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -# ============================================================================= -## @file DetCond/HistoCond.py -# Decorate the Condition object with functions to extract 1d and 2d-histograms -# @authorVanya BELYAEV Ivan.Belyaev@nikhef.nl -# @date 2009-12-01 -# ============================================================================= -""" -Decorate the Condition object with functions to extract 1d and 2d-histograms, and -define functions to convert 1d and 2d histograms to Condition parameter strings. -""" -# ============================================================================= -__author__ = "Vanya BELYAEV Ivan.Belyaev@nikhef.nl and Dmitry Golubkov" -__version__ = "CVS Tag $Name: not supported by cvs2svn $, verison $Revision: 1.1 $" -# ============================================================================= -# export nothing -__all__ = () ## export nothing -# ============================================================================= - -## import HistoStrings.Histos -from GaudiPython.Bindings import gbl as cpp - -_C = cpp.Condition -# ============================================================================= -## function to convert 1D histogram to an xml param string -def histo1DAsParam ( h1d, name = 'name', comment = 'comment' ) : - """ - Convert 1D histogram to an xml param string - """ - param_head = '\n <param name = "%s" type = "Histo1D" comment="%s">\n' - param_tail = '\n </param>\n' - - return param_head % (name, comment) + h1d.toString() + param_tail -# ============================================================================= -## function to convert 2D histogram to an xml param string -def histo2DAsParam ( h2d, name = 'name', comment = 'comment' ) : - """ - Convert 2D histogram to an xml param string - """ - param_head = '\n <param name = "%s" type = "Histo2D" comment="%s">\n' - param_tail = '\n </param>\n' - - return param_head % (name, comment) + h2d.toString() + param_tail -# ============================================================================= -## decorate the condition object: -if not hasattr ( _C , 'paramAsH1' ) : - - _F1 = cpp.DetDesc.Params.paramAsHisto1D - - # ========================================================================= - ## Extract the 1D-histogram form condition objects - # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - # @date 2009-12-01 - def _paramAsH1_ ( self , name ) : - """ - Extract the 1D-histiogram from condition objects - - >>> cond = ... ## get the condition object - >>> name = ... ## the name - - >>> h1 = cond.paramAsH1 ( name ) - >>> h1 = cond.paramAsHisto1D ( name ) # same as Condition.paramAsH1 - """ - return _F1 ( self , name ) - - _paramAsH1_ . __doc__ += '\n' + _F1 . __doc__ - _C .paramAsH1 = _paramAsH1_ - _C .paramAsHisto1D = _paramAsH1_ - -# ============================================================================= -## decorate the condition object: -if not hasattr ( _C , 'paramAsH2' ) : - - _F2 = cpp.DetDesc.Params.paramAsHisto2D - - # ========================================================================= - ## Extract the 2D-histogram form condition objects - # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - # @date 2009-12-01 - def _paramAsH2_ ( self , name ) : - """ - Extract the 2D-histiogram from condition objects - - >>> cond = ... ## get the condition object - >>> name = ... ## the name - - >>> h2 = cond.paramAsH2 ( name ) - >>> h2 = cond.paramAsHisto2D ( name ) # same as Condition.paramAsH2() - """ - return _F2 ( self , name ) - - _paramAsH2_ . __doc__ += '\n' + _F2 . __doc__ - _C .paramAsH2 = _paramAsH2_ - _C .paramAsHisto2D = _paramAsH2_ - -if '__main__' == __name__ : - - print __doc__ - print __author__ - print __version__ - -# ============================================================================= -# The END -# ============================================================================= diff --git a/Det/DetCond/python/DetCond/__init__.py b/Det/DetCond/python/DetCond/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/Det/DetCond/src/Lib/CondDBGenericCnv.cpp b/Det/DetCond/src/Lib/CondDBGenericCnv.cpp deleted file mode 100755 index b83b90922..000000000 --- a/Det/DetCond/src/Lib/CondDBGenericCnv.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// Include files -#include "GaudiKernel/IDetDataSvc.h" -#include "GaudiKernel/Time.h" -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/IValidity.h" -#include "GaudiKernel/DataObject.h" - -#include "DetDesc/IDetectorElement.h" -#include "DetDesc/ValidDataObject.h" - -#include "CoolKernel/ValidityKey.h" -#include "CoolKernel/IFolder.h" -#include "CoolKernel/IObject.h" -#include "CoolKernel/IDatabase.h" -#include "CoolKernel/Exception.h" - -// local -#include "DetCond/CondDBGenericCnv.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBGenericCnv -// -// 2004-12-03 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBGenericCnv::CondDBGenericCnv(ISvcLocator* svc,const CLID& clid): - Converter(CONDDB_StorageType,clid,svc) -{} -//============================================================================= -// Destructor -//============================================================================= -CondDBGenericCnv::~CondDBGenericCnv() = default; - -//========================================================================= -// Initialization -//========================================================================= -StatusCode CondDBGenericCnv::initialize() { - // Initializes the grand father - StatusCode sc = Converter::initialize(); - - // Query the IDetDataSvc interface of the detector data service - m_detDataSvc = serviceLocator()->service("DetectorDataSvc"); - if( !sc.isSuccess() ) { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - log << MSG::ERROR << "Can't locate DetectorDataSvc" << endmsg; - return sc; - } else { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Succesfully located DetectorDataSvc" << endmsg; - } - // Get a pointer to the CondDBReader (implemented by the conversion service) - m_condDBReader.reset( conversionSvc().get() ); - if ( !m_condDBReader ) { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - log << MSG::ERROR << "The conversion service does not implement ICondDBReader!" << endmsg; - return StatusCode::FAILURE; - } - - return sc; -} - -//========================================================================= -// Finalization -//========================================================================= -StatusCode CondDBGenericCnv::finalize() { - m_detDataSvc.reset(); - m_condDBReader.reset(); - return Converter::finalize(); -} - -//========================================================================= -// Ask the event time to the DetectorDataSvc -//========================================================================= - -StatusCode CondDBGenericCnv::eventTime(Gaudi::Time &time) const { - if (!m_detDataSvc->validEventTime()){ - return StatusCode::FAILURE; - } - time = m_detDataSvc->eventTime(); - return StatusCode::SUCCESS; -} - -//========================================================================= -// Set the validity of the object -//========================================================================= -void CondDBGenericCnv::setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject){ - // Set validity of created object - IValidity* pValidity = dynamic_cast<IValidity*>(pObject); - - if ( pValidity != NULL ) { // it has a validity - - pValidity->setValidity(since, till); - - } else { - - // I cannot set the validity range - MsgStream log(msgSvc(),"CondDBGenericCnv"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG - << "Created object (CLID = " << pObject->clID() - << ") does not implement IValidity: cannot set validity" - << endmsg; - } -} - -//========================================================================= -// get an object from the conditions database -//========================================================================= -StatusCode CondDBGenericCnv::getObject (const std::string &path, const cool::ChannelId &channel, - ICondDBReader::DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until) { - - Gaudi::Time now; - StatusCode sc = eventTime(now); - if (sc.isFailure()) { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - log << MSG::ERROR << "Cannot create DataObject: event time undefined" << endmsg; - return sc; - } - - return m_condDBReader->getObject(path,now,data,descr,since,until,channel); -} - -//========================================================================= -// get get the list of nodes in a folderset from the conditions database -//========================================================================= -StatusCode CondDBGenericCnv::getChildNodes(const std::string &path,std::vector<std::string> &node_names){ - MsgStream log(msgSvc(),"CondDBGenericCnv"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; - - return m_condDBReader->getChildNodes(path,node_names); -} -//============================================================================= - diff --git a/Det/DetCond/src/component/COOLConfSvc.cpp b/Det/DetCond/src/component/COOLConfSvc.cpp deleted file mode 100755 index 384a0b8f0..000000000 --- a/Det/DetCond/src/component/COOLConfSvc.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#ifdef __INTEL_COMPILER // Disable ICC remark from CORAL MessageStream and Boost - #pragma warning(disable:2259) -#endif - -// Include files -#include "RelationalAccess/ConnectionService.h" -#include "RelationalAccess/IConnectionServiceConfiguration.h" -#include "RelationalAccess/IReplicaSortingAlgorithm.h" -#include "RelationalAccess/IDatabaseServiceDescription.h" - -#include "CoolKernel/IDatabaseSvc.h" -#include "CoolApplication/Application.h" -#include "CoolApplication/DatabaseSvcFactory.h" - -#include "COOLConfSvc.h" - -#ifdef WIN32 -#define NOMSG -#define NOGDI -#endif - -// For the case insensitive string comparison (boost::algorithm::icontains). -#include "boost/algorithm/string/predicate.hpp" -// For random numbers not affecting simulation. -#include "boost/random/linear_congruential.hpp" -//#include "boost/random/uniform_smallint.hpp" -#include "boost/date_time/posix_time/posix_time_types.hpp" - -namespace -{ - - /** @class ReplicaSortAlg - * - * Small class implementing coral::IReplicaSortingAlgorithm interface to allow dynamic sorting of - * database replicas obtained from LFC. - * - * When retrieving the list of DB replicas, LFCReplicaService obtains a list in an arbitrary order. - * We have to provide to CORAL a class to be used to sort the list of replicas according to our - * needs. First we want the closest DB, identified by the environment variable LHCBPRODSITE, then - * the CERN server (LCG.CERN.ch), while the remaining one can be in any order (this implementation - * uses the natural string ordering). - * - * @author Marco Clemencic - * @date 2007-05-02 - */ - class ReplicaSortAlg: virtual public coral::IReplicaSortingAlgorithm - { - typedef coral::IDatabaseServiceDescription dbDesc_t; - typedef std::vector< const dbDesc_t * > replicaSet_t; - - /** @class ReplicaSortAlg::Comparator - * - * Comparison function defining which replica comes before another. - * - * This class is used via the STL algorithm "sort" to order the list the way we need it. - * - * @author Marco Clemencic - * @date 2007-05-02 - */ - class Comparator: public std::binary_function<const dbDesc_t*,const dbDesc_t*,bool> - { - typedef boost::rand48 RandomGenType; - typedef RandomGenType::result_type WeightType; - typedef std::map<std::string,WeightType> WeightMap; - - /// Site that have to be used before the others - std::string site; - /// Map used to remember the priority of the sites. - /// the local site has weight -1, the other are randomly chosen the first - /// time they are encountered. - mutable WeightMap weights; - /// Random number generator. Using Boost to avoid interactions with the - /// random generator services. - mutable RandomGenType gen; - - WeightType getWeight(const std::string& key) const { - WeightMap::iterator i = weights.find(key); - if ( weights.end() == i ) { // not found - WeightType newWeight = 0; - if (boost::algorithm::icontains(key,site)) { - // it means that this is the site with highest priority - newWeight = gen.max(); - } else { - // all other sites are distributed randomly - newWeight = gen(); - } - weights[key] = newWeight; - return newWeight; - } - return i->second; - } - - public: - - /// Constructor. - /// @param theSite the local LHCb Production Site (<i>SITE</i>.<i>country</i>) - Comparator(std::string theSite): - site(std::move(theSite)), - gen(// this is the rather longish Boost way of getting the current number of - // seconds since the beginning of the day... that I want to use as seed - // for the local random number generator (I do not use "seconds since epoch" - // because the boosted way of getting it is too long). - boost::posix_time::second_clock::universal_time().time_of_day().total_seconds()) - {} - - /// Main function - result_type operator() (first_argument_type a, second_argument_type b) const - { - return getWeight(a->serviceParameter(a->serverNameParam())) - < - getWeight(b->serviceParameter(b->serverNameParam())); - } - - }; - - std::string localSite; - MsgStream log; - - public: - - /// Constructor. - /// @param theSite the local LHCb Production Site (LCG.<i>SITE</i>.<i>country</i>) - ReplicaSortAlg(std::string theSite, IMessageSvc *msgSvc): - localSite(std::move(theSite)), - log(msgSvc,"ReplicaSortAlg") - { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Constructor" << endmsg; - } - - /// Destructor. - virtual ~ReplicaSortAlg() - { - // log << MSG::VERBOSE << "ReplicaSortAlg --> destructor" <<std::endl; - } - - /// Main function - virtual void sort (std::vector< const coral::IDatabaseServiceDescription * > &replicaSet) - { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { - log << MSG::VERBOSE << "Original list" << endmsg; - replicaSet_t::iterator i; - for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { - log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; - } - - log << MSG::VERBOSE << "Sorting..." << endmsg; - } - std::sort(replicaSet.begin(),replicaSet.end(),Comparator(localSite)); - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { - log << MSG::VERBOSE << "Sorted list" << endmsg; - replicaSet_t::iterator i; - for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { - log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; - } - } - } - - }; - -} - -// Factory implementation -DECLARE_SERVICE_FACTORY(COOLConfSvc) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -COOLConfSvc::COOLConfSvc(const std::string& name, ISvcLocator* svcloc): - base_class(name,svcloc) -{ - declareProperty("UseLFCReplicaSvc", m_useLFCReplicaSvc = false ); - declareProperty("LocalSite", m_localSite = "", - "The name of the site we are running on, used to order the " - "list of replicas in LFC."); - declareProperty("EnableCoralConnectionCleanUp", m_coralConnCleanUp = false ); - declareProperty("CoralConnectionRetrialPeriod", m_retrialPeriod = 60, - "Time between two connection trials (in seconds)."); - declareProperty("CoralConnectionRetrialTimeOut", m_retrialTimeOut = 15*60, - "How long to keep retrying before giving up (in seconds)."); -} -//============================================================================= -// Destructor -//============================================================================= -COOLConfSvc::~COOLConfSvc() {} - -//============================================================================= -// Access to COOL DatabaseSvc -//============================================================================= -cool::IDatabaseSvc& COOLConfSvc::databaseSvc() { - return coolApplication()->databaseService(); -} - -//============================================================================= -// Access to SEAL Context -//============================================================================= -coral::IConnectionService& COOLConfSvc::connectionSvc() { - return coolApplication()->connectionSvc(); -} - -//============================================================================= -// initialize -//============================================================================= -StatusCode COOLConfSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if ( ! m_coolApplication.get() ) { - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initializing COOL Application" << endmsg; - m_coolApplication.reset(new cool::Application); - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Getting CORAL Connection Service configurator" << endmsg; - coral::IConnectionServiceConfiguration &connSvcConf = - m_coolApplication->connectionSvc().configuration(); - - if ( m_useLFCReplicaSvc ) { - - log << MSG::INFO << "Using CORAL LFCReplicaService" << endmsg; - connSvcConf.setLookupService( "CORAL/Services/LFCReplicaService" ); - connSvcConf.setAuthenticationService( "CORAL/Services/LFCReplicaService" ); - - if ( m_localSite.empty() ) { - // if we didn't get a site from options, we try the environment var DIRACSITE - m_localSite = System::getEnv("DIRACSITE"); - if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { - // if DIRACSITE is not defined, we try, for backward compatibility, LHCBPRODSITE - m_localSite = System::getEnv("LHCBPRODSITE"); - if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { - // if none of the env. vars is set, let's stick to a "sensible" default - m_localSite = "CERN.ch"; - } - } - } - log << MSG::INFO << "Using '" << m_localSite << "' as preferred site" << endmsg; - - m_replicaSortAlg.reset(new ReplicaSortAlg(m_localSite,msgSvc())); - connSvcConf.setReplicaSortingAlgorithm(*m_replicaSortAlg); - } - - if ( ! m_coralConnCleanUp ) { - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Disabling CORAL connection automatic clean up" << endmsg; - connSvcConf.disablePoolAutomaticCleanUp(); - connSvcConf.setConnectionTimeOut( 0 ); - - } - - connSvcConf.setConnectionRetrialPeriod(m_retrialPeriod); - log << MSG::INFO << "CORAL Connection Retrial Period set to " - << connSvcConf.connectionRetrialPeriod() << "s" << endmsg; - - connSvcConf.setConnectionRetrialTimeOut(m_retrialTimeOut); - log << MSG::INFO << "CORAL Connection Retrial Time-Out set to " - << connSvcConf.connectionRetrialTimeOut() << "s" << endmsg; - - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode COOLConfSvc::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - m_coolApplication.reset(); - m_replicaSortAlg.reset(); - return base_class::finalize(); -} diff --git a/Det/DetCond/src/component/COOLConfSvc.h b/Det/DetCond/src/component/COOLConfSvc.h deleted file mode 100755 index 6de60e7cb..000000000 --- a/Det/DetCond/src/component/COOLConfSvc.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef COMPONENT_COOLCONFSVC_H -#define COMPONENT_COOLCONFSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "GaudiKernel/GaudiException.h" -#include "DetCond/ICOOLConfSvc.h" - -// Forward declarations -template <class TYPE> class SvcFactory; - -namespace cool { - class Application; - class RecordSpecification; -} -namespace coral { - class IReplicaSortingAlgorithm; -} - -/** @class COOLConfSvc COOLConfSvc.h - * - * Class used as interface to LCG COOL library API. It should expose as less as - * possible COOL internal details. - * - * @author Marco Clemencic - * @date 2005-01-11 - */ - -class COOLConfSvc: public extends1<Service, ICOOLConfSvc> { -public: - /// Initialize COOL (CondDB) Configuration Service - virtual StatusCode initialize(); - - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICOOLConfSvc implementation - /// Access to the CORAL connection service used by COOL (if needed). - virtual coral::IConnectionService& connectionSvc(); - - /// Get the COOL Database service (used to connect to the databases). - virtual cool::IDatabaseSvc& databaseSvc(); - -protected: - /// Standard constructor - COOLConfSvc(const std::string& name, ISvcLocator* svcloc); - - virtual ~COOLConfSvc( ); ///< Destructor - -private: - - inline cool::Application *coolApplication(){ - if (!m_coolApplication.get()) - throw GaudiException("Attempt to access COOL instance before initialization", - "(COOLConfSvc)" + name() + "::coolApplication", - StatusCode::FAILURE); - return m_coolApplication.get(); - } - - /// Pointer to a shared instance of the COOL Application - std::unique_ptr<cool::Application> m_coolApplication; - - std::unique_ptr<coral::IReplicaSortingAlgorithm> m_replicaSortAlg; - - /// Flag to turn off/on the CORAL LFCReplicaService (option UseLFCReplicaSvc, default = false). - /// Setting this option works only if it is set for the first COOLConfSvc initialized - /// because of a "feature" of CORAL. - bool m_useLFCReplicaSvc; - - /// Name of the grid site the application is running on. It is meaningful only - /// if m_useLFCReplicaSvc (option UseLFCReplicaSvc) is set to true. If not - /// specified the value of the environment variables "DIRACSITE" or - /// "LHCBPRODSITE" is used. If even the environment variables are not set, - /// then it is assumed to be "CERN.ch". (Note: the value is case insensitive) - std::string m_localSite; - - /// Flag to turn off/on the CORAL Automatinc connection clean up - /// (option EnableCoralConnectionCleanUp, default = false). - /// Setting this option works only if it is set for the first COOLConfSvc initialized. - bool m_coralConnCleanUp; - - /// Time between two connection trials (in seconds). - /// Passed to CORAL when loaded. - int m_retrialPeriod; - - /// How long to keep retrying before giving up (in seconds). - /// Passed to CORAL when loaded. - int m_retrialTimeOut; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<COOLConfSvc>; - -}; -#endif // COMPONENT_COOLCONFSVC_H diff --git a/Det/DetCond/src/component/CondDBAccessSvc.cpp b/Det/DetCond/src/component/CondDBAccessSvc.cpp deleted file mode 100755 index d8d75e653..000000000 --- a/Det/DetCond/src/component/CondDBAccessSvc.cpp +++ /dev/null @@ -1,1492 +0,0 @@ -// Include files -#include <sstream> -//#include <cstdlib> -//#include <ctime> - - -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -#include "GaudiKernel/IRndmGenSvc.h" -#include "GaudiKernel/IRndmEngine.h" - -#include "CoolKernel/DatabaseId.h" -#include "CoolKernel/IDatabaseSvc.h" -#include "CoolKernel/IFolder.h" -#include "CoolKernel/IFolderSet.h" -#include "CoolKernel/IObject.h" -#include "CoolKernel/IObjectIterator.h" -#include "CoolKernel/Exception.h" -#include "CoolKernel/RecordSpecification.h" -#include "CoolKernel/FolderSpecification.h" -#include "CoolKernel/StorageType.h" -#include "CoolKernel/Record.h" - -#include "CoralBase/AttributeList.h" -#include "CoralBase/Exception.h" -// FIXME: Needed because of COOL bug #38422 -#include "CoralBase/AttributeException.h" - -#include "DetCond/ICOOLConfSvc.h" - -// local -#include "CondDBAccessSvc.h" -#include "CondDBCache.h" - -#include "CondDBCommon.h" -#include "IOVListHelpers.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBAccessSvc) - -// Utility function -namespace { - template <class EXC> - inline void report_exception(MsgStream &log, const std::string &msg, const EXC& e){ - log << MSG::ERROR << msg << endmsg; - log << MSG::ERROR << System::typeinfoName(typeid(e)) << ": " - << e.what() << endmsg; - } -} - -#include "GaudiKernel/Sleep.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBAccessSvc -// -// 2005-01-11 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBAccessSvc::CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc): - base_class(name,svcloc), - m_coolConfSvc(0), - m_cache(0), - m_rndmSvc(0), - m_latestHeartBeat(0) -{ - declareProperty("ConnectionString", m_connectionString = "" ); - declareProperty("DefaultTAG", m_dbTAG = "" ); - declareProperty("NoDB", m_noDB = false ); - declareProperty("UseCache", m_useCache = true ); - declareProperty("CacheLowLevel", m_cacheLL = 10 ); - declareProperty("CacheHighLevel", m_cacheHL = 100 ); - //declareProperty("CachePreload", m_cachePreload=3600*1E9); // ns - declareProperty("CheckTAGTrials", m_checkTagTrials = 1 ); - declareProperty("CheckTAGTimeOut", m_checkTagTimeOut = 60 ); - declareProperty("ReadOnly", m_readonly = true ); - - declareProperty("ConnectionTimeOut", m_connectionTimeOutProp = 120 ); - - declareProperty("LazyConnect", m_lazyConnect = true ); - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); - declareProperty("HeartBeatCondition", m_heartBeatCondition = ""); - - declareProperty("QueryGranularity", m_queryGranularity = 0, - "Granularity of the query in the database (in time units), " - "to allow bulk retrievals."); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBAccessSvc::~CondDBAccessSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBAccessSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if (m_connectionTimeOutProp) { - m_connectionTimeOut = boost::posix_time::seconds(m_connectionTimeOutProp); - } else { - m_connectionTimeOut = boost::posix_time::pos_infin; - } - - if ( m_noDB && !m_useCache ) { - log << MSG::ERROR << "Database access disabled and cache off: I cannot work like that. Ciao!" << endmsg; - return StatusCode::FAILURE; - } - - if ( !m_noDB ) { - if ( connectionString() == "" ) { - // we need a connection string to connect to the DB - log << MSG::ERROR << "Connection to database requested and no connection string provided." << endmsg; - log << MSG::ERROR << "Set the option \"" << name() << ".ConnectionString\"." << endmsg; - return StatusCode::FAILURE; - } - - if ( ! m_lazyConnect ) { - sc = i_initializeConnection(); - if (!sc.isSuccess()) return sc; - } - - } - else { - log << MSG::INFO << "Database not requested: I'm not trying to connect" << endmsg; - } - - // set up cache if needed - if (m_useCache) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize CondDB cache." << endmsg; - m_cache = new CondDBCache(MsgStream(msgSvc(), name() + ".Cache"), - m_cacheHL, m_cacheLL); - if (m_cache == NULL) { - log << MSG::ERROR << "Unable to initialize CondDB cache." << endmsg; - return StatusCode::FAILURE; - } - // when we do bulk retrievals it is normal to have overlaps when inserting objects - // into the cache - m_cache->setSilentConflicts(m_queryGranularity > 0); - - } else { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "CondDB cache not needed" << endmsg; - m_cache = NULL; - } - if ( m_xmlDirectMapping && ! m_useCache ) { - // @todo: make it possible to use the direct mapping without cache - log << MSG::FATAL << "Cannot use direct XML mapping without cache (YET)" << endmsg; - return StatusCode::FAILURE; - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { - if (!m_heartBeatCondition.empty()) { - log << MSG::DEBUG << "Using heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; - } - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBAccessSvc::finalize(){ - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(), name() ); - log << MSG::DEBUG << "Finalize" << endmsg; - } - - // stop TimeOut thread - i_stopTimeoutChecker(); - - // release the database - m_db.reset(); - if (m_useCache) { - // dump the content of the cache - m_cache->dump(); - // dispose of the cache manager - delete m_cache; - } - if ( m_rndmSvc ) m_rndmSvc->release(); - - return base_class::finalize(); -} - -//============================================================================= -// Connect to the database -//============================================================================= -StatusCode CondDBAccessSvc::i_initializeConnection(){ - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(), name() ); - log << MSG::DEBUG << "Connection string = \"" << connectionString() << "\"" << endmsg; - } - - StatusCode sc = i_openConnection(); - if (!sc.isSuccess()) return sc; - - // start TimeOut thread - i_startTimeoutChecker(); - - return i_validateDefaultTag(); -} - -//============================================================================= -// Connect to the database -//============================================================================= -StatusCode CondDBAccessSvc::i_openConnection(){ - MsgStream log(msgSvc(), name() ); - - try { - if (! m_db) { // The database is not yet opened - - if ( !m_coolConfSvc ) { - StatusCode sc = service("COOLConfSvc",m_coolConfSvc,true); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot get COOLConfSvc" << endmsg; - return sc; - } - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Get cool::DatabaseSvc" << endmsg; - cool::IDatabaseSvc &dbSvc = m_coolConfSvc->databaseSvc(); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { - log << MSG::DEBUG << "cool::DatabaseSvc got" << endmsg; - log << MSG::DEBUG << "Opening connection" << endmsg; - } - m_db = dbSvc.openDatabase(connectionString(),m_readonly); - - } - else { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Database connection already established!" << endmsg; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieve the root folderset." << endmsg; - m_rootFolderSet = m_db->getFolderSet("/"); - } - // catch ( cool::DatabaseDoesNotExist &e ) { - catch ( coral::Exception &e ) { - report_exception(log,"Problems opening database",e); - m_db.reset(); - return StatusCode::FAILURE; - } - catch ( cool::Exception &e ) { - report_exception(log,"Problems opening database",e); - m_db.reset(); - return StatusCode::FAILURE; - } - - touchLastAccess(); - log << MSG::INFO << "Connected to database \"" << connectionString() << "\"" << endmsg; - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::i_validateDefaultTag() { - MsgStream log(msgSvc(), name() ); - - // Check the existence of the provided tag. - StatusCode sc = i_checkTag(); - - // Try again if requested - int trials_to_go = m_checkTagTrials - 1; // take into account the trial just done - while (!sc.isSuccess() && (trials_to_go > 0)){ - log << MSG::INFO << "TAG \"" << tag() << "\" not ready, I try again in " << m_checkTagTimeOut << "s. " - << trials_to_go << " trials left." << endmsg; - Gaudi::Sleep(m_checkTagTimeOut); - sc = i_checkTag(); - --trials_to_go; - } - - // Fail if the tag is not found - if (!sc.isSuccess()){ - log << MSG::ERROR << "Bad TAG given: \"" << tag() << "\" not in the database" << endmsg; - return sc; - } - log << MSG::INFO << "Using TAG \"" << tag() << "\"" << endmsg; - return StatusCode::SUCCESS; -} -//============================================================================= -// TAG handling -//============================================================================= -const std::string &CondDBAccessSvc::tag() const { return m_dbTAG; } -StatusCode CondDBAccessSvc::setTag(const std::string &_tag){ - - if (m_dbTAG == _tag) return StatusCode::SUCCESS; // no need to change - - StatusCode sc = i_checkTag(_tag); - if ( sc.isSuccess() ) { - m_dbTAG = _tag; - // the cache must be cleared if the tag is changed - clearCache(); - MsgStream log(msgSvc(), name() ); - log << MSG::WARNING << "TAG changed to \"" << _tag << "\"" << endmsg; - } else { - MsgStream log(msgSvc(), name() ); - log << MSG::WARNING << "Unable to set TAG \"" << _tag - << "\": not in the DB. (Still using \"" << tag() << "\")" << endmsg; - } - return sc; -} -StatusCode CondDBAccessSvc::i_checkTag(const std::string &tag) const { - - MsgStream log(msgSvc(), name() ); - if ( !m_db ) { - log << MSG::ERROR << "Check tag \"" << tag - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Check availability of tag \"" << tag << "\"" << endmsg; - /// @TODO: check all sub-nodes to validate the tag and not only the root - if (m_rootFolderSet) { - // HEAD tags are always good - //if ( (tag.empty()) || (tag == "HEAD") ) return StatusCode::SUCCESS; - if ( cool::IHvsNode::isHeadTag(tag) ) { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "\"" << tag << "\" is a HEAD tag: OK" << endmsg; - return StatusCode::SUCCESS; - } - // try to resolve the tag (it cannot be checked) - try { - try { - m_rootFolderSet->resolveTag(tag); - } catch (cool::NodeRelationNotFound) { - // to be ignored: it means that the tag exists, but somewhere else. - } catch (coral::AttributeException) { // FIXME: COOL bug #38422 - // to be ignored: it means that the tag exists, but somewhere else. - } - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "\"" << tag << "\" found: OK" << endmsg; - return StatusCode::SUCCESS; - } catch (cool::TagNotFound &) { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "\"" << tag << "\" NOT found" << endmsg; - return StatusCode::FAILURE; - } - catch (cool::TagRelationNotFound &e) { - log << MSG::ERROR << "got a cool::TagRelationNotFound : " << e.what() << endmsg; - return StatusCode::FAILURE; - } - catch (std::exception &e) { - report_exception(log,"got exception",e); - return StatusCode::FAILURE; - } - - } - return StatusCode::FAILURE; -} - - -//============================================================================= -// Return the connection string used to connect to the database. -//============================================================================= -const std::string &CondDBAccessSvc::connectionString() const{ - return m_connectionString; -} - -//============================================================================= -// Utilities -//============================================================================= -StatusCode CondDBAccessSvc::createNode(const std::string &path, - const std::string &descr, - StorageType storage, - VersionMode vers) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot create node in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - try { - switch (storage) { - case FOLDERSET: - m_db->createFolderSet(path,descr,true); - break; - case XML: - { - cool::FolderSpecification spec((vers == SINGLE) - ?cool::FolderVersioning::SINGLE_VERSION - :cool::FolderVersioning::MULTI_VERSION, - CondDB::getXMLStorageSpec()); - - // append to the description the storage type - std::ostringstream _descr; - _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - m_db->createFolder(path, - spec, - _descr.str(), - true); - } - break; - default: - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": unknown StorageType" << endmsg; - return StatusCode::FAILURE; - } - } catch(cool::NodeExists &){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the node already exists" << endmsg; - return StatusCode::FAILURE; - } catch(cool::Exception &e){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::createNode(const std::string &path, - const std::string &descr, - const std::set<std::string> &fields, - StorageType storage, - VersionMode vers) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot create node in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - try { - switch (storage) { - case FOLDERSET: - m_db->createFolderSet(path,descr,true); - break; - case XML: - { - cool::RecordSpecification recSpec; - for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ - recSpec.extend(*f, cool::StorageType::String16M); - } - cool::FolderSpecification spec((vers == SINGLE) - ?cool::FolderVersioning::SINGLE_VERSION - :cool::FolderVersioning::MULTI_VERSION, - recSpec); - - // append to the description the storage type - std::ostringstream _descr; - _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - m_db->createFolder(path, - spec, - _descr.str(), - true); - } - break; - default: - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": unknown StorageType" << endmsg; - return StatusCode::FAILURE; - } - } catch(cool::NodeExists &){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the node already exists" << endmsg; - return StatusCode::FAILURE; - } catch(cool::Exception &e){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot store in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the object \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - try { - // retrieve folder pointer - cool::IFolderPtr folder = m_db->getFolder(path); - cool::Record payload(folder->payloadSpecification()); - payload["data"].setValue<cool::String16M>(data); - folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); - - } catch (cool::FolderNotFound &) { - - MsgStream log(msgSvc(), name() ); - if (m_db->existsFolderSet(path)) - log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << - path << '\"' << endmsg; - else - log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - - } catch (cool::Exception &e){ - - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the XML string into \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot store in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the object \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - try { - // retrieve folder pointer - cool::IFolderPtr folder = m_db->getFolder(path); - cool::Record payload(folder->payloadSpecification()); - for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ - payload[d->first].setValue<cool::String16M>(d->second); - } - - folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); - - } catch (cool::FolderNotFound &) { - - MsgStream log(msgSvc(), name() ); - if (m_db->existsFolderSet(path)) - log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << - path << '\"' << endmsg; - else - log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - - } catch (cool::Exception &e){ - - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the XML string into \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - - } - return StatusCode::SUCCESS; -} - -cool::ValidityKey CondDBAccessSvc::timeToValKey(const Gaudi::Time &time) const { - // ValidityKey is an uInt64 of which only 63 bits used (0 -> 9223372036854775807), - // while time.ns() is a positive signed Int64! (the same thing) - return time.ns(); -} - -Gaudi::Time CondDBAccessSvc::valKeyToTime(const cool::ValidityKey &key) const { - return Gaudi::Time(key); -} - -StatusCode CondDBAccessSvc::tagLeafNode(const std::string &path, const std::string &tagName, - const std::string &description) { - MsgStream log(msgSvc(),name()); - - if ( m_readonly ) { - log << "Cannot tag in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - log << MSG::ERROR << "Unable to tag the leaf node \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - try { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering tagLeafNode: \"" << path << '"' << endmsg; - - cool::IFolderPtr folder = m_db->getFolder(path); - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION){ - log << MSG::WARNING << "Not tagging leaf node \"" << path << "\": single-version" << endmsg; - } else { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Tagging leaf node \"" << path << "\": " << tagName << endmsg; - folder->tagCurrentHead(tagName, description); - } - - } catch (cool::FolderNotFound &) { - - if (m_db->existsFolderSet(path)) - log << MSG::ERROR << "Node \"" << path << "\" is not leaf." << endmsg; - else - log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - - } catch (cool::Exception &e){ - - log << MSG::ERROR << "Unable tag leaf node \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - - } - - return StatusCode::SUCCESS; -} - -std::string CondDBAccessSvc::generateUniqueTagName(const std::string &base, - const std::set<std::string> &reserved) const { - - if ( !m_db->isOpen() ) { - throw GaudiException("Database not open","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); - } - if ( ! m_rndmSvc ) { - IRndmGenSvc *svc; - StatusCode sc = service("RndmGenSvc",svc,true); - const_cast<CondDBAccessSvc*>(this)->m_rndmSvc = svc; - if ( ! sc.isSuccess() ) { - throw GaudiException("Cannot get a pointer to RndmGenSvc","CondDBAccessSvc::generateUniqueTagName",sc); - } - } - - std::string tag = ""; - do { - // start with the signature - tag = "_auto_"; - // add the base, if any - if (!base.empty()) tag += base + "-"; - // append 6 randomly chosen chars in set [0-9A-Za-z] - for ( int i = 0; i<6; ++i ) { - char c=(char) ( 62.0 * m_rndmSvc->engine()->rndm() ); - if ( c > 61 ) GaudiException("Generator failure","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); // c %= 62; - if ( c >= 36 ) tag += c + 61; - else if ( c >= 10 ) tag += c + 55; - else tag += c + 48; - } - // check if the random name already exists or is reserved - } while ( m_db->existsTag(tag) || (reserved.find(tag) != reserved.end()) ); - - return tag; -} - - -StatusCode CondDBAccessSvc::recursiveTag(const std::string &path, const std::string &tagName, - const std::string &description) { - std::set<std::string> reserved; - DataBaseOperationLock dbLock(this); - return i_recursiveTag(path,tagName,description,tagName,reserved); -} - -StatusCode CondDBAccessSvc::i_recursiveTag(const std::string &path, const std::string &base, - const std::string &description, - const std::string &tagName, - std::set<std::string> &reserved) { - MsgStream log(msgSvc(),name()); - - if ( m_readonly ) { - log << MSG::ERROR << "Cannot tag in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - log << MSG::ERROR << "Unable to tag the inner node \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - try { - // start reserving the tag name we want to apply to the current folderset - reserved.insert(tagName); - - // get the list of child nodes (both types) - cool::IFolderSetPtr this_folderset = m_db->getFolderSet(path); - std::vector<std::string> folders = this_folderset->listFolders(); - std::vector<std::string> foldersets = this_folderset->listFolderSets(); - - // loop over leaf nodes and apply the tags - std::vector<std::string>::iterator f; - for ( f = folders.begin(); f != folders.end(); ++f ) { - - std::string auto_tag = generateUniqueTagName(base,reserved); - cool::IFolderPtr child_folder = m_db->getFolder(*f); - - if (child_folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION) { - // only multi-version folders can be tagged - child_folder->tagCurrentHead(auto_tag, description); - // associate the child folder tag with the parent one - child_folder->createTagRelation(tagName, auto_tag); - } - - } - - // loop over inner nodes and recurse - for ( f = foldersets.begin(); f != foldersets.end(); ++f ) { - - std::string auto_tag = generateUniqueTagName(base,reserved); - StatusCode sc = i_recursiveTag(*f,base,description,auto_tag,reserved); - if (!sc.isSuccess()) return sc; - - cool::IFolderSetPtr child_folderset = m_db->getFolderSet(*f); - child_folderset->createTagRelation(tagName, auto_tag); - - } - } - catch (cool::FolderSetNotFound &) { - if (m_db->existsFolder(path)) - log << MSG::ERROR << "Node \"" << path << "\" is a leaf." << endmsg; - else - log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - } - catch (cool::Exception &e) { - log << MSG::ERROR << "Problems tagging" << endmsg; - log << MSG::ERROR << e.what() << endmsg; - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - cool::ChannelId channel){ - return i_getObject(path, when, data, descr, since, until, - true, channel, ""); -} - -StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - const std::string &channel){ - return i_getObject(path, when, data, descr, since, until, - false, 0, channel); -} -/* -namespace { - ICondDBReader::IOVList getHoles(const ICondDBReader::IOV& iov, const ICondDBReader::IOVList& data){ - typedef ICondDBReader::IOVList IOVList; - typedef ICondDBReader::IOV IOV; - IOVList result; - - Gaudi::Time last = iov.since; // keep track of the end of coverage - // loop over covering interval - for (IOVList::const_iterator covered = data.begin(); covered != data.end(); ++covered) { - if (covered->since > last) { // hole between the end of coverage and begin of next IOV - result.push_back(IOV(last, covered->since)); - } - last = covered->until; // prepare to look for the next hole - } - if (last < iov.until) { - // we didn't get anything to cover until the end of the requested IOV - result.push_back(IOV(last, iov.until)); - } - - return result; - } -} -*/ - -ICondDBReader::IOVList CondDBAccessSvc::i_getIOVsFromDB(const std::string & path, const IOV &iov, cool::ChannelId channel) { - ICondDBReader::IOVList result; - try { - DataBaseOperationLock dbLock(this); - // we want a folder, so go to the database to get it - cool::IFolderPtr folder = database()->getFolder(path); - cool::IObjectIteratorPtr objects; - - // FIXME: we need to considered the query granularity - // Note: IFolder::browseObject returns the objects valid up to the 'until' - // included, which means that asking for [1,10] will return also the - // object starting at 10, so, to exclude it we need to ask for [1,9]. - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION - || tag().empty() || tag() == "HEAD" ){ - objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel); - } else { - objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel, folder->resolveTag(tag())); - } - - if (!objects->isEmpty()) {// check if we managed to find anything - while (objects->goToNext()) { - // add data to the cache while filling the list of IOVs - const cool::IObject &obj = objects->currentRef(); - m_cache->insert(folder, obj, channel); - result.push_back(ICondDBReader::IOV(Gaudi::Time(obj.since()), Gaudi::Time(obj.until()))); - } - } - } catch(cool::FolderNotFound &/*e*/) { - // ignore - } catch (cool::TagRelationNotFound &/*e*/) { - // ignore - } catch (cool::NodeRelationNotFound &) { - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - } - return result; -} - -ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - typedef ICondDBReader::IOVList IOVList; - IOVList result; - if (m_useCache){ - /// Look for holes in the timeline of the cache - result = m_cache->getIOVs(path, iov, channel); - IOVList holes = IOVListHelpers::find_holes(result, iov); - for(IOVList::iterator hole = holes.begin(); hole != holes.end(); ++hole) { - const IOVList cover = i_getIOVsFromDB(path, *hole, channel); - result.insert(result.end(), cover.begin(), cover.end()); - } - std::sort(result.begin(), result.end()); - } else { - result = i_getIOVsFromDB(path, iov, channel); - } - return result; -} - -ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - cool::ChannelId id; - if (m_useCache){ - // Check if the cache knows about the path - if (m_cache->hasPath(path)) { - // the folder is in the cache - if (m_cache->getChannelId(path, channel, id)) { - return getIOVs(path, iov, id); // we know about the folder and the channel - } else { - return ICondDBReader::IOVList(); // we know about the folder, but not about the channel - } - } - } - - // the folder is not in the cache or we do not use the cache, so we have to - // get the channel id from the DB - try { - DataBaseOperationLock dbLock(this); - cool::IFolderPtr folder = database()->getFolder(path); - id = folder->channelId(channel); - } catch(cool::FolderNotFound &/*e*/) { - return ICondDBReader::IOVList(); // unknown folder - } catch(cool::InvalidChannelName &/*e*/) { - return ICondDBReader::IOVList(); // unknown channel - } - return getIOVs(path, iov, id); -} - -StatusCode CondDBAccessSvc::i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, - DataPtr &data, - std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, - bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ - try { - - bool existsFolderSet = false; - { - DataBaseOperationLock dbLock(this); - existsFolderSet = database()->existsFolderSet(path); - } - // Check if the user asked for a folderset - if (existsFolderSet) { - if ( !m_xmlDirectMapping ) { - // with FolderSets, I put an empty entry and clear the shared_ptr - if (m_useCache) m_cache->addFolderSet(path,""); - data.reset(); - } else { - // Using XML direct mapping, foldersets are replaced in the cache - // with the XML equivalent (a catalog). - i_generateXMLCatalogFromFolderset(path); - // now get the data from the cache - m_cache->get(path,when,channel,since,until,descr,data); - } - - return StatusCode::SUCCESS; - } - else { - // Special retrieval procedure if we use "query granularity" (make sense - // only when using the cache). - if (m_useCache && m_queryGranularity > 0){ - // modify the range rounding it to the requested granularity (if needed) - // Range used for the query - cool::ValidityKey sinceWhen = when, untilWhen = when; - - sinceWhen -= when % m_queryGranularity; - untilWhen = sinceWhen + m_queryGranularity; - - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(),name()); - log << MSG::DEBUG << "Retrieving conditions in range " - << sinceWhen << " - " << untilWhen << endmsg; - } - - DataBaseOperationLock dbLock(this); - // we want a folder, so go to the database to get it - cool::IFolderPtr folder = database()->getFolder(path); - cool::IObjectIteratorPtr objects; - if ( !use_numeric_chid ) { // we need to convert from name to id - channel = folder->channelId(channelstr); - } - - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION - || tag().empty() || tag() == "HEAD" ){ - objects = folder->browseObjects(sinceWhen, untilWhen, channel); - } else { - objects = folder->browseObjects(sinceWhen, untilWhen, channel, folder->resolveTag(tag())); - } - - if (objects->isEmpty()) // check if we managed to find anything - return StatusCode::FAILURE; - - while (objects->goToNext()) { - m_cache->insert(folder, objects->currentRef(), channel); - } - // now get the data from the cache - m_cache->get(path, when, channel, since, until, descr, data); - - } else { // no-cache or no granularity are quite similar - - DataBaseOperationLock dbLock(this); - // we want a folder, so go to the database to get it - cool::IFolderPtr folder = database()->getFolder(path); - cool::IObjectPtr object; - if ( !use_numeric_chid ) { // we need to convert from name to id - channel = folder->channelId(channelstr); - } - - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION - || tag().empty() || tag() == "HEAD" ){ - object = folder->findObject(when, channel); - } else { - object = folder->findObject(when, channel, folder->resolveTag(tag())); - } - - if (m_useCache) { - // add the object to the cache - m_cache->insert(folder, *object, channel); - // and get the data back - m_cache->get(path, when, channel, since, until, descr, data); - } else { - data = DataPtr(new cool::Record(object->payload())); - descr = folder->description(); - since = object->since(); - until = object->until(); - } - } - } - } catch ( cool::FolderNotFound &/*e*/) { - //log << MSG::ERROR << e << endmsg; - return StatusCode::FAILURE; - } catch (cool::TagRelationNotFound &/*e*/) { - return StatusCode::FAILURE; - } catch (cool::ObjectNotFound &/*e*/) { - //log << MSG::ERROR << "Object not found in \"" << path << - // "\" for tag \"" << (*accSvc)->tag() << "\" ("<< now << ')' << endmsg; - //log << MSG::DEBUG << e << endmsg; - return StatusCode::FAILURE; - } catch (cool::NodeRelationNotFound &) { - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - return StatusCode::FAILURE; - } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - return StatusCode::FAILURE; - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::i_getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ - - cool::ValidityKey vk_when = timeToValKey(when); - cool::ValidityKey vk_since = 0, vk_until = 0; - - // This is not in i_getObjectFromDB because I need to ensure that m_latestHeartBeat - // is correctly set even when using the cache. - if (vk_when >= i_latestHeartBeat()) { - MsgStream log(msgSvc(), name()); - const Gaudi::Time hb = valKeyToTime(i_latestHeartBeat()); - log << MSG::ERROR << "Database not up-to-date. Latest known update is at " - << hb.format(false, "%Y-%m-%d %H:%M:%S") << "." << hb.nanoformat() - << " UTC, event time is " - << when.format(false, "%Y-%m-%d %H:%M:%S") << "." << when.nanoformat() - << " UTC" << endmsg; - return StatusCode::FAILURE; - } - - if (m_useCache) { - - // Check if the cache knows about the path - if ( m_cache->hasPath(path) ) { - - // the folder is in the cache - if ( !use_numeric_chid ) { // we need to convert from name to id - if (!m_cache->getChannelId(path,channelstr,channel)) { - // the channel name cannot be found in the cached folder - return StatusCode::FAILURE; - } - } - - if ( m_cache->get(path,vk_when,channel,vk_since,vk_until,descr,data) ) { - since = valKeyToTime(vk_since); - /// Artificially cutting the end of validity of the retrieved object to - /// the latest know heart beat guarantees that we will have to go back - /// to the database when the event time exceeds it. - /// Note that we are not calling i_latestHeartBeat() on purpose: - /// it returns +inf if called during initialize, but it sets - /// correctly the variable m_latestHeartBeat. - until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); - return StatusCode::SUCCESS; - } - } - - } - // If we get here, either we do not know about the folder, we didn't - // find the object, or we are not using the cache, so let's try the DB - if (m_noDB) { - // oops... we are not using the db: no way of getting the object from it - return StatusCode::FAILURE; - } - - StatusCode sc = i_getObjectFromDB(path,vk_when,data,descr,vk_since,vk_until,use_numeric_chid,channel,channelstr); - since = valKeyToTime(vk_since); - /// Artificially cutting the end of validity of the retrieved object to - /// the latest know heart beat guarantees that we will have to go back - /// to the database when the event time exceeds it. - /// Note that we are not calling i_latestHeartBeat() on purpose: - /// it returns +inf if called during initialize, but it sets - /// correctly the variable m_latestHeartBeat. - until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); - return sc; -} - -namespace { - // Small helper function to reduce duplications - inline void cannotGetHeartBeatError(CondDBAccessSvc *self, const std::string&path) { - MsgStream log(self->msgSvc(), self->name()); - log << MSG::ERROR << "Cannot get latest heart beat (" << path - << ") in the database" << endmsg; - } -} -const cool::ValidityKey& CondDBAccessSvc::i_latestHeartBeat() -{ - if (m_latestHeartBeat == 0) { - if (m_heartBeatCondition.empty() || - m_noDB) { // it doesn't make sense to ask for a heart beat if we do not use the DB - // no heart beat condition: the database is always valid - m_latestHeartBeat = cool::ValidityKeyMax; - } else { - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(),name()); - log << MSG::DEBUG << "Retrieving heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; - } - // we do not use the normal functions to retrieve the object because - // we want to by-pass the cache - try { - DataBaseOperationLock dbLock(this); - cool::IFolderPtr folder = database()->getFolder(m_heartBeatCondition); - cool::IObjectPtr obj = folder->findObject(cool::ValidityKeyMax-1, 0); - m_latestHeartBeat = obj->since(); - } - catch (cool::Exception &) { - cannotGetHeartBeatError(this, m_heartBeatCondition); - m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database - } - catch (coral::Exception &) { - cannotGetHeartBeatError(this, m_heartBeatCondition); - m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database - } - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(),name()); - log << MSG::DEBUG << "Latest heart beat at " << m_latestHeartBeat << endmsg; - } - } - } - if (FSMState() != Gaudi::StateMachine::RUNNING) { - // Temporarily consider the database valid if not running - // (e.g. during initialize). - // Note that the retrieve is done (and must be done) anyway, - // because it is needed by i_getObject(). - return cool::ValidityKeyMax; - } - return m_latestHeartBeat; -} - - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) { - MsgStream log(msgSvc(),name()); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; - - folders.clear(); - foldersets.clear(); - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - if (database()->existsFolderSet(path)) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "FolderSet \"" << path << "\" exists" << endmsg; - - cool::IFolderSetPtr folderSet = database()->getFolderSet(path); - - std::vector<std::string> fldr_names = folderSet->listFolders(); - std::vector<std::string> fldrset_names = folderSet->listFolderSets(); - - for ( std::vector<std::string>::iterator f = fldr_names.begin(); f != fldr_names.end(); ++f ) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << *f << endmsg; - // Check if folder is tagged with a tag set to load db with. - cool::IFolderPtr folder = database()->getFolder(*f); - if (folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION){ - try{ - folder->resolveTag(tag()); - folders.push_back(f->substr(f->rfind('/')+1)); - } catch (cool::TagRelationNotFound &) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Tag '" << tag() - << "' relation was not found for ': "<< *f << "' folder" << endmsg; - } catch (cool::ReservedHeadTag &) { - //to be ignored: 'HEAD' tag is in every node - folders.push_back(f->substr(f->rfind('/')+1)); - } catch (cool::NodeRelationNotFound &) { - //to be ignored: it means that the tag exists, but it is not in the node '/'. - } catch (coral::AttributeException &) { // FIXME: COOL bug #38422. To be ignored: - //it means that the tag exists, but it is not in the node '/'. - } catch (coral::Exception &e) { - report_exception(log,"got CORAL exception",e); - folders.push_back(f->substr(f->rfind('/')+1)); - } - } else { //add folder if it is single version without tag verification - folders.push_back(f->substr(f->rfind('/')+1)); - } - } - - for ( std::vector<std::string>::iterator f = fldrset_names.begin(); f != fldrset_names.end(); ++f ) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << *f << endmsg; - foldersets.push_back(f->substr(f->rfind('/')+1)); - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { - log << MSG::DEBUG << "got " << folders.size() << " sub folders" << endmsg; - log << MSG::DEBUG << "got " << foldersets.size() << " sub foldersets" << endmsg; - } - - } else { - // cannot get the sub-nodes of a folder! - return StatusCode::FAILURE; - } - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - m_cache->getSubNodes(path,folders,foldersets); - } else { - // no cache and no db - return StatusCode::FAILURE; - } - } catch ( cool::FolderNotFound &/*e*/) { - //log << MSG::ERROR << e << endmsg; - return StatusCode::FAILURE; - } catch (coral::Exception &e) { - report_exception(log,"got CORAL exception",e); - } - return StatusCode::SUCCESS; - - -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { - - std::vector<std::string> temp; - StatusCode sc = getChildNodes(path, node_names, temp); - if (sc.isSuccess()) - node_names.insert(node_names.end(), temp.begin(), temp.end()); - return sc; - -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBAccessSvc::exists(const std::string &path) { - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - return database()->existsFolderSet(path) || database()->existsFolder(path); - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - return m_cache->hasPath(path); - } - - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - // if we do not have neither DB nor cache, or we got an exception - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBAccessSvc::isFolder(const std::string &path) { - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - return database()->existsFolder(path); - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - return m_cache->isFolder(path); - } - - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - // if we do not have neither DB nor cache, or we got an exception - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBAccessSvc::isFolderSet(const std::string &path) { - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - return database()->existsFolderSet(path); - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - return m_cache->isFolderSet(path); - } - - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - // if we do not have neither DB nor cache, or we got an exception - return false; -} - -//========================================================================= -// Disconnect from the database. -//========================================================================= -void CondDBAccessSvc::disconnect() { - boost::mutex::scoped_lock busy_lock(m_busy); - if ( database() && database()->isOpen() ) { - if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { - debug() << "Forced disconnect from database (will reconnect automatically)" << endmsg; - } - database()->closeDatabase(); - } else if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { - debug() << "Database already disconnected" << endmsg; - } - i_stopTimeoutChecker(); -} - -//========================================================================= -// Add database name and TAG to the passed vector. -//========================================================================= -void CondDBAccessSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - /// @todo This should be something like - /// <quote> - /// tags.push_back(LHCb::CondDBNameTagPair(database()->dbName(),tag())); - /// </quote> - /// but COOL API does not provide that function yet. (Available since 2.2.0) - - std::string dbName; - // Parsing of COOL connection string to find database name - // - first type: <tech>://<server>;schema=<schema>;dbname=<dbname> - std::string::size_type pos = connectionString().find("dbname="); - if ( std::string::npos != pos ) { - pos += 7; - std::string::size_type pos2 = connectionString().find(';',pos); - if ( std::string::npos != pos2 ) - dbName = connectionString().substr(pos,pos2-pos); - else - dbName = connectionString().substr(pos); - } else { - // - second type: <alias>/<dbname> - pos = connectionString().find_last_of('/'); - if ( std::string::npos != pos ) { - dbName = connectionString().substr(pos+1); - } else { - throw GaudiException("Cannot understand COOL connection string", - "CondDBAccessSvc::defaultTags",StatusCode::FAILURE); - } - } - // If the tag is a "HEAD" tag, I want to show "HEAD" - std::string tagName = tag(); - if (cool::IHvsNode::isHeadTag(tagName)) { - tagName = "HEAD"; - } - - tags.push_back(LHCb::CondDBNameTagPair(dbName,tagName)); - -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec) { - if (!m_useCache) { - MsgStream log(msgSvc(),name()); - log << MSG::ERROR << "Cache not in use: I cannot add a folder to it." << endmsg; - return StatusCode::FAILURE; - } - return m_cache->addFolder(path,descr,spec) ? StatusCode::SUCCESS : StatusCode::FAILURE; -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddFolderSet(const std::string &path, const std::string &descr) { - if (!m_useCache) { - MsgStream log(msgSvc(),name()); - log << MSG::ERROR << "Cache not in use: I cannot add a folder-set to it." << endmsg; - return StatusCode::FAILURE; - } - return m_cache->addFolderSet(path,descr) ? StatusCode::SUCCESS : StatusCode::FAILURE; -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path) { - std::ostringstream _descr; - _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - return cacheAddFolder(path,_descr.str(),CondDB::getXMLStorageSpec()); -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) { - std::ostringstream _descr; - _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - cool::RecordSpecification spec; - for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ - spec.extend(*f, cool::StorageType::String16M); - } - return cacheAddFolder(path,_descr.str(),spec); -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const cool::IRecord& payload, cool::ChannelId channel) { - if (!m_useCache) { - MsgStream log(msgSvc(),name()); - log << MSG::ERROR << "Cache not in use: I cannot add an object to it." << endmsg; - return StatusCode::FAILURE; - } - return m_cache->addObject(path,timeToValKey(since),timeToValKey(until),payload,channel) - ? StatusCode::SUCCESS - : StatusCode::FAILURE; -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string &data, cool::ChannelId channel) { - /// @todo this is affected by the evolution in COOL API - cool::Record payload(CondDB::getXMLStorageSpec()); - payload["data"].setValue<cool::String16M>(data); - return cacheAddObject(path,since,until,payload,channel); -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::map<std::string,std::string> &data, cool::ChannelId channel) { - cool::RecordSpecification spec; - for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ - spec.extend(d->first,cool::StorageType::String16M); - } - - cool::Record payload(spec); - - for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ - payload[d->first].setValue<cool::String16M>(d->second); - } - return cacheAddObject(path,since,until,payload,channel); -} - -//========================================================================= -// -//========================================================================= -void CondDBAccessSvc::clearCache() -{ - if (m_useCache) { - m_cache->clear(); - } -} - -//========================================================================= -// -//========================================================================= -void CondDBAccessSvc::dumpCache() const { - if (m_useCache) m_cache->dump(); -} - -//========================================================================= -// -//========================================================================= -void CondDBAccessSvc::i_generateXMLCatalogFromFolderset(const std::string &path){ - // Use the name of the folderset as catalog name. - std::string::size_type pos = path.rfind('/'); - if ( std::string::npos == pos ) { - pos = 0; // if we cannot find '/' let's take the whole string - } else { - ++pos; - } - std::string folderset_name = path.substr(pos); - - // Get the names of sub-folders and sub-foldersets - std::vector<std::string> fldr_names, fldrset_names; - getChildNodes(path, fldr_names, fldrset_names).ignore(); - - std::string xml; - CondDB::generateXMLCatalog(folderset_name,fldr_names,fldrset_names,xml); - - // Put the data in the cache - if ( ! m_cache->hasPath(path) ) - cacheAddXMLFolder(path); - - // This is needed because we cannot add objects valid for the current event - // to the cache using the ICondDBAccessSvc API. - bool check_enabled = m_cache->setIOVCheck(false); - cacheAddXMLData(path,Gaudi::Time::epoch(),Gaudi::Time::max(),xml,0).ignore(); - m_cache->setIOVCheck(check_enabled); - -} diff --git a/Det/DetCond/src/component/CondDBAccessSvc.h b/Det/DetCond/src/component/CondDBAccessSvc.h deleted file mode 100755 index 34e578470..000000000 --- a/Det/DetCond/src/component/CondDBAccessSvc.h +++ /dev/null @@ -1,506 +0,0 @@ -#ifndef COMPONENT_CONDDBACCESSSVC_H -#define COMPONENT_CONDDBACCESSSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "GaudiKernel/GaudiException.h" -#include "Kernel/ICondDBInfo.h" -#include "DetCond/ICondDBAccessSvc.h" -#include "DetCond/ICondDBReader.h" -#include "DetCond/ICondDBEditor.h" -#include <set> - -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/thread/thread.hpp> -#include <boost/thread/mutex.hpp> -#include <boost/thread/condition.hpp> -#include <boost/thread/thread_time.hpp> - -#include "CoolKernel/IDatabase.h" - -// Forward declarations -template <class TYPE> class SvcFactory; - -class CondDBCache; -class IRndmGenSvc; -class ICOOLConfSvc; - -namespace cool { - class Application; - class RecordSpecification; -} - -/** @class CondDBAccessSvc CondDBAccessSvc.h - * - * Class used as interface to LCG COOL library API. It should expose as less as - * possible COOL internal details. - * - * @author Marco Clemencic - * @date 2005-01-11 - */ - -class CondDBAccessSvc: public extends3<Service, - ICondDBAccessSvc, - ICondDBReader, - ICondDBEditor> { -public: - - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - /// (Version with alphanumeric channel id) - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags ) const; - - // --------- ICondDBEditor implementation - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - StorageType storage = XML, - VersionMode vers = MULTI) const; - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - const std::set<std::string> &fields, - StorageType storage = XML, - VersionMode vers = MULTI) const; - - /// Utility function that simplifies the storage of an XML string. - virtual StatusCode storeXMLData(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; - - /// Utility function that simplifies the storage of a set of XML strings. - virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; - - /// Tag the given leaf node with the given tag-name. - virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, - const std::string &description = ""); - - /// Tag the given inner node with the given tag-name, recursively tagging the head - /// of child nodes with automatically generated tag-names. - virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, - const std::string &description = ""); - - // --------- ICondDBAccessSvc implementation - - /// Used to obtain direct access to the database. - virtual cool::IDatabasePtr& database() { return m_db; } - - /// Convert from Gaudi::Time class to cool::ValidityKey. - virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const; - - /// Convert from cool::ValidityKey to Gaudi::Time class. - virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const; - - /// Return the currently set TAG to use. - virtual const std::string &tag() const; - - /// Set the TAG to use. - virtual StatusCode setTag(const std::string &_tag); - - /// Return the connection string used to connect to the database. - virtual const std::string &connectionString() const; - - /// Add a folder to the cache (bypass the DB) - virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec); - - /// Add a folder-set to the cache (bypass the DB) - virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr); - - /// Add a folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path); - - /// Add an XML folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields); - - ///Add an object to the cache (bypass the DB) - virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const cool::IRecord& payload, cool::ChannelId channel = 0); - - ///Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string& data, cool::ChannelId channel = 0); - - /// Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::map<std::string,std::string> &data, cool::ChannelId channel = 0); - - /// Clear the cache - virtual void clearCache(); - - /// Dump the cache (debug) - virtual void dumpCache() const; - -protected: - /// Standard constructor - CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc); - - virtual ~CondDBAccessSvc( ); ///< Destructor - -protected: - // Properties - - /// Property CondDBAccessSvc.ConnectionString: full connection string to open database access. - /// Format is: "<BackEnd>://<HostName>;schema=<Schema>;dbname=<Database>;[user=<User>;][password=<Password>;]" - /// or "<HostAlias>/<Database>". - std::string m_connectionString; - -private: - /// Property CondDBAccessSvc.DefaultTAG: which tag to use if none is specified - std::string m_dbTAG; - - /** Property CondDBAccessSvc.UseCache: store the retrieved informations into a cache for faster - later access. */ - bool m_useCache; - - /// Property CondDBAccessSvc.CacheLowLevel: minimum fill of the cache. - size_t m_cacheLL; - - /// Property CondDBAccessSvc.CacheHighLevel: maximum fill of the cache. - size_t m_cacheHL; - - /// Property CondDBAccessSvc.NoDB: do not use the database (cache must be on). - bool m_noDB; - - /// Property CondDBAccessSvc.ReadOnly: open the database as read-only (default: true). - bool m_readonly; - - /// Property CondDBAccessSvc.CheckTAGTrials: Number of times to retry the check on the tag (default = 1). - int m_checkTagTrials; - - /// Property CondDBAccessSvc.CheckTAGTimeOut: Seconds to sleep between one trial and the following (default = 60). - int m_checkTagTimeOut; - - /// Pointer to the service initializing COOL/CORAL. - ICOOLConfSvc *m_coolConfSvc; - - /// Shared pointer to the COOL database instance - cool::IDatabasePtr m_db; - - /// Shared pointer to the COOL database instance - cool::IFolderSetPtr m_rootFolderSet; - - /// Pointer to the cache manager - CondDBCache *m_cache; - - /// Pointer to the random generator service - IRndmGenSvc *m_rndmSvc; - - /// Lazy connection flag. - /// If true (the default), the connection to (lazy = connect only when needed). - bool m_lazyConnect; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Path in the condition database (not in the transient store) to be used as - /// heart-beat marker. - /// The latest update of the condition specified give information about when - /// the replica was last updated: We cannot guarantee that the database is more - /// "up to date" then the "since" field of the latest object in the heart-beat - /// condition. - std::string m_heartBeatCondition; - - /// Latest know update of the database ("since" field of the latest heart-beat condition). - /// Initialized to 0, if no heart-beat condition is requested, it is set to - /// cool::ValidityKeyMax, otherwise, during the first access to the DB, the - /// object valid until ValidityKeyMax is retrieved and its "since" field is - /// recorded in this variable. - /// When disconnected from the database, it is reset to 0 to force a re-check. - cool::ValidityKey m_latestHeartBeat; - - // ---------------------------------------------- - // ---------- Private Member Functions ---------- - // ---------------------------------------------- - - /// Connect to the COOL database. It sets 'm_db'. - StatusCode i_initializeConnection(); - - /// Connect to the COOL database. It sets 'm_db'. - StatusCode i_openConnection(); - - /// Internal method to retrieve an object. - StatusCode i_getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - bool use_numeric_chid, - cool::ChannelId channel, const std::string &channelstr); - - /// Internal method to retrieve an object from the database. - /// If the cache is activated, the result is copied there. - StatusCode i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, - DataPtr &data, - std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, - bool use_numeric_chid, - cool::ChannelId channel, const std::string &channelstr); - - /// Internal method to get the list of IOVs in a range. - /// @see ICondDBReader::getIOVs - IOVList i_getIOVsFromDB(const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - - void i_generateXMLCatalogFromFolderset(const std::string &path); - - /// Connect to the COOL database. It sets 'm_db'. - StatusCode i_validateDefaultTag(); - - /// Check if the TAG set exists in the DB. - inline StatusCode i_checkTag() const { return i_checkTag(tag()); } - - /// Check if the given TAG exists in the DB. - StatusCode i_checkTag(const std::string &tag) const; - - /// Generate a tag name that do not create conflicts in the DB. - /// Tagnames generated by this method will start with "_auto_". - /// If base value is passed to the method, the result will have - /// a "_auto_`base`-" prefix. - std::string generateUniqueTagName(const std::string &base, - const std::set<std::string> &reserved) const; - - /// Function used by recursiveTag to do the real work. - StatusCode i_recursiveTag(const std::string &path, - const std::string &base, - const std::string &description, - const std::string &tagName, - std::set<std::string> &reserved); - - - /// Return the value of m_latestHeartBeat. - /// The value is retrieved from the database when requested the first time - /// in the RUNNING state. - const cool::ValidityKey &i_latestHeartBeat(); - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBAccessSvc>; - - /// AttributeListSpecification used to sore XML strings - static std::unique_ptr<cool::RecordSpecification> s_XMLstorageSpec; - - /// Parameter controlling the granularity of the queries to the conditions database (in time units). - /// - /// When different from 0, instead of retrieving the only condition valid for the requested event time, - /// we will retrieve all the conditions valid for a range around the event time, rounded by the - /// granularity. - /// - /// For example, with granularity set to 1h and the event time 16:18:08, all the conditions valid for the - /// range 16:00:00 to 17:00:00 will be retrieved. - /// - /// \b Note: if the cache is not enabled the parameter has no effect. - cool::ValidityKey m_queryGranularity; - - // ------------------------------------- - // ---------- Time Out Thread ---------- - // ------------------------------------- - - /// Property CondDBAccessSvc.ConnectionTimeOut: How many seconds to keep the connection to the DB open after the - /// last access (default = 120, 0 means never). The connection will be started again if a new operation is performed. - int m_connectionTimeOutProp; - boost::posix_time::time_duration m_connectionTimeOut; - - /// Mutex to avoid conflicts between the main thread and the thread trying to close the connection. - boost::mutex m_busy; - - /// The time of last access. - boost::system_time m_lastAccess; - - /// Mutex to protect the last access time. - boost::mutex m_lastAccessMutex; - - /// Pointer to the second thread. - std::unique_ptr<boost::thread> m_timeOutCheckerThread; - - /// Function to set the last access time to "now". - inline void touchLastAccess() - { - boost::mutex::scoped_lock myLock(m_lastAccessMutex); - m_lastAccess = boost::get_system_time(); - } - - /// Get the last access time. - inline const boost::system_time &lastAccess() const - { - return m_lastAccess; - } - - /// Start the timeout checker thread, if requested. - inline void i_startTimeoutChecker() { - if ( UNLIKELY( (!m_timeOutCheckerThread) - && (!m_connectionTimeOut.is_pos_infinity()) ) ) { - m_timeOutCheckerThread.reset( new boost::thread(TimeOutChecker{this}) ); - } - } - - /// Stop the timeout checker thread if running. - inline void i_stopTimeoutChecker() { - if ( LIKELY( NULL != m_timeOutCheckerThread.get() ) ) { - m_timeOutCheckerThread->interrupt(); // tell the thread to stop - m_timeOutCheckerThread->join(); // wait for it - m_timeOutCheckerThread.reset(); // delete it - } - } - - /// Class executed in a separate thread to disconnect from the database if - /// a time-out is reached. - class TimeOutChecker - { - /// Pointer to the CondDBAccessSvc, used to acquire operation locks and - /// access parameters. - CondDBAccessSvc *m_owner; - /// Cached MsgStream to report messages. - MsgStream log; - - public: - TimeOutChecker(CondDBAccessSvc *owner): - m_owner(owner), - log(m_owner->msgSvc(),m_owner->name()+".TimeOutChecker") - { - } - - void operator () () - { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Starting" << endmsg; - - boost::system_time last_access = m_owner->lastAccess(); - - // set initial check time - boost::system_time next_check = last_access + m_owner->m_connectionTimeOut; - - try { - // enter infinite loop - while (true) { - // Wait until the next check point time is reached. - // An early exit must be triggered by a call to this->interrupt(), which - // will produce an exception during the sleep. - boost::thread::sleep(next_check); - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Time-out reached (" << next_check << ")" << endmsg; - - boost::mutex::scoped_lock busy_lock(m_owner->m_busy); - - if ( last_access == m_owner->lastAccess() ) { // no further accesses - - if ( m_owner->database()->isOpen() ) { // close the database - log << MSG::INFO << "Disconnect from database after being idle for " - << m_owner->m_connectionTimeOut.total_seconds() - << "s (will reconnect if needed)"<< endmsg; - m_owner->database()->closeDatabase(); - // reset the latest heart beat because it may be different the next time - // we connect to the DB - if (!m_owner->m_heartBeatCondition.empty()) m_owner->m_latestHeartBeat = 0; - } - - // schedule the next check for now + dt (seems a good estimate) - next_check = boost::get_system_time() + m_owner->m_connectionTimeOut; - - } else { - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Wait more" << endmsg; - - // schedule the next check for last_access + dt - next_check = last_access = m_owner->lastAccess(); - next_check += m_owner->m_connectionTimeOut; - } - } - } - // Ignore the exception since it is used only to exit from the loop. - catch (boost::thread_interrupted&) {} - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Stopping" << endmsg; - } - }; - - class DataBaseOperationLock - { - CondDBAccessSvc *m_owner; - MsgStream log; - boost::mutex::scoped_lock busy_lock; - public: - DataBaseOperationLock(const CondDBAccessSvc *owner): - m_owner(const_cast<CondDBAccessSvc*>(owner)), - log(m_owner->msgSvc(),m_owner->name()+".DataBaseOperationLock"), - busy_lock(m_owner->m_busy) // lock the access to the db - { - // If the database has not been instantiated yet, we may be using - // lazy connection and we have to connect now. - if (!m_owner->m_db) { - // we have to release the lock because i_initializeConnection - // needs to lock the DB - busy_lock.unlock(); - StatusCode sc = m_owner->i_initializeConnection(); - busy_lock.lock(); - if (! sc.isSuccess()) - throw GaudiException("Cannot initialize connection", - "DataBaseOperationLock::DataBaseOperationLock", - sc); - } - if (!m_owner->m_db->isOpen()){ - log << MSG::INFO << "Connecting to database" << endmsg; - m_owner->m_db->openDatabase(); // ensure that the db is open - m_owner->i_startTimeoutChecker(); // ensure that the timeout checker is running - } - } - - ~DataBaseOperationLock() - { - m_owner->touchLastAccess(); // update last access time - } - }; - - friend class TimeOutChecker; - friend class DataBaseOperationLock; - -}; -#endif // COMPONENT_CONDDBACCESSSVC_H diff --git a/Det/DetCond/src/component/CondDBCache.cpp b/Det/DetCond/src/component/CondDBCache.cpp deleted file mode 100755 index 2e6e94cc4..000000000 --- a/Det/DetCond/src/component/CondDBCache.cpp +++ /dev/null @@ -1,444 +0,0 @@ -// Include files -#include "CondDBCache.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBCache -// -// 2005-06-13 : Marco Clemencic -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBCache::CondDBCache(const MsgStream& log, size_t highLvl, size_t lowLvl): - m_highLvl(highLvl), m_lowLvl(lowLvl), - m_level(0), - m_log(log), - m_lastRequestedTime(0), m_checkLastReqTime(true), - m_silentConflicts(false) -{ - if ( highLvl == 0 ) { - m_log << MSG::WARNING << "High level == 0 : forced to 100" << endmsg; - m_highLvl = 100; - } - if ( highLvl <= lowLvl ) { - m_log << MSG::WARNING << "High level <= low level : low level forced to 0" << endmsg; - m_lowLvl = 0; - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Cache initialized with high/low levels = " << - m_highLvl << '/' << m_lowLvl << endmsg; -} -//============================================================================= -// Destructor -//============================================================================= -CondDBCache::~CondDBCache() { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Cache deleted. Level was = " << m_level << endmsg; -} - -//========================================================================= -// Add a new item to the cache -//========================================================================= -bool CondDBCache::insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel) { - // increment object count and check the limit - if ( m_level >= highLevel() ){ - // needs clean up - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Level above max threshold" << endmsg; - clean_up(); - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Insert Folder '" << folder->fullPath() - << "', IOV : " << obj.since() << " - " << obj.until() - << ", channel : " << channel << endmsg; - - FolderIdType id(folder->fullPath()); - StorageType::iterator f = m_cache.find(id); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(id, CondFolder(folder))).first; - // Fill the map of channel names. - std::map<cool::ChannelId,std::string>::const_iterator p; - std::map<cool::ChannelId,std::string> ch_names = folder->listChannelsWithNames(); - for (p = ch_names.begin(); p != ch_names.end(); ++p) { - f->second.channelNames[p->second] = p->first; - } - } else { - if (f->second.items[channel].end() != f->second.conflict(obj.since(), obj.until(), channel)) { - const MSG::Level lvl = (m_silentConflicts ? MSG::DEBUG : MSG::WARNING); - m_log << lvl << "Conflict found: item not inserted" << endmsg; - ItemListType::iterator i = f->second.conflict(obj.since(), obj.until(), channel); - m_log << lvl << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; - return false; - } - } - // for vectors - // f->second.items.push_back(CondItem(&f->second,obj)); - // for lists - ItemListType &items = f->second.items[channel]; - ItemListType::iterator pos = items.begin(); - while (pos != items.end() && pos->iov.first < obj.since()) { - ++pos; - } - items.insert(pos, CondItem(&f->second, obj)); - - ++m_level; - return true; -} - -//========================================================================= -// Add a new folder using the given specification and description. (Bypass the real DB) -//========================================================================= -bool CondDBCache::addFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec) { - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; - } - return true; -} -bool CondDBCache::addFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec, - const std::map<cool::ChannelId,std::string>& ch_names) { - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; - // Fill the map of channel names. - std::map<cool::ChannelId,std::string>::const_iterator p; - for (p = ch_names.begin(); p != ch_names.end(); ++p) { - f->second.channelNames[p->second] = p->first; - } - } - return true; -} - -//========================================================================= -// Add a new folder using the given specification and description. (Bypass the real DB) -//========================================================================= -bool CondDBCache::addFolderSet(const std::string &path, const std::string &descr) { - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(path,CondFolder(descr))).first; - } - return true; -} - -//========================================================================= -// Add a new object to a given folder -//========================================================================= -bool CondDBCache::addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before) { - // new objects cannot be already valid. check it! - if ( IOVCheck() && (m_lastRequestedTime != 0) - && ( since <= m_lastRequestedTime && m_lastRequestedTime < until ) ) { - m_log << (m_silentConflicts ? MSG::DEBUG : MSG::WARNING) - << "New item IOV is compatible with last requested time:" - << " not allowed to avoid inconsistencies" << endmsg; - return false; - } - // increment object count and check the limit - if ( m_level >= highLevel() ){ - // needs clean up - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Level above max threshold" << endmsg; - clean_up(); - } - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - m_log << MSG::WARNING << "Could not find the folder: object not added" << endmsg; - return false; - } - if (!f->second.spec) { // no specification means FolderSet - m_log << MSG::WARNING << '"' << path << '"' << " is a FolderSet: object not added" << endmsg; - return false; - } - - // when bypassing the DB, the conflicts must be solved - /* - if (f->second.conflict(since,until) != f->second.items.end()) { - m_log << MSG::WARNING << "Conflict found: item not inserted" << endmsg; - return false; - } - */ - // **** COOL single version style --> [x;+inf] + [y(>x);z] = [x;y], [y;z] - // scan for conflicting items (from the end) - ItemListType::iterator i = f->second.conflict(since,until,channel); - if ( i != f->second.items[channel].end() ) { // conflict found - if ( i->iov.second == cool::ValidityKeyMax && i->iov.first < since ) { - // solvable conflict - if (iov_before) *iov_before = i->iov; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Solvable conflict found: old until = " << i->iov.second << endmsg; - i->iov.second = since; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " new until = " << i->iov.second << endmsg; - } else { - // conflict not solvable - m_log << MSG::WARNING << "Unsolvable conflict found: item not inserted" << endmsg; - return false; - } - } - // for vectors - // f->second.items.push_back(CondItem(&f->second,since,until,rec)); - // for lists - f->second.items[channel].push_front(CondItem(&f->second,since,until,rec)); - ++m_level; - return true; -} - -//========================================================================= -// Get data from given path and valid at given time -//========================================================================= -bool CondDBCache::get(const std::string &path, const cool::ValidityKey &when, - const cool::ChannelId &channel, - cool::ValidityKey &since, cool::ValidityKey &until, - std::string &descr, ICondDBReader::DataPtr &payload ) { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Request Folder '" << path - << "' @ " << when << " channel " << channel; - m_lastRequestedTime = when; - StorageType::iterator folder = m_cache.find(path); - if (folder != m_cache.end()) { - if ( ! folder->second.spec ) { - // It's a FolderSet! no objects inside - since = cool::ValidityKeyMin; - until = cool::ValidityKeyMax; - descr = folder->second.description; - payload.reset(); - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << " FOUND (FolderSet)" << endmsg; - return true; - } - ItemListType::iterator i = folder->second.find(when,channel); - if ( i != folder->second.items[channel].end() ) { - since = i->iov.first; - until = i->iov.second; - descr = folder->second.description; - payload = i->data; - //i->score += 1.0; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << " FOUND" << endmsg; - return true; - } - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << " MISSING" << endmsg; - return false; -} -//========================================================================= -// -//========================================================================= -bool CondDBCache::getChannelId(const std::string &path,const std::string &name, - cool::ChannelId &channel) const { - StorageType::const_iterator f = m_cache.find(path); - if ( m_cache.end() != f ) { - CondFolder::ChannelNamesMapType::const_iterator id = f->second.channelNames.find(name); - if ( f->second.channelNames.end() != id ) { - channel = id->second; - return true; - } - } - channel = 0; - return false; -} -//========================================================================= -// -//========================================================================= -void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets) { - - folders.clear(); - foldersets.clear(); - - StorageType::iterator f; - for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { - const std::string &p = f->first; - if ( p.find(path) == 0 // the string must start with path - && ( p.size() > path.size() ) // it must contain something more than the path - && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name - if ( f->second.spec.get() ) { - // this is a folder - folders.push_back(p.substr(path.size())); - } else { - // this is a folderset - foldersets.push_back(p.substr(path.size())); - } - } - } -} -//========================================================================= -// -//========================================================================= -void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &node_names) { - // @todo: could be implemented as getSubNodes(path,node_names,node_names); - - node_names.clear(); - - StorageType::iterator f; - for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { - const std::string &p = f->first; - if ( p.find(path) == 0 // the string must start with path - && ( p.size() > path.size() ) // it must contain something more than the path - && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name - node_names.push_back(p.substr(path.size())); - } - } -} -//========================================================================= -// Remove unused entries from the cache -//========================================================================= - -void CondDBCache::clean_up(){ - typedef std::vector<std::pair<float,std::pair<CondDBCache::CondFolder*,std::pair<cool::ValidityKey,cool::ChannelId> > > > - _vec_t; - _vec_t all_items; - float score = 0; - size_t old_level = level(); - - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) { - m_log << MSG::DEBUG << "Start cleaning up (level = " << level() << ")" << endmsg; - m_log << MSG::DEBUG << " Last requested time = " << m_lastRequestedTime << endmsg; - } - // collect all items info in order - StorageType::iterator folder; - for ( folder = m_cache.begin() ; folder != m_cache.end() ; ++folder ) { - - if ( ! folder->second.spec ) continue; // It's a FolderSet! no objects inside: skip it - - CondFolder::StorageType::iterator ch; - ItemListType::iterator i; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Folder " << folder->first << endmsg; - for ( ch = folder->second.items.begin(); ch != folder->second.items.end() ; ++ch ){ - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " channel : " << ch->first << endmsg; - for ( i = ch->second.begin(); i != ch->second.end() ; ++i ){ - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; - if ( ! (i->iov.first <= m_lastRequestedTime && i->iov.second > m_lastRequestedTime) ) { - if ( m_lastRequestedTime < i->iov.first ) { - score = (float)m_lastRequestedTime - i->iov.first; - } else { - score = (float)i->iov.second - m_lastRequestedTime; - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " score = " << score << endmsg; - all_items.push_back( - std::make_pair(score, - std::make_pair(&folder->second, - std::make_pair(i->iov.first,ch->first)))); - // i->score = 0; - } - } - } - } - std::sort(all_items.begin(),all_items.end()); - - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Remove items" << endmsg; - // remove items - _vec_t::iterator it = all_items.begin(); - while ( m_level > m_lowLvl && it != all_items.end()) { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Remove item since " << it->second.second.first << - " channel " << it->second.second.second << - // " from '" << it->second.first->path << "'" << - " (score =" << it->first << ")" << endmsg; - // folder when - it->second.first->erase(it->second.second.first,it->second.second.second); - --m_level; - ++it; - } - - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Remove empty folders:" << endmsg; - // remove empty folders - std::vector<FolderIdType> to_remove; - for ( StorageType::iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { - if (!i->second.sticky && i->second.empty()) { // delete folders which are empty but not sticky - to_remove.push_back(i->first); - } - } - for ( std::vector<FolderIdType>::iterator i = to_remove.begin(); i != to_remove.end(); ++i ) { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " " << *i << endmsg; - m_cache.erase(m_cache.find(*i)); - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Clean up finished (level = " << level() << ")" << endmsg; - if ( UNLIKELY(old_level == level()) ) { - m_log << MSG::WARNING << "No item removed: I increase high threshold" << endmsg; - setHighLevel(highLevel()+(highLevel()-lowLevel())/10+1); - m_log << MSG::WARNING << "New threshold = " << highLevel() << endmsg; - } -} - -//========================================================================= -// Check if an entry for the give path+time is in the cache -//========================================================================= -bool CondDBCache::hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel) const { - StorageType::const_iterator folder = m_cache.find(path); - if (folder != m_cache.end()) { - - if ( !folder->second.spec ) return true; // It's a FolderSet! They ignore time - - ItemListType::const_iterator i = folder->second.find(when,channel); - const ItemListType &lst = (*const_cast<CondFolder::StorageType *>(&folder->second.items))[channel]; - return i != lst.end(); - } - return false; -} - -ICondDBReader::IOVList CondDBCache::getIOVs(const std::string & path, const ICondDBReader::IOV & iov, cool::ChannelId channel) -{ - ICondDBReader::IOVList result; - StorageType::const_iterator folder = m_cache.find(path); - if (folder != m_cache.end()) { - if (folder->second.spec) { - // find the first recorded interval which overlaps with requested IOV - ItemListType::const_iterator i = folder->second.conflict(iov.since.ns(), iov.until.ns(), channel); - // marker for the end of IOVs in the cache for the channel - const ItemListType::const_iterator end = folder->second.end(channel); - // we add all the IOVs in the cache starting from the one found until - // we are in the list and the IOV is in the requested range. - for(; i != end && (i->iov.first < static_cast<cool::ValidityKey>(iov.until.ns())); ++i) { - result.push_back(ICondDBReader::IOV(i->iov.first, i->iov.second)); - } - } else { - // it's a FolderSet: IOV is infinite - result.push_back(ICondDBReader::IOV(Gaudi::Time::epoch(), Gaudi::Time::max())); - } - } - return result; -} - -//========================================================================= -// Dump the content of the cache to the message service. -//========================================================================= -void CondDBCache::dump() { - if (m_log.level() > MSG::DEBUG) return; // do not dump outside for non debug - m_log << MSG::DEBUG << "Cache content dump --------------------- BEGIN" << endmsg; - m_log << MSG::DEBUG << " Thresholds (high/low) -> " << m_highLvl << '/' << m_lowLvl << endmsg; - m_log << MSG::DEBUG << " Level = " << level() << endmsg; - for(StorageType::const_iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { - if ( !i->second.spec ) { // It's a FolderSet! They ignore time - m_log << MSG::DEBUG << "FolderSet '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; - continue; - } else { - m_log << MSG::DEBUG << "Folder '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; - } - - for(CondFolder::StorageType::const_iterator ch = i->second.items.begin(); ch != i->second.items.end(); ++ch) { - m_log << MSG::DEBUG << " Channel " << ch->first << endmsg; - size_t cnt = 0; - for(ItemListType::const_iterator j = ch->second.begin(); j != ch->second.end(); ++j) { - m_log << MSG::DEBUG << " Object " << cnt++ << endmsg; - m_log << MSG::DEBUG << " Score: " << j->score << endmsg; - m_log << MSG::DEBUG << " Validity: " << j->iov.first << " - " << j->iov.second << endmsg; - m_log << MSG::DEBUG << " Data: " << *(j->data)<< endmsg; - } - } - } - m_log << MSG::DEBUG << "Cache content dump --------------------- END" << endmsg; -} -//============================================================================= - diff --git a/Det/DetCond/src/component/CondDBCache.h b/Det/DetCond/src/component/CondDBCache.h deleted file mode 100755 index 0f8ab7994..000000000 --- a/Det/DetCond/src/component/CondDBCache.h +++ /dev/null @@ -1,279 +0,0 @@ -#ifndef COMPONENT_CONDDBCACHE_H -#define COMPONENT_CONDDBCACHE_H 1 - -// Include files -#include <string> -#include <vector> -#include <list> - -#include "GaudiKernel/MsgStream.h" - -#include "GaudiKernel/HashMap.h" - -#include "CoolKernel/types.h" -#include "CoolKernel/pointers.h" -#include "CoolKernel/ValidityKey.h" -#include "CoolKernel/IObject.h" -#include "CoolKernel/IFolder.h" -#include "CoolKernel/IRecord.h" -#include "CoolKernel/Record.h" -#include "CoolKernel/IRecordSpecification.h" -#include "CoolKernel/RecordSpecification.h" - -#include "DetCond/ICondDBReader.h" - -#include <boost/shared_ptr.hpp> - -/** @class CondDBCache CondDBCache.h component/CondDBCache.h - * - * Class used to manage in memory conditions. - * - * @author Marco Clemencic - * @date 2005-06-13 - */ -class CondDBCache { - -public: - - typedef std::pair<cool::ValidityKey,cool::ValidityKey> IOVType; - - //-------------------------------------------------------------------------------- - /// Standard constructor - CondDBCache(const MsgStream& log, size_t highLevel = 100, size_t lowLevel = 10); - - virtual ~CondDBCache( ); ///< Destructor - - /// Add a new data object to the cache. - /// \warning {no check performed} - bool insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel = 0); - - /// Shortcut for the regular implementations (for backward compatibility). - inline bool insert(const cool::IFolderPtr &folder,const cool::IObjectPtr &obj, const cool::ChannelId &channel = 0) { - return insert(folder, *obj.get(), channel); - } - - bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec); - bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec, - const std::map<cool::ChannelId,std::string>& ch_names); - bool addFolderSet(const std::string &path, const std::string &descr); - bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before = NULL); - /// (version kept for backward compatibility) - inline bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord& rec, IOVType *iov_before = NULL) - { - return addObject(path,since,until,rec,0,iov_before); - } - - - /// Search an entry in the cache and returns the data string or an empty string if no object is found. - bool get(const std::string &path, const cool::ValidityKey &when, - const cool::ChannelId &channel, - cool::ValidityKey &since, cool::ValidityKey &until, - std::string &descr, ICondDBReader::DataPtr &payload); - - /// Search an entry in the cache and returns the data string or an empty string if no object is found. - /// (version kept for backward compatibility) - inline bool get(const std::string &path, const cool::ValidityKey &when, - cool::ValidityKey &since, cool::ValidityKey &until, - std::string &descr, ICondDBReader::DataPtr &payload) { - return get(path,when,0,since,until,descr,payload); - } - - /// Find the value of the channel id for the given channel name in a folder - /// (if present in the cache). - /// Returns true if the channel name in the folder was found - bool getChannelId(const std::string &path,const std::string &name, - cool::ChannelId &channel) const; - - void getSubNodes(const std::string &path, std::vector<std::string> &node_names); - - void getSubNodes(const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets); - - /// Remove all entries from the cache; - inline void clear() {m_cache.clear();} - - /// Get the number of items cached. - inline size_t size() const; - - inline void setHighLevel(size_t lvl) { m_highLvl = lvl; } - inline void setLowLevel(size_t lvl) { m_lowLvl = lvl; } - inline size_t highLevel() const { return m_highLvl; } - inline size_t lowLevel() const { return m_lowLvl; } - - inline size_t level() const { return m_level; } - - void clean_up(); - - /// Check if the given path is present in the cache. - inline bool hasPath(const std::string &path) const { return m_cache.count(path) != 0; } - - /// Check if the path is a folderset. - inline bool isFolderSet(const std::string &path) const { - return hasPath(path) && (m_cache.find(path)->second.spec.get() == 0); - } - - /// Check if the path is a folderset. - inline bool isFolder(const std::string &path) const { - return hasPath(path) && (m_cache.find(path)->second.spec.get() != 0); - } - - /// Check if the given path,time pair is present in the cache. - bool hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const; - - /// Return the list of IOVs known for the given path, IOV, channel. - /// @see ICondDBReader::getIOVs - ICondDBReader::IOVList getIOVs(const std::string &path, const ICondDBReader::IOV &iov, cool::ChannelId channel = 0); - - void dump(); - - /// Set the flag to enable the check that the inserted IOVs are not compatible with the latest - /// requested time (needed to avoid that the cache is modified for the current event). - /// @return previous value - bool setIOVCheck(bool enable) - { - bool old = m_checkLastReqTime; - m_checkLastReqTime = enable; - return old; - } - - /// Tell if the check on inserted IOVs is enabled. - bool IOVCheck() { return m_checkLastReqTime; } - - /// Getter for the data member m_silentConflicts. - bool silentConflicts() const { return m_silentConflicts; } - - /// Getter for the data member m_silentConflicts. - void setSilentConflicts(bool value) { m_silentConflicts = value; } - -protected: - -private: - - struct CondFolder; - struct CondItem; - - typedef std::string FolderIdType; - //typedef std::vector<CondItem> ItemListType; - typedef std::list<CondItem> ItemListType; - // typedef std::map<FolderIdType,CondFolder> FolderListType; - typedef GaudiUtils::HashMap<FolderIdType,CondFolder> StorageType; - - /// Internal class used to record IOV+data pairs - struct CondItem { - /// Constructor. - CondItem(CondFolder *myFolder, const cool::IObject &obj): - folder(myFolder),iov(obj.since(),obj.until()), - data(new cool::Record(obj.payload())),score(1.0) {} - CondItem(CondFolder *myFolder, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord &rec): - folder(myFolder),iov(since,until), data(new cool::Record(rec)),score(1.0) {} - CondFolder *folder; - IOVType iov; - ICondDBReader::DataPtr data; - float score; - /// Check if the CondItem is valid at the given time. - inline bool valid(const cool::ValidityKey &when) const { - return iov.first <= when && when < iov.second; - } - }; - - /// Internal class used to keep the items common to a given path. - struct CondFolder { - - typedef GaudiUtils::Map<cool::ChannelId,ItemListType> StorageType; - typedef GaudiUtils::HashMap<std::string,cool::ChannelId> ChannelNamesMapType; - - CondFolder(const cool::IFolderPtr &fld): - description(fld->description()), - spec(new cool::RecordSpecification(fld->payloadSpecification())), - sticky(false) {} - CondFolder(const std::string &descr, const cool::IRecordSpecification& new_spec): - description(descr),spec(new cool::RecordSpecification(new_spec)),sticky(true) {} - // for a folderset (FolderSets are identified by missing spec) - CondFolder(const std::string &descr): - description(descr),sticky(true) {} - std::string description; - boost::shared_ptr<cool::IRecordSpecification> spec; - StorageType items; - ChannelNamesMapType channelNames; - bool sticky; - /// Search for the first item in the storage valid at the given time. - inline ItemListType::iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { - ItemListType &lst = items[channel]; - ItemListType::iterator i; - for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} - return i; - } - /// Const version of the search method. - inline ItemListType::const_iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const { - const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; - ItemListType::const_iterator i; - for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} - return i; - } - inline ItemListType::iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::ChannelId &channel = 0) { - ItemListType &lst = items[channel]; - ItemListType::iterator i; - for ( i = lst.begin(); i != lst.end() ; ++i ){ - // Given two IOVs a and b, they conflict if the intersection is not empty: - // max(a.s,b.s) < min(a.u,b.u) - if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; - } - return i; - } - inline ItemListType::const_iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::ChannelId &channel = 0) const { - const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; - ItemListType::const_iterator i; - for ( i = lst.begin(); i != lst.end() ; ++i ){ - if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; - } - return i; - } - inline ItemListType::iterator end(const cool::ChannelId &channel = 0) { - return items[channel].end(); - } - inline ItemListType::const_iterator end(const cool::ChannelId &channel = 0) const { - return (*const_cast<StorageType *>(&items))[channel].end(); - } - inline void erase (const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { - items[channel].erase(find(when,channel)); - } - inline bool empty() const { - for (StorageType::const_iterator ch = items.begin(); ch != items.end(); ++ch ) { - if (! ch->second.empty()) return false; - } - return true; - } - - }; - - /// Actual storage - StorageType m_cache; - - size_t m_highLvl; - size_t m_lowLvl; - size_t m_level; - - MsgStream m_log; - - cool::ValidityKey m_lastRequestedTime; - bool m_checkLastReqTime; - - // Do not print warning messages in case of conflicts during the insertion - bool m_silentConflicts; -}; - -inline size_t CondDBCache::size() const { - size_t count = 0; - StorageType::const_iterator folder; - for (folder = m_cache.begin(); folder != m_cache.end(); ++folder) { - for (CondFolder::StorageType::const_iterator ch = folder->second.items.begin(); ch != folder->second.items.end(); ++ch) - count += ch->second.size(); - } - return count; -} - -#endif // COMPONENT_CONDDBCACHE_H diff --git a/Det/DetCond/src/component/CondDBCnvSvc.cpp b/Det/DetCond/src/component/CondDBCnvSvc.cpp deleted file mode 100755 index a192987ee..000000000 --- a/Det/DetCond/src/component/CondDBCnvSvc.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include <string> - -#include "CondDBCnvSvc.h" -#include "DetCond/ICondDBReader.h" - -#include "GaudiKernel/GenericAddress.h" -#include "GaudiKernel/IDetDataSvc.h" -#include "GaudiKernel/IDataProviderSvc.h" -#include "GaudiKernel/MsgStream.h" - -/// Instantiation of a static factory to create instances of this service -DECLARE_SERVICE_FACTORY(CondDBCnvSvc) - -//---------------------------------------------------------------------------- - -/// Constructor -CondDBCnvSvc::CondDBCnvSvc( const std::string& name, ISvcLocator* svc) - : base_class ( name, svc, CONDDB_StorageType ), - m_dbReader(0) -{ - declareProperty( "CondDBReader", m_dbReaderName = "CondDBAccessSvc" ); -} - -//---------------------------------------------------------------------------- - -/// Destructor -CondDBCnvSvc::~CondDBCnvSvc() {} - -//---------------------------------------------------------------------------- - -/// Initialize the service. -StatusCode CondDBCnvSvc::initialize() -{ - - // Before anything else, we need to initialise the base class - StatusCode sc = base_class::initialize(); - if ( !sc.isSuccess() ) return sc; - - // Now we can get a handle to the MessageSvc - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Specific initialization starting" << endmsg; - - // Locate the Database Access Service - sc = service(m_dbReaderName,m_dbReader,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << m_dbReaderName << endmsg; - return sc; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved " << m_dbReaderName << endmsg; - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Specific initialization completed" << endmsg; - return sc; -} - -//---------------------------------------------------------------------------- - -/// Finalize the service. -StatusCode CondDBCnvSvc::finalize() -{ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalizing" << endmsg; - if (m_dbReader) m_dbReader->release(); - return base_class::finalize(); -} - -//---------------------------------------------------------------------------- - -/// Create an address using explicit arguments to identify a single object. -/// Par[0] is folder name in the CondDB. -/// Par[1] is entry name in the string (which may contain many conditions, -/// for instance in the case of XML files with more than one element). -StatusCode CondDBCnvSvc::createAddress( long svc_type, - const CLID& clid, - const std::string* par, - const unsigned long* ipar, - IOpaqueAddress*& refpAddress ) { - - // First check that requested address is of type CONDDB_StorageType - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering createAddress" << endmsg; - if ( svc_type!= CONDDB_StorageType ) { - log << MSG::ERROR - << "Cannot create addresses of type " << (int)svc_type - << " which is different from " << (int)CONDDB_StorageType - << endmsg; - return StatusCode::FAILURE; - } - - // Par[0] is folder name in the CondDB. - std::string folderName = par[0]; - - // Par[1] is entry name in the string (which may contain many conditions, - // for instance in the case of XML files with more than one element). - std::string entryName = par[1]; - - // iPar[0] is the cool::ChannelId - unsigned long channelId = ipar[0]; - - // Now create the address - refpAddress = new GenericAddress( CONDDB_StorageType, - clid, - folderName, - entryName, - channelId ); - return StatusCode::SUCCESS; - -} - -//---------------------------------------------------------------------------- - -/// Retrieve converter from list -IConverter* CondDBCnvSvc::converter(const CLID& clid) { - IConverter* cnv = 0; - cnv = ConversionSvc::converter(clid); - if ( cnv ) { - return cnv; - } - else { - return ConversionSvc::converter(CLID_Any); - } -} - -//---------------------------------------------------------------------------- -// Implementation of ICondDBReader -StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) -{ - return m_dbReader->getObject(path,when,data,descr,since,until,channel); -} - -StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) -{ - return m_dbReader->getObject(path,when,data,descr,since,until,channel); -} - -StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) -{ - return m_dbReader->getChildNodes(path,node_names); -} - -StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) -{ - return m_dbReader->getChildNodes(path,folders,foldersets); -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBCnvSvc::exists(const std::string &path) { - return m_dbReader->exists(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBCnvSvc::isFolder(const std::string &path) { - return m_dbReader->isFolder(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBCnvSvc::isFolderSet(const std::string &path) { - return m_dbReader->isFolder(path); -} - -void CondDBCnvSvc::disconnect() { - if(m_dbReader) - m_dbReader->disconnect(); -} - -ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return m_dbReader->getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return m_dbReader->getIOVs(path, iov, channel); -} - -void CondDBCnvSvc::defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const -{ - tags.clear(); - m_dbReader->defaultTags(tags); -} - diff --git a/Det/DetCond/src/component/CondDBCnvSvc.h b/Det/DetCond/src/component/CondDBCnvSvc.h deleted file mode 100755 index 88430fd0a..000000000 --- a/Det/DetCond/src/component/CondDBCnvSvc.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef DETCOND_CONDDBCNVSVC_H -#define DETCOND_CONDDBCNVSVC_H 1 - -/// Include files -#include "GaudiKernel/ConversionSvc.h" - -#include "DetCond/ICondDBReader.h" - -/// Forward and external declarations -template <class TYPE> class SvcFactory; -class IDetDataSvc; -class IOpaqueAddress; - -///--------------------------------------------------------------------------- -/** @class CondDBCnvSvc CondDBCnvSvc.h - - A conversion service for CERN-IT COOL (ex. CondDB) persistency. - Allows to create and update condition data objects (i.e. DataObjects - implementing IValidity). - - @author Marco Clemencic - @date November 2004 -*///-------------------------------------------------------------------------- - -class CondDBCnvSvc : public extends1<ConversionSvc, ICondDBReader> { - - /// Only factories can access protected constructors - friend class SvcFactory<CondDBCnvSvc>; - -protected: - - /// Constructor - CondDBCnvSvc( const std::string& name, ISvcLocator* svc ); - - /// Destructor - virtual ~CondDBCnvSvc(); - -public: - - // Overloaded from ConversionSvc - - /// Initialize the service - virtual StatusCode initialize(); - - /// Finalize the service - virtual StatusCode finalize(); - - using ConversionSvc::createAddress; - /// Create an address using explicit arguments to identify a single object. - virtual StatusCode createAddress (long svc_type, - const CLID& clid, - const std::string* par, - const unsigned long* ip, - IOpaqueAddress*& refpAddress ); - -public: - - /// Retrieve converter from list - virtual IConverter* converter(const CLID& clid); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - -private: - - /// List of all the names of the known databases. It is filled via the option - /// CondDBCnvSvc.CondDBReader. If none is given, "CondDBAccessSvc" is used. - std::string m_dbReaderName; - - /// Handles to the database Access services - ICondDBReader* m_dbReader; - -protected: - -}; - -#endif // DETCOND_CONDITIONSDBCNVSVC_H - - diff --git a/Det/DetCond/src/component/CondDBCommon.cpp b/Det/DetCond/src/component/CondDBCommon.cpp deleted file mode 100755 index c0fbf40bb..000000000 --- a/Det/DetCond/src/component/CondDBCommon.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "CondDBCommon.h" - -#include <sstream> - -#include "CoolKernel/RecordSpecification.h" -#include "CoolKernel/Record.h" -#include "CoolKernel/StorageType.h" - -static std::unique_ptr<cool::RecordSpecification> s_XMLStorageSpec{}; - -namespace CondDB { - -const cool::RecordSpecification& getXMLStorageSpec() { - if ( s_XMLStorageSpec.get() == NULL){ - // attribute list spec template - s_XMLStorageSpec = std::unique_ptr<cool::RecordSpecification>(new cool::RecordSpecification()); - s_XMLStorageSpec->extend("data", cool::StorageType::String16M); - } - return *s_XMLStorageSpec; -} - -namespace { - inline bool ends_with(const std::string& s, const std::string &suff) { - const auto count = suff.size(); - const auto size = s.size(); - return (size >= count) && - (s.compare(size - count, count, suff) == 0); - } -} - -void generateXMLCatalog(const std::string &name, - const std::vector<std::string> &fldrs, - const std::vector<std::string> &fldrsets, - std::string &data) { - std::ostringstream xml; // buffer for the XML - - // XML header, root element and catalog initial tag - xml << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" - << "<!DOCTYPE DDDB SYSTEM \"conddb:/DTD/structure.dtd\">" - << "<DDDB><catalog name=\"" << name << "\">"; - - // sub-folders are considered as container of conditions - std::vector<std::string>::const_iterator f; - for (const auto& f: fldrs) { - // Ignore folders with the .xml extension. - // We never used .xml for Online conditions and after the Hlt1/Hlt2 split - // we need to avoid automatic mapping for the .xml files. - if (!ends_with(f, ".xml")) { - xml << "<conditionref href=\"" << name << '/' << f << "\"/>"; - } - } - // sub-foldersets are considered as catalogs - for (const auto& f: fldrsets) { - xml << "<catalogref href=\"" << name << '/' << f << "\"/>"; - } - // catalog and root element final tag - xml << "</catalog></DDDB>"; - - data = xml.str(); -} - -StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, - ICondDBReader::DataPtr &payload){ - // get the list of subnodes - std::vector<std::string> folders, foldersets; - StatusCode sc = reader->getChildNodes(path,folders,foldersets); - if (sc.isFailure()) return sc; - - // extract the name of the folderset - std::string::size_type pos = path.rfind('/'); - std::string name; - if ( std::string::npos != pos ) { - name = path.substr(pos+1); - } else { - name = path; - } - - // generate the XML catalog - std::string xml; - generateXMLCatalog(name,folders,foldersets,xml); - - // prepare new payload - cool::Record *rec = new cool::Record(getXMLStorageSpec()); - (*rec)["data"].setValue<cool::String16M>(xml); - payload.reset(rec); - - return sc; -} - -} diff --git a/Det/DetCond/src/component/CondDBCommon.h b/Det/DetCond/src/component/CondDBCommon.h deleted file mode 100755 index 476f26811..000000000 --- a/Det/DetCond/src/component/CondDBCommon.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CONDDBCOMMON_H_ -#define CONDDBCOMMON_H_ - -#include <string> -#include <vector> -#include "DetCond/ICondDBReader.h" - -// forward declaration -namespace cool{ - class RecordSpecification; -} - -/** @file Utility functions shared among DetCond components. - * - * @author Marco Clemencic - */ -namespace CondDB { - void generateXMLCatalog(const std::string &name, - const std::vector<std::string> &fldrs, - const std::vector<std::string> &fldrsets, - std::string &data); - - StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, - ICondDBReader::DataPtr &data); - - const cool::RecordSpecification& getXMLStorageSpec(); -} - -#endif /*CONDDBCOMMON_H_*/ diff --git a/Det/DetCond/src/component/CondDBDQScanner.cpp b/Det/DetCond/src/component/CondDBDQScanner.cpp deleted file mode 100644 index 48cdd8556..000000000 --- a/Det/DetCond/src/component/CondDBDQScanner.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Include files - -// From Gaudi -#include "GaudiKernel/IConverter.h" -#include "GaudiKernel/IAddressCreator.h" -#include "GaudiKernel/IOpaqueAddress.h" - -#include "CoolKernel/IRecord.h" -#include "CoolKernel/RecordException.h" - -// From LHCb -#include "DetCond/ICondDBReader.h" -#include "DetDesc/Condition.h" - -// local -#include "CondDBDQScanner.h" -#include "RelyConverter.h" - -// ---------------------------------------------------------------------------- -// Implementation file for class: CondDBDQScanner -// -// 04/11/2011: Marco Clemencic -// ---------------------------------------------------------------------------- -DECLARE_TOOL_FACTORY(CondDBDQScanner) - -// ============================================================================ -// Standard constructor, initializes variables -// ============================================================================ -CondDBDQScanner::CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent) - : base_class(type, name, parent) -{ - - declareProperty("ConditionPath", - m_condPath = "/Conditions/DQ/Flags", - "Path in the Conditions Database where to find the Data " - "Quality condition."); - - declareProperty("CondDBReader", - m_condDBReaderName = "CondDBCnvSvc", - "Service implementing the ICondDBReader interface to be used " - "to access the CondDB."); - - declareProperty("Converter", - m_converterName = "DetectorPersistencySvc", - "Service implementing the IConverter interface."); -} - -CondDBDQScanner::~CondDBDQScanner() {} - -IDQFilter::FlagsType CondDBDQScanner::scan(const Gaudi::Time & since, const Gaudi::Time & until) const -{ - typedef ICondDBReader::IOVList IOVList; - typedef ICondDBReader::IOV IOV; - IDQFilter::FlagsType flags; - - ICondDBReader::DataPtr data; - Gaudi::Time dataSince, dataUntil; - std::string desc; - - // Loop over the list of conditions in the folder - IOVList iovs = m_condDB->getIOVs(m_condPath, IOV(since, until)); - for(IOVList::iterator iov = iovs.begin(); iov != iovs.end(); ++iov) { - // get the condition data (XML) - StatusCode sc = m_condDB->getObject(m_condPath, iov->since, data, desc, dataSince, dataUntil); - if (sc.isFailure()){ - Exception("Problems retrieving data from the database"); - return flags; // never reached, but helps Coverity - } - - try { - // prepare the IOpaqueAddress to be given to the PersistencySvc - const long storageType = RelyConverter::getStorageType(m_condPath, desc); - const std::string xml_data = (*data.get())["data"].data<std::string>(); - IOpaqueAddress *addr = RelyConverter::createTmpAddress("conddb:" + m_condPath, - storageType, - "Flags", - Condition::classID(), - xml_data, - info(), - m_converter->addressCreator()); - if (!addr){ - Exception("Failed to create temporary IOpaqueAddress"); - return flags; // never reached, but helps Coverity - } - - // Retrieve the condition data - DataObject *obj = 0; - Condition *cond = 0; - if (m_converter->createObj(addr, obj).isFailure() - || m_converter->fillObjRefs(addr, obj).isFailure() - || (cond = dynamic_cast<Condition*>(obj)) == 0) { //assignment intended - delete addr; - if (obj) delete obj; - Exception("Conversion of Condition failed"); - return flags; // never reached, but helps Coverity - } - delete addr; - - // Merge the condition map with the collected one. - const IDQFilter::FlagsType &condFlags = cond->param<IDQFilter::FlagsType>("map"); - flags.insert(condFlags.begin(), condFlags.end()); - - delete obj; - - } catch (cool::RecordSpecificationUnknownField &e) { - Exception(std::string("I cannot find the data inside COOL object: ") + e.what()); - } - } - - return flags; -} - - - - -StatusCode CondDBDQScanner::initialize() -{ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - m_condDB = service(m_condDBReaderName); - if (UNLIKELY(!m_condDB.isValid())) { - error() << "Cannot get the ICondDBReader implementation " << m_condDBReaderName << endmsg; - return StatusCode::FAILURE; - } - - m_converter = service(m_converterName); - if (UNLIKELY(!m_converter.isValid())) { - error() << "Cannot get the IConverter implementation " << m_converterName << endmsg; - return StatusCode::FAILURE; - } - - return sc; -} - - - -StatusCode CondDBDQScanner::finalize() -{ - m_condDB.reset(); // release the ICondDBReader service - - return base_class::finalize(); -} - - - -// ============================================================================ diff --git a/Det/DetCond/src/component/CondDBDQScanner.h b/Det/DetCond/src/component/CondDBDQScanner.h deleted file mode 100644 index c686a8fd4..000000000 --- a/Det/DetCond/src/component/CondDBDQScanner.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SRC_CONDDBDQSCANNER_H -#define SRC_CONDDBDQSCANNER_H 1 -// Include files -// from Gaudi -#include "GaudiAlg/GaudiTool.h" -#include "GaudiKernel/SmartIF.h" - -// Implemented interfaces -#include "Kernel/IDQScanner.h" // IDQScanner - -class ICondDBReader; -class IConverter; - -/** Basic implementation of an IDQScanner based on the Conditions Database. - * - * @author Marco Clemencic - * @date 04/11/2011 - */ -class CondDBDQScanner: public extends1<GaudiTool, IDQScanner> { -public: - /// Standard constructor - CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent); - virtual ~CondDBDQScanner(); ///< Destructor - - /// Scan all the Data Quality flags in the give time range in the CondDB. - /// @return merged list of DQ flags - virtual IDQFilter::FlagsType scan(const Gaudi::Time& since, const Gaudi::Time& until) const; - - virtual StatusCode initialize(); ///< Initialize the instance. - virtual StatusCode finalize(); ///< Finalize the instance. - -protected: -private: - - /// Path to the condition object containing the Data Quality flags. - /// (property ConditionPath) - std::string m_condPath; - - /// ICondDBReader implementation to use to access the Conditions Database. - /// (property CondDBReader) - std::string m_condDBReaderName; - - /// IConverter implementation (e.g. the persistency service) to use to convert - /// the data to a Condition. - /// (property Converter) - std::string m_converterName; - - /// ICondDBReader instance. - SmartIF<ICondDBReader> m_condDB; - - /// ICondDBReader instance. - SmartIF<IConverter> m_converter; - -}; - -#endif // SRC_CONDDBDQSCANNER_H diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.cpp b/Det/DetCond/src/component/CondDBDispatcherSvc.cpp deleted file mode 100755 index 624638275..000000000 --- a/Det/DetCond/src/component/CondDBDispatcherSvc.cpp +++ /dev/null @@ -1,294 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -// local -#include "CondDBDispatcherSvc.h" -#include "CondDBCommon.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBDispatcherSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBDispatcherSvc -// -// 2006-07-10 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBDispatcherSvc::CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc), - m_mainDB(0), - m_alternatives() -{ - declareProperty("MainAccessSvc", m_mainAccessSvcName = "CondDBAccessSvc" ); - declareProperty("Alternatives", m_alternativesDeclarationMap ); - - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBDispatcherSvc::~CondDBDispatcherSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBDispatcherSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - // locate the main access service - sc = service(m_mainAccessSvcName,m_mainDB,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << m_mainAccessSvcName << endmsg; - return sc; - } - - // locate all the alternative AccessSvcs - std::map<std::string,std::string>::iterator decl; - for ( decl = m_alternativesDeclarationMap.begin(); decl != m_alternativesDeclarationMap.end(); ++decl ) { - const std::string &altPath = decl->first; - const std::string &svcName = decl->second; - - if ( m_alternatives.find(altPath) != m_alternatives.end() ) { - log << MSG::ERROR << "More than one alternative for path " << altPath << endmsg; - return StatusCode::FAILURE; - } - - ICondDBReader *svcPtr; - sc = service(svcName,svcPtr,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << svcName << endmsg; - return sc; - } - - m_alternatives[altPath] = svcPtr; - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved '" << svcName << "' (for path '" << altPath << "')" << endmsg; - - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBDispatcherSvc::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - - if (m_mainDB) { - m_mainDB->release(); - m_mainDB = 0; - } - - std::map<std::string,ICondDBReader*>::iterator alt; - for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { - if (alt->second) alt->second->release(); - } - m_alternatives.clear(); - - return base_class::finalize(); -} - -ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return alternativeFor(path)->getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return alternativeFor(path)->getIOVs(path, iov, channel); -} - -//========================================================================= -// find the appropriate alternative -//========================================================================= -ICondDBReader *CondDBDispatcherSvc::alternativeFor(const std::string &path) const { - MsgStream log(msgSvc(), name() ); - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Get alternative DB for '" << path << "'" << endmsg; - if ( path.empty() || (path == "/") ) { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Root node: using '" << m_mainAccessSvcName << "'" << endmsg; - return m_mainDB; - } - - // loop over alternatives - std::map<std::string,ICondDBReader*>::const_reverse_iterator alt; - for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { - if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { - log << MSG::VERBOSE << "Comparing with " << alt->first << endmsg; - } - // FIXME: (MCl) wrong logic - // path=/Conditions/Velo/AlignmentCatalog.xml - // alt.=/Conditions/Velo/Alignment - // Should not match - if ( ( path.size() >= alt->first.size() ) && - ( path.substr(0,alt->first.size()) == alt->first ) ){ - if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { - IService *svc = dynamic_cast<IService*>(alt->second); - log << MSG::VERBOSE << "Using '" ; - if (svc) log << svc->name(); - else log << "unknown"; - log << "'" << endmsg; - } - - return alt->second; - } - } - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Not found: using '" << m_mainAccessSvcName << "'" << endmsg; - return m_mainDB; -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) { - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); - } - return sc; -} -StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) { - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); - } - return sc; -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { - return getChildNodes(path,node_names,node_names); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) { - // clear the destination vectors - folders.clear(); - foldersets.clear(); - - // Get the folders and foldersets from the dedicated alternative - std::vector<std::string> tmpv1,tmpv2; - StatusCode sc = alternativeFor(path)->getChildNodes(path,tmpv1,tmpv2); - if (sc.isFailure()) return sc; - - // Find alternatives for subfolders of the path. - std::map<std::string,ICondDBReader*>::reverse_iterator alt; - std::string::size_type path_size = path.size(); - for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { - // check if the path for the alternative is a subfolder of the required path - // i.e. alt->first should be = path + '/' + extra - if ( ( alt->first.size() > (path_size+1) ) && // it must be long enough - ( alt->first[path_size] == '/' ) && - ( alt->first.substr(0,path_size) == path ) ){ - // take the name of the child folder[set] implied by the alternative - // i.e. substring from after (path+'/') to the next '/' - std::string sub = alt->first.substr(path_size+1, - alt->first.find('/',path_size+1)-(path_size+1)); - if (std::find(tmpv1.begin(),tmpv1.end(),sub) == tmpv1.end() && - std::find(tmpv2.begin(),tmpv2.end(),sub) == tmpv2.end()){ - // this subnode is an addition due to the alternative - // let's check the type - if (alt->second->isFolder(path+'/'+sub)) - tmpv1.push_back(sub); // folder - else - tmpv2.push_back(sub); // folderset - } - } - } - - // copy the temporary vectors to the output ones - folders = tmpv1; - foldersets = tmpv2; - return sc; -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBDispatcherSvc::exists(const std::string &path) { - return alternativeFor(path)->exists(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBDispatcherSvc::isFolder(const std::string &path) { - return alternativeFor(path)->isFolder(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBDispatcherSvc::isFolderSet(const std::string &path) { - return alternativeFor(path)->isFolderSet(path); -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBDispatcherSvc::disconnect() { - // loop over alternatives - std::map<std::string,ICondDBReader*>::const_iterator alt; - for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { - alt->second->disconnect(); - } - if (m_mainDB) - m_mainDB->disconnect(); -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBDispatcherSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - // first add the main db - m_mainDB->defaultTags(tags); - - // loop over alternatives - std::map<std::string,ICondDBReader*>::const_iterator alt; - for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { - alt->second->defaultTags(tags); - } -} - - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.h b/Det/DetCond/src/component/CondDBDispatcherSvc.h deleted file mode 100755 index 2e3819280..000000000 --- a/Det/DetCond/src/component/CondDBDispatcherSvc.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef COMPONENT_CONDDBDISPATCHERSVC_H -#define COMPONENT_CONDDBDISPATCHERSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "DetCond/ICondDBReader.h" -#include <vector> -#include <map> - -template <class TYPE> class SvcFactory; - -/** @class CondDBDispatcherSvc CondDBDispatcherSvc.h component/CondDBDispatcherSvc.h - * - * - * - * @author Marco Clemencic - * @date 2006-07-10 - */ -class CondDBDispatcherSvc: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - - -protected: - /// Standard constructor - CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBDispatcherSvc( ); ///< Destructor - - -private: - - ICondDBReader *alternativeFor(const std::string &path) const; - - // -------------------- Data Members - - /// Property CondDBDispatcherSvc.MainAccessSvc: the AccessSvc instance to use to retrieve all the - /// objects for which an alternative is not specified (default to "CondDBAccessSvc"). - std::string m_mainAccessSvcName; - - /// Property CondDBDispatcherSvc.Alternatives: list of alternative Access Services in the form of - /// "/path/for/alternative":"ServiceType/ServiceName". - std::map<std::string,std::string> m_alternativesDeclarationMap; - - /// Pointer to the main access service. - ICondDBReader* m_mainDB; - - /// Container fo the alternatives. - std::map<std::string,ICondDBReader*> m_alternatives; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBDispatcherSvc>; - -}; -#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.cpp b/Det/DetCond/src/component/CondDBLayeringSvc.cpp deleted file mode 100755 index d78161e24..000000000 --- a/Det/DetCond/src/component/CondDBLayeringSvc.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -// local -#include "CondDBLayeringSvc.h" -#include "CondDBCommon.h" -#include "IOVListHelpers.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBLayeringSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBLayeringSvc -// -// 2006-07-14 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -// This is needed otherwise the implementation of std::map does -// not find operator<(Gaudi::Time,Gaudi::Time). -namespace Gaudi { using ::operator<; } - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBLayeringSvc::CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc) { - - declareProperty("Layers", m_layersNames ); - - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); - -} -//============================================================================= -// Destructor -//============================================================================= -CondDBLayeringSvc::~CondDBLayeringSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBLayeringSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - // locate all the AccessSvcs layers - std::vector<std::string>::iterator lname; - for ( lname = m_layersNames.begin(); lname != m_layersNames.end(); ++lname ) { - - ICondDBReader *svcPtr; - sc = service(*lname,svcPtr,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << *lname << endmsg; - return sc; - } - - m_layers.push_back(svcPtr); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved '" << *lname << "'" << endmsg; - - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBLayeringSvc::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - - std::vector<ICondDBReader*>::iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ( *layer ) (*layer)->release(); - } - m_layers.clear(); - - return base_class::finalize(); -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) -{ - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - std::vector<ICondDBReader*>::iterator layer; - sc = StatusCode::FAILURE; - for ( layer = m_layers.begin(); - layer != m_layers.end() && sc.isFailure(); - ++layer ) { - sc = (*layer)->getObject(path,when,data,descr,since,until,channel); - } - } - return sc; -} -StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) -{ - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - std::vector<ICondDBReader*>::iterator layer; - sc = StatusCode::FAILURE; - for ( layer = m_layers.begin(); - layer != m_layers.end() && sc.isFailure(); - ++layer ) { - sc = (*layer)->getObject(path,when,data,descr,since,until,channel); - } - } - return sc; -} - -template <typename Channel> -ICondDBReader::IOVList CondDBLayeringSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) -{ - IOVList iovs; - - IOVList missing; // IOVs not found - missing.push_back(iov); - - std::vector<ICondDBReader*>::iterator layer; - // for each layer - for ( layer = m_layers.begin(); - layer != m_layers.end() && !missing.empty(); - ++layer ) { - - IOVList layer_iovs; - - // look for the missing IOVs in this layer - for ( IOVList::iterator m = missing.begin(); - m != missing.end(); - ++m ) { - IOVList missing_iovs = (*layer)->getIOVs(path, *m, channel); - // if we found something merge with the others in the layer - if (!missing_iovs.empty()) { - // ensure that the found IOVs do not overlap with the already available ones - missing_iovs.front().since = std::max(missing_iovs.front().since, m->since); - missing_iovs.back().until = std::min(missing_iovs.back().until, m->until); - layer_iovs.insert(layer_iovs.end(), missing_iovs.begin(), missing_iovs.end()); - } - else continue; - } - - // if we got IOVs in this layer, we add them to the results list - if (!layer_iovs.empty()) { - iovs.insert(iovs.end(), layer_iovs.begin(), layer_iovs.end()); - std::sort(iovs.begin(), iovs.end()); - // regenerate the list of holes - missing = IOVListHelpers::find_holes(iovs, iov); - } - } - - return iovs; -} - -ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return i_getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return i_getIOVs(path, iov, channel); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) -{ - return getChildNodes(path,node_names,node_names); -} - -namespace { - // helper function - template <class Input, class Output> - void merge(const Input &i, Output &o){ - typename Input::const_iterator it; - for (it = i.begin(); it != i.end(); ++it){ - if (std::find(o.begin(),o.end(),*it)==o.end()) { - o.push_back(*it); - } - } - } -} -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) -{ - // clear the destination vectors - folders.clear(); - foldersets.clear(); - - // Get the folders and foldersets from the dedicated alternative - std::vector<std::string> tmpv1,tmpv2; - StatusCode sc = StatusCode::FAILURE; - std::vector<ICondDBReader*>::iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->getChildNodes(path,tmpv1,tmpv2).isSuccess()){ - // we consider it a success if it worked at least for one of the layers - sc = StatusCode::SUCCESS; - merge(tmpv1,folders); - merge(tmpv2,foldersets); - } - } - return sc; -} -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBLayeringSvc::exists(const std::string &path) { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->exists(path)) return true; - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBLayeringSvc::isFolder(const std::string &path) { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->exists(path)) return (*layer)->isFolder(path); - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBLayeringSvc::isFolderSet(const std::string &path) { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->exists(path)) return (*layer)->isFolderSet(path); - } - return false; -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBLayeringSvc::disconnect() { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - (*layer)->disconnect(); - } -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBLayeringSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - // loop over layers - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - (*layer)->defaultTags(tags); - } -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.h b/Det/DetCond/src/component/CondDBLayeringSvc.h deleted file mode 100755 index c821688ef..000000000 --- a/Det/DetCond/src/component/CondDBLayeringSvc.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef COMPONENT_CONDDBLAYERINGSVC_H -#define COMPONENT_CONDDBLAYERINGSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "DetCond/ICondDBReader.h" -#include <vector> - -template <class TYPE> class SvcFactory; - -/** @class CondDBLayeringSvc CondDBLayeringSvc.h component/CondDBLayeringSvc.h - * - * - * @author Marco CLEMENCIC - * @date 2006-07-14 - */ -class CondDBLayeringSvc: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - -protected: - - /// Standard constructor - CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBLayeringSvc( ); ///< Destructor - -protected: - -private: - - // -------------------- Data Members - - /// Property CondDBLayeringSvc.Layers: list of Access Service layers. - /// They will be searched from the first to the last. - std::vector<std::string> m_layersNames; - - /// Container fo the alternatives. - std::vector<ICondDBReader*> m_layers; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBLayeringSvc>; - - /// Internal implementation helper to generalize the channel type. - template <typename Channel> - IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); - -}; -#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBLogger.cpp b/Det/DetCond/src/component/CondDBLogger.cpp deleted file mode 100755 index 9ec6bc57f..000000000 --- a/Det/DetCond/src/component/CondDBLogger.cpp +++ /dev/null @@ -1,250 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -#include <fstream> - -// local -#include "CondDBLogger.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBLogger) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBLogger -// -// 2008-01-24 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBLogger::CondDBLogger( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc), m_loggedReader(nullptr) { - - declareProperty("LoggedReader", m_loggedReaderName = "", - "Fully qualified name of the ICondDBReader to which the calls" - " have to be forwarded."); - declareProperty("LogFile", m_logFileName = "", - "Path to the log file (it is overwritten if it exists). " - "If not specified or set to empty, the file name is set from " - "the name of the instance plus '.log'." ); - -} -//============================================================================= -// Destructor -//============================================================================= -CondDBLogger::~CondDBLogger() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBLogger::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if ( m_loggedReaderName.empty() ){ - log << MSG::ERROR << "Property LoggedReader is not set." << endmsg; - return StatusCode::FAILURE; - } - - // locate the CondDBReader - sc = service(m_loggedReaderName,m_loggedReader,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << m_loggedReaderName << endmsg; - return sc; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved '" << m_loggedReaderName << "'" << endmsg; - - // Set the default value of the file name if not specified. - if ( m_logFileName.empty() ){ - m_logFileName = name() + ".log"; - log << MSG::INFO << "Property LogFile not specified, using '" - << m_logFileName << "'" << endmsg; - } - - // Open the output file and start writing. - m_logFile = std::unique_ptr<std::ostream>(new std::ofstream(m_logFileName.c_str())); - if ( ! m_logFile->good() ) { - log << MSG::ERROR << "Problems opening " << m_logFileName << endmsg; - return StatusCode::FAILURE; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "File '" << m_logFileName << "' opened for writing." << endmsg; - - (*m_logFile) << "INI: " << Gaudi::Time::current().ns() << " " << name() << " logging " << m_loggedReaderName << std::endl; - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBLogger::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - - if ( m_loggedReader ) { - m_loggedReader->release(); - m_loggedReader = 0; - } - - if (m_logFile.get()) { - (*m_logFile) << "FIN: " << Gaudi::Time::current().ns() << " " << name() << std::endl; - m_logFile.reset(0); - } - - return base_class::finalize(); -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GET: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << when.ns() << " " << std::flush; - StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} -StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GCN: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << when.ns() << " " << std::flush; - StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} - -ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "IOV: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << iov.since.ns() << " " << iov.until.ns() << std::endl; - return m_loggedReader->getIOVs(path, iov, channel); - } - return ICondDBReader::IOVList(); -} - -ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "ICN: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << iov.since.ns() << " " << iov.until.ns() << std::endl; - return m_loggedReader->getIOVs(path, iov, channel); - } - return ICondDBReader::IOVList(); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLogger::getChildNodes (const std::string &path, std::vector<std::string> &node_names) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - StatusCode sc = m_loggedReader->getChildNodes(path,node_names); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLogger::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - StatusCode sc = m_loggedReader->getChildNodes(path,folders,foldersets); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBLogger::exists(const std::string &path) { - if ( m_loggedReader ) { - (*m_logFile) << "XST: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - bool out = m_loggedReader->exists(path); - (*m_logFile) << out << std::endl; - return out; - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBLogger::isFolder(const std::string &path) { - if ( m_loggedReader ) { - (*m_logFile) << "IFL: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - bool out = m_loggedReader->isFolder(path); - (*m_logFile) << out << std::endl; - return out; - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBLogger::isFolderSet(const std::string &path) { - if ( m_loggedReader ) { - (*m_logFile) << "IFS: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - bool out = m_loggedReader->isFolderSet(path); - (*m_logFile) << out << std::endl; - return out; - } - return false; -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBLogger::disconnect() { - if ( m_loggedReader ) { - (*m_logFile) << "DIS: " << Gaudi::Time::current().ns() << std::endl; - m_loggedReader->disconnect(); - } -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBLogger::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - if ( m_loggedReader ) { - (*m_logFile) << "TAG: " << Gaudi::Time::current().ns() << std::endl; - m_loggedReader->defaultTags(tags); - } -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLogger.h b/Det/DetCond/src/component/CondDBLogger.h deleted file mode 100755 index d05fc8fd1..000000000 --- a/Det/DetCond/src/component/CondDBLogger.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef COMPONENT_CONDDBLOGGER_H -#define COMPONENT_CONDDBLOGGER_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "DetCond/ICondDBReader.h" - -template <class TYPE> class SvcFactory; - -/** @class CondDBLogger CondDBLogger.h component/CondDBLogger.h - * - * Logger of acesses to CondDB. - * - * CondDBLogger is a simple class that allow to store in a file all the - * requests made to a ICondDBReader instance. It has to be used as a front-end - * to the instance we want to monitor. - * - * Given the following option snippet - * @code - * MyCondDBUser.Reader = "ACondDBReader"; - * @endcode - * the CondDBLogger can be enabled with - * @code - * CondDBLogger.LoggedReader = "ACondDBReader"; - * MyCondDBUser.Reader = "CondDBLogger"; - * @endcode - * or in python options - * @code - * user = MyCondDBUser() - * user.Reader = CondDBLogger(LoggedReader = user.Reader) - * @endcode - * - * The format of the log file is very simple. Each line starts with an - * operation code then the time of the operation in ns (as returned by - * Gaudi::Time::ns()). The rest of the line depend on the operation: - * - "INI:" - * - Initialization of the logger - * - "TAG:" - * - Request of the used tag - * - "GCH:" - * - Retrieve the child nodes of a folderset. - * - "GET:" - * - Request of an object from the database, the format is<br> - * <path> <channel id> <path> <evt.time> <status> - * - "GCN:" - * - Request of an object from the database using the channel name, the format is<br> - * <path> <channel name> <path> <evt.time> <status> - * - "FIN:" - * - Finalization of the logger - * - "IOV:" - * - Request list of IOVs (using numeric channel) - * - "ICN:" - * - Request list of IOVs (using channel name) - * - * @param LoggedReader - * Fully qualified name of the ICondDBReader to which the calls have to - * be forwarded. - * @param LogFile - * Path to the log file (it is overwritten if it exists). If not - * specified or set to empty, the file name is set from the name of the - * instance plus '.log'. - * - * @author Marco CLEMENCIC - * @date 2008-01-24 - */ -class CondDBLogger: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - -protected: - - /// Standard constructor - CondDBLogger( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBLogger( ); ///< Destructor - -private: - - // -------------------- Data Members - - /// Pointer to the CondDBReader whose activity has to be logged. - ICondDBReader *m_loggedReader; - - /// Name of the CondDBReader whose activity has to be logged. - std::string m_loggedReaderName; - - /// Path to the file that will contain the log. - std::unique_ptr<std::ostream> m_logFile; - - /// Path to the file that will contain the log. - std::string m_logFileName; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBLogger>; - -}; -#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBReplayAlg.cpp b/Det/DetCond/src/component/CondDBReplayAlg.cpp deleted file mode 100755 index 101826444..000000000 --- a/Det/DetCond/src/component/CondDBReplayAlg.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Include files - -// from Gaudi -// needed to sleep between two operations -#include "GaudiKernel/Sleep.h" - -#include "DetCond/ICondDBReader.h" -#include <fstream> - -// local -#include "CondDBReplayAlg.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBReplayAlg -// -// Jan 25, 2008 : Marco Clemencic -//----------------------------------------------------------------------------- - -// Declaration of the Algorithm Factory -DECLARE_ALGORITHM_FACTORY( CondDBReplayAlg ) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBReplayAlg::CondDBReplayAlg( const std::string& name, - ISvcLocator* pSvcLocator) - : GaudiAlgorithm ( name , pSvcLocator ) - , m_reader(NULL) -{ - declareProperty("Reader", m_readerName = "CondDBCnvSvc", - "Name of the reader to use to replay the requests."); - declareProperty("LogFile", m_logFileName = "", - "Path to the log file to re-play. " - "If not specified or set to empty, the file name is set from " - "the name of the instance plus '.log'." ); -} -//============================================================================= -// Destructor -//============================================================================= -CondDBReplayAlg::~CondDBReplayAlg() {} - -//============================================================================= -// Initialization -//============================================================================= -StatusCode CondDBReplayAlg::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Initialize" << endmsg; - - const bool create = true; - m_reader = svc<ICondDBReader>(m_readerName,create); - - // Open the input file. - std::unique_ptr<std::istream> logFile(new std::ifstream(m_logFileName.c_str())); - if ( ! logFile->good() ) { - error() << "Problems opening " << m_logFileName << endmsg; - return StatusCode::FAILURE; - } - info() << "File '" << m_logFileName << "' opened for reading." << endmsg; - - // Parse the input file - std::string opcode, tmp; - operation_t operation; - Gaudi::Time last_time; - Gaudi::Time::ValueType tmptime; - while ( ! logFile->eof() ) { - - (*logFile) >> opcode; - if ("GET:" == opcode || "GCN:" == opcode) { // we use this operation... - - operation.use_numeric_channel = ("GET:" == opcode); - - (*logFile) >> tmptime; operation.time = Gaudi::Time(tmptime); - (*logFile) >> operation.node; - (*logFile) >> tmptime; operation.evttime = Gaudi::Time(tmptime); - - if (operation.use_numeric_channel) { - (*logFile) >> operation.channel; - } - else { - (*logFile) >> operation.chn_name; - } - - if ( last_time > operation.time ) { - error() << "Error in the log file: the operation time is not strictly increasing"; - return StatusCode::FAILURE; - } - - //info() << operation.time.ns() << " " << operation.node << " " << operation.evttime.ns() << " " << operation.channel << endmsg; - last_time = operation.time; - m_operations.push_back(operation); - } - // skip the rest of the line - std::getline(*logFile,tmp); - } - info() << "Found " << m_operations.size() << " operations to replay." << endmsg; - - return StatusCode::SUCCESS; -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode CondDBReplayAlg::execute() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Execute" << endmsg; - - info() << "Replaying database operations ..." << endmsg; - ICondDBReader::DataPtr data; - std::string descr; - Gaudi::Time since, until; - // replay the operations - Gaudi::Time last_optime, last_time; - bool first = true; - for(list_t::iterator op = m_operations.begin(); op != m_operations.end(); ++op) { - - if ( first ) { - // we do not have to wait for the first operation - first = false; - } else { - // calculate how much we have to sleep - Gaudi::Time::ValueType ns_to_sleep = (op->time.ns() - last_optime.ns()) // time between operations - - (Gaudi::Time::current().ns() - last_time.ns()); // time wasted - - if ( ns_to_sleep > 0 ) Gaudi::NanoSleep(ns_to_sleep); - } - - last_optime = op->time; - - // I have to store the current time before the operation otherwise - // we to not count the time that the operation takes as already elapsed. - last_time = Gaudi::Time::current(); - - // Get the object - if (op->use_numeric_channel) { - m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->channel).ignore(); - } - else { - m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->chn_name).ignore(); - } - - } - info() << "Replay completed." << endmsg; - - return StatusCode::SUCCESS; -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode CondDBReplayAlg::finalize() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Finalize" << endmsg; - - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBReplayAlg.h b/Det/DetCond/src/component/CondDBReplayAlg.h deleted file mode 100755 index 9eff90934..000000000 --- a/Det/DetCond/src/component/CondDBReplayAlg.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef CONDDBREPLAYALG_H_ -#define CONDDBREPLAYALG_H_ - -// Include files -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" -#include "GaudiKernel/Time.h" -#include <list> - -class ICondDBReader; - -/** @class CondDBReplayAlg CondDBReplayAlg.h - * - * Simple algorithm that reads a file in the format produced by CondDBLogger - * and re-play the request to the database with the same timing written in the - * log file. - * - * @author Marco Clemencic <marco.clemencic@cern.ch> - * @date 2008-01-25 - */ -class CondDBReplayAlg : public GaudiAlgorithm { -public: - /// Standard constructor - CondDBReplayAlg( const std::string& name, ISvcLocator* pSvcLocator ); - - virtual ~CondDBReplayAlg( ); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization - -protected: - -private: - - /// Path to the file containing the log. - std::string m_logFileName; - - /// Name of the reader to use to replay the requests. - std::string m_readerName; - - /// Pointer to the ICondDBReader service. - ICondDBReader *m_reader; - - struct operation_t { - Gaudi::Time time; - std::string node; - Gaudi::Time evttime; - bool use_numeric_channel; - cool::ChannelId channel; - std::string chn_name; - }; - typedef std::list<operation_t> list_t; - - /// List of operations to perform - list_t m_operations; - -}; - -#endif /*CONDDBREPLAYALG_H_*/ diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp deleted file mode 100755 index f4701c43f..000000000 --- a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/Property.h" -#include "GaudiKernel/IJobOptionsSvc.h" -#include "GaudiKernel/ThreadGaudi.h" - -#include "boost/filesystem/path.hpp" -#include "boost/filesystem/operations.hpp" -#include "boost/filesystem/exception.hpp" - -// local -#include "CondDBSQLiteCopyAccSvc.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBSQLiteCopyAccSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBSQLiteCopyAccSvc -// -// 2007-03-22 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBSQLiteCopyAccSvc::CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ): - CondDBAccessSvc(name,svcloc) -{ - declareProperty("OriginalFile", m_source_path = "" ); - declareProperty("DestinationFile", m_dest_path = "" ); - declareProperty("DBName", m_dbname = "" ); - declareProperty("ForceCopy", m_force_copy = false ); - declareProperty("IgnoreCopyError", m_ignore_copy_error = false ); -} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBSQLiteCopyAccSvc::initialize(){ - //before initializing the parent, I have to copy the file - StatusCode sc = setProperties(); - if ( ! sc.isSuccess() ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Failed to set properties" << endmsg; - return sc; - } - - // this should be done after getting the properties - MsgStream log(msgSvc(), name() ); - - // preliminary checks on the options - if ( m_source_path.empty() ) { - log << MSG::ERROR << "You must provide the source file path via the option '" - << name() << ".OriginalFile'" << endmsg; - return StatusCode::FAILURE; - } - if ( m_dest_path.empty() ) { - log << MSG::ERROR << "You must provide the destination file path via the option '" - << name() << ".DestinationFile'" << endmsg; - return StatusCode::FAILURE; - } - if ( m_dbname.empty() ) { - log << MSG::ERROR << "You must provide the database name via the option '" - << name() << ".DBName'" << endmsg; - return StatusCode::FAILURE; - } - - try { - - // if "force" mode is selected: remove the destination file if it exists - if ( m_force_copy ) { - bool file_existed = boost::filesystem::remove( m_dest_path ); - if ( file_existed ) { - log << MSG::WARNING << "Removed file '" << m_dest_path << "' to replace it" << endmsg; - } - } - - // copy the source file - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Copying " - << m_source_path << " -> " - << m_dest_path << endmsg; - boost::filesystem::copy_file(m_source_path,m_dest_path); - - } - catch (boost::filesystem::filesystem_error &e){ - - MSG::Level lvl = MSG::ERROR; - if ( m_ignore_copy_error ) lvl = MSG::WARNING; - - log << lvl << "Problems occurred copying the file" << endmsg; - log << lvl << e.what() << endmsg; - if ( ! m_ignore_copy_error ) - return StatusCode::FAILURE; - } - - /* - // I need to override the connection string property - IJobOptionsSvc* jos; - const bool CREATEIF(true); - sc = serviceLocator()->service( "JobOptionsSvc", jos, CREATEIF ); - if( sc.isFailure() ) { - log << MSG::ERROR << "Service JobOptionsSvc not found" << endmsg; - } - - sc = jos->addPropertyToCatalogue( getGaudiThreadGenericName(name()), - StringProperty( "ConnectionString", - "sqlite_file:" + m_dest_path + "/" + m_dbname) ); - jos->release(); - if ( ! sc.isSuccess() ) { - log << MSG::ERROR << "Failed to override the property '" << name() << ".ConnectionString'"<< endmsg; - return sc; - } - */ - - // Set the connection string to be used (the one from the base class will be ignored). - m_sqlite_connstring = "sqlite_file:" + m_dest_path + "/" + m_dbname; - - // Initialize the base class. - return CondDBAccessSvc::initialize(); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBSQLiteCopyAccSvc::~CondDBSQLiteCopyAccSvc() {} - -//============================================================================= -// Return the connection string used to connect to the database. -//============================================================================= -const std::string &CondDBSQLiteCopyAccSvc::connectionString() const { - return m_sqlite_connstring; -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h deleted file mode 100755 index 1daecf30c..000000000 --- a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef COMPONENT_CONDDBSQLITECOPYACCSVC_H -#define COMPONENT_CONDDBSQLITECOPYACCSVC_H 1 - -// Include files -#include "CondDBAccessSvc.h" - -/** @class CondDBSQLiteCopyAccSvc CondDBSQLiteCopyAccSvc.h component/CondDBSQLiteCopyAccSvc.h - * - * Extension to CondDBAccessSvc SQLite specific. The original SQLite file is copied to - * a different direcory before being used. This is particularily helpful when the original - * file is accessible only via NFS (see http://www.sqlite.org/faq.html#q7 for details). - * - * @author Marco Clemencic - * @date 2007-03-22 - */ -class CondDBSQLiteCopyAccSvc: public CondDBAccessSvc { - -public: - - /// Initilize the service - virtual StatusCode initialize(); - - /// Return the connection string used to connect to the database. - virtual const std::string &connectionString() const; - - -protected: - /// Standard constructor - CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBSQLiteCopyAccSvc( ); ///< Destructor - -private: - - /// Path to the original file - std::string m_source_path; - /// Path to destination file - std::string m_dest_path; - /// COOL database name - std::string m_dbname; - - /// Whether to overwrite the destination file. - bool m_force_copy; - /// Whether ingore copy error (e.g. if the destination file exists, try to use it) - bool m_ignore_copy_error; - - /// Needed to avoid interference with the connection string set by CondDBAccessSvc - /// standard options (we need to overwrite it). - std::string m_sqlite_connstring; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBSQLiteCopyAccSvc>; - -}; -#endif // COMPONENT_CONDDBSQLITECOPYACCSVC_H diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp b/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp deleted file mode 100755 index 7df80596a..000000000 --- a/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp +++ /dev/null @@ -1,363 +0,0 @@ -// Include files -#ifdef WIN32 // Hacks to compile on Windows... -#define NOMSG -#define NOGDI -#define max max -#endif - -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" -#include "GaudiKernel/SystemOfUnits.h" -#include "GaudiKernel/IDetDataSvc.h" - -// local -#include "CondDBTimeSwitchSvc.h" -#include "CondDBCommon.h" - - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBTimeSwitchSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBTimeSwitchSvc -// -// 2006-07-10 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -// This is needed otherwise the implementation of std::map does -// not find operator<(Gaudi::Time,Gaudi::Time). -namespace Gaudi { using ::operator<; } -//============================================================================= -// Code copied from GaudiKernel Parsers, to have a parser for -// pair<long long,long long>. -// ============================================================================ -// GaudiKernel -// ============================================================================ -// 2011-08-26 : alexander.mazurov@gmail.com -#include "GaudiKernel/ParsersFactory.h" -namespace { - StatusCode parse(std::pair<long long,long long>& result, - const std::string& input){ - return Gaudi::Parsers::parse_(result, input); - } -} -//============================================================================= - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBTimeSwitchSvc::CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc), - m_readersDeclatations(), - m_readers(), - m_latestReaderRequested(0), - m_dds(0) -{ - - // "'CondDBReader':(since, until)", with since and until doubles - declareProperty("Readers", m_readersDeclatations); - - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBTimeSwitchSvc::~CondDBTimeSwitchSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBTimeSwitchSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if (m_readersDeclatations.empty()) { - log << MSG::ERROR << "No CondDBReader has been specified" - " (property 'Readers')." << endmsg; - return StatusCode::FAILURE; - } - - // decoding the property "Readers" - std::string reader_name, reader_siov; - std::pair<long long,long long> reader_iov; - for (ReadersDeclatationsType::iterator rd = m_readersDeclatations.begin(); - rd != m_readersDeclatations.end(); ++rd){ - // first step of parsing (split "'name':value" -> "name","value") - sc = Gaudi::Parsers::parse(reader_name,reader_siov,*rd); - if (sc.isSuccess()) { - // second step (only if first passed) - sc = ::parse(reader_iov,reader_siov); - } - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot decode string '" << *rd << "'" << endmsg; - return sc; - } - // Check for overlaps - const bool quiet = true; - ReaderInfo *old = readerFor(reader_iov.first,quiet); - if (!old) old = readerFor(reader_iov.second,quiet); - if (old) { - log << MSG::ERROR << "Conflicting IOVs between '" << old->name << "':(" - << old->since.ns() << "," << old->until.ns() << ") and " - << *rd << endmsg; - return StatusCode::FAILURE; - } - // use "until" as key to be able to search with "upper_bound" - ReaderInfo ri(reader_name, reader_iov.first, reader_iov.second); - m_readers.insert(std::make_pair(ri.until,ri)); - } - if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { - log << MSG::DEBUG << "Configured CondDBReaders:" << endmsg; - ReadersType::iterator r; - for (r = m_readers.begin(); r != m_readers.end(); ++r) { - log << MSG::DEBUG << " " << r->second.since << " - " << r->second.until - << ": " << r->second.name << endmsg; - } - } - // we need to reset it because it got corrupted during the - // check for overlaps - m_latestReaderRequested = 0; - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBTimeSwitchSvc::finalize(){ - if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(), name()); - log << MSG::DEBUG << "Finalize" << endmsg; - } - - // release all the loaded CondDBReader services - m_readers.clear(); - if(m_dds) { - m_dds->release(); - m_dds = 0; - } - m_readersDeclatations.clear(); - m_latestReaderRequested = 0; - - return base_class::finalize(); -} - -//========================================================================= -// find the appropriate reader -//========================================================================= -CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::readerFor(const Gaudi::Time &when, bool quiet) { - MsgStream log(msgSvc(), name()); - - if (!quiet) log << MSG::VERBOSE << "Get CondDBReader for event time " << when << endmsg; - - // TODO: (MCl) if we change service, we may clear the cache of the one - // that is not needed. - if ((!m_latestReaderRequested) || !m_latestReaderRequested->isValidAt(when)){ - // service not valid: search for the correct one - - // Find the element with key ("until") greater that the requested one - ReadersType::iterator reader = m_readers.upper_bound(when); - if (reader != m_readers.end() && reader->second.isValidAt(when)){ - m_latestReaderRequested = &(reader->second); - } else { - m_latestReaderRequested = 0; // reader not found - if (!quiet) log << MSG::WARNING << "No reader configured for requested event time" << endmsg; - } - } - - return m_latestReaderRequested; -} - -//========================================================================= -// get the current time -//========================================================================= -Gaudi::Time CondDBTimeSwitchSvc::getTime() { - if (!m_dds) { - StatusCode sc = service("DetectorDataSvc",m_dds,false); - if (sc.isFailure()) { - MsgStream log(msgSvc(), name()); - log << MSG::WARNING << "Cannot find the DetectorDataSvc," - " using a default event time (0)" << endmsg; - return Gaudi::Time(); - } - } - return m_dds->eventTime(); -} - -//========================================================================= -// get the current reader -//========================================================================= -CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::currentReader() { - if (!m_latestReaderRequested) { - // Let's stay on the safe side if we don't find a reader - if (readerFor(getTime()) == 0) { - throw GaudiException("No reader configured for current event time", - "CondDBTimeSwitchSvc::currentReader",StatusCode::FAILURE); - } - } - return m_latestReaderRequested; -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, - const Gaudi::Time &when, - DataPtr &data, - std::string &descr, - Gaudi::Time &since, - Gaudi::Time &until, - cool::ChannelId channel) { - // get the reader for the requested time - ReaderInfo *ri = readerFor(when); - if (!ri) return StatusCode::FAILURE; - - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); - if (sc.isSuccess()) ri->cutIOV(since,until); - } - return sc; -} -StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, - const Gaudi::Time &when, - DataPtr &data, - std::string &descr, - Gaudi::Time &since, - Gaudi::Time &until, - const std::string &channel) { - // get the reader for the requested time - ReaderInfo *ri = readerFor(when); - if (!ri) return StatusCode::FAILURE; - - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); - if (sc.isSuccess()) ri->cutIOV(since,until); - } - return sc; - -} - -template <typename Channel> -ICondDBReader::IOVList CondDBTimeSwitchSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) -{ - IOVList iovs; - - IOV tmp; - - // get the list of readers valid in the given time IOV - ReadersType::iterator r; - for(r = m_readers.begin(); r != m_readers.end(); ++r) { - if (r->second.until <= iov.since) continue; // ignore readers before... - if (r->second.since >= iov.until) break; // ...and after the request - - tmp.since = std::max(iov.since, r->second.since); - tmp.until = std::min(iov.until, r->second.until); - - IOVList new_iovs = r->second.reader(serviceLocator())->getIOVs(path, tmp, channel); - if (!new_iovs.empty()) { - // trim the IOVs found - new_iovs.front().since = std::max(tmp.since, new_iovs.front().since); - new_iovs.back().until = std::min(tmp.until, new_iovs.back().until); - - iovs.insert(iovs.end(), new_iovs.begin(), new_iovs.end()); - } - } - return iovs; -} - -ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return i_getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return i_getIOVs(path, iov, channel); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { - return getChildNodes(path,node_names,node_names); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) { - // clear the destination vectors - folders.clear(); - foldersets.clear(); - - // delegate to the current Reader (hoping that is good enough) - return currentReader()->reader(serviceLocator())->getChildNodes(path,folders,foldersets); -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBTimeSwitchSvc::exists(const std::string &path) { - return currentReader()->reader(serviceLocator())->exists(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBTimeSwitchSvc::isFolder(const std::string &path) { - return currentReader()->reader(serviceLocator())->isFolder(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBTimeSwitchSvc::isFolderSet(const std::string &path) { - return currentReader()->reader(serviceLocator())->isFolderSet(path); -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBTimeSwitchSvc::disconnect() { - // loop over all readers - ReadersType::const_iterator reader; - for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { - if (reader->second.loaded()) - reader->second.reader(serviceLocator())->disconnect(); - } -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBTimeSwitchSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - // loop over all readers - ReadersType::const_iterator reader; - for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { - reader->second.reader(serviceLocator())->defaultTags(tags); - } -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.h b/Det/DetCond/src/component/CondDBTimeSwitchSvc.h deleted file mode 100755 index c1eecb386..000000000 --- a/Det/DetCond/src/component/CondDBTimeSwitchSvc.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef COMPONENT_CONDDBTIMESWITCHSVC_H -#define COMPONENT_CONDDBTIMESWITCHSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "GaudiKernel/Map.h" -#include "DetCond/ICondDBReader.h" -#include <vector> -#include <map> - -template <class TYPE> class SvcFactory; -class IDetDataSvc; - -/** @class CondDBTimeSwitchSvc CondDBTimeSwitchSvc.h component/CondDBTimeSwitchSvc.h - * - * - * - * @author Marco Clemencic - * @date 2006-07-10 - */ -class CondDBTimeSwitchSvc: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - - -protected: - /// Standard constructor - CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBTimeSwitchSvc( ); ///< Destructor - - -private: - - /// Internal class to record the readers - struct ReaderInfo { - /// CondDBReader instance name ("type/name") - std::string name; - /// Boundaries of the Interval Of Validity - Gaudi::Time since, until; - /// Default Constructor - ReaderInfo(const std::string &_n, - Gaudi::Time _s = Gaudi::Time::epoch(), - Gaudi::Time _u = Gaudi::Time::max()): - name(_n), - since(_s), - until(_u), - m_reader(0) - {} - /// Default Constructor - ReaderInfo(const std::string &_n, Gaudi::Time::ValueType _s, Gaudi::Time::ValueType _u): - name(_n), - since(_s), - until(_u), - m_reader(0) - {} - /// Copy constructor (for a correct reference counting). - ReaderInfo(const ReaderInfo &_ri): - name(_ri.name), - since(_ri.since), - until(_ri.until), - m_reader(_ri.m_reader) - { - if (m_reader) m_reader->addRef(); - } - /// Destructor (releases the CondDBReader service). - ~ReaderInfo(){ - if (m_reader) m_reader->release(); - } - /// Shortcut to check the validity of the reader - bool isValidAt(const Gaudi::Time &when) const { - return since <= when && until > when; - } - /// Shortcut to retrieve the pointer to the reader service. - ICondDBReader *reader(ISvcLocator *svcloc) const { - if (!m_reader) { - if (!svcloc) - throw GaudiException("ServiceLocator pointer is NULL", - "CondDBTimeSwitchSvc::ReaderInfo::get",StatusCode::FAILURE); - StatusCode sc = svcloc->service(name,m_reader,true); - if (sc.isFailure()) - throw GaudiException("Cannot get ICondDBReader '"+name+"'", - "CondDBTimeSwitchSvc::ReaderInfo::get",sc); - } - return m_reader; - } - /// Shortcut to restrict and IOV to the boundaries defined for the reader - void cutIOV(Gaudi::Time &_since, Gaudi::Time &_until) const { - if ( since > _since ) _since = since; - if ( until < _until ) _until = until; - } - /// convert to a string - std::string toString() const; - /// tell if the reader has already been instantiated - bool loaded() const { - return m_reader; - } - private: - /// Pointer to the CondDBReader instance - mutable ICondDBReader *m_reader; - }; - - /// Get the the CondDBReader valid for a given point in time. - /// Returns 0 if no service is available. - /// The boolean flag is used to avoid messages (during initialization). - ReaderInfo *readerFor(const Gaudi::Time &when, bool quiet = false); - - /// Get the the CondDBReader valid for a given point in time. - /// Returns 0 if no service is available - ReaderInfo *currentReader(); - - /// Get current event time from the detector data svc. - Gaudi::Time getTime(); - - // -------------------- Data Members - typedef std::vector<std::string> ReadersDeclatationsType; - typedef GaudiUtils::Map<Gaudi::Time,ReaderInfo> ReadersType; - - /// Property CondDBTimeSwitchSvc.Readers: list of ICondDBReaders to be used - /// for given intervals of validity. The format is "'Reader': (since, until)", - /// where since and until are doubles defining the time in standard units. - ReadersDeclatationsType m_readersDeclatations; - - /// Container for the alternatives. The ReaderInfo objects are indexed by - /// "until" to allow efficient search with map::upper_bound. - ReadersType m_readers; - - /// Pointer used to cache the latest requested reader. - /// It allows to avoid the search. - ReaderInfo *m_latestReaderRequested; - - /// Pointer to the detector data service, used to get the event time in - /// the methods that do not require it as argument. - /// It used only if there was not a previous request with the time. - IDetDataSvc *m_dds; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBTimeSwitchSvc>; - - /// Internal implementation helper to generalize the channel type. - template <typename Channel> - IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); -}; -#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/IOVListHelpers.cpp b/Det/DetCond/src/component/IOVListHelpers.cpp deleted file mode 100644 index 62ede6d93..000000000 --- a/Det/DetCond/src/component/IOVListHelpers.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "IOVListHelpers.h" - -namespace IOVListHelpers { - ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov) { - - ICondDBReader::IOVList result; - - Gaudi::Time last = iov.since; // keep track of the end of coverage - // loop over covering interval - for (const auto& covered : data ) { - if (covered.since > last) { // hole between the end of coverage and begin of next IOV - result.emplace_back(last, covered.since); - } - last = covered.until; // prepare to look for the next hole - } - if (last < iov.until) { - // we didn't get anything to cover until the end of the requested IOV - result.emplace_back(last, iov.until); - } - - return result; - } -} diff --git a/Det/DetCond/src/component/IOVListHelpers.h b/Det/DetCond/src/component/IOVListHelpers.h deleted file mode 100644 index d660cf962..000000000 --- a/Det/DetCond/src/component/IOVListHelpers.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef IOVLISTHELPERS_H -#define IOVLISTHELPERS_H -#include "DetCond/ICondDBReader.h" - -namespace IOVListHelpers { - /// Find the intervals in passed interval that are not covered by the provided. - ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov); -} - -#endif diff --git a/Det/DetCond/src/component/LoadDDDB.cpp b/Det/DetCond/src/component/LoadDDDB.cpp deleted file mode 100755 index 08beaac28..000000000 --- a/Det/DetCond/src/component/LoadDDDB.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Include files - -// from Gaudi -#include "GaudiKernel/DataStoreItem.h" -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/GaudiException.h" - -// from LHCb -#include "Kernel/ICondDBInfo.h" - -// local -#include "LoadDDDB.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : LoadDDDB -// -// 2005-10-14 : Marco Clemencic -//----------------------------------------------------------------------------- - -// Declaration of the Algorithm Factory -DECLARE_ALGORITHM_FACTORY( LoadDDDB ) - - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -LoadDDDB::LoadDDDB( const std::string& name, - ISvcLocator* pSvcLocator) - : GaudiAlgorithm ( name , pSvcLocator ) -{ - declareProperty("Node", m_treeToLoad = "/dd*"); -} -//============================================================================= -// Destructor -//============================================================================= -LoadDDDB::~LoadDDDB() {} - -//============================================================================= -// Initialization -//============================================================================= -StatusCode LoadDDDB::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Initialize" << endmsg; - - std::vector<LHCb::CondDBNameTagPair> tmp; - svc<ICondDBInfo>("CondDBCnvSvc",true)->defaultTags(tmp); - - std::vector<LHCb::CondDBNameTagPair>::iterator db; - for ( db = tmp.begin(); db != tmp.end(); ++db ) { - info() << "Database " << db->first << " tag " << db->second << endmsg; - } - - updMgrSvc(); // trigger the initialization of the Condition Update sub-system - return StatusCode::SUCCESS; -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode LoadDDDB::execute() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Execute" << endmsg; - - info() << "Loading the DDDB" << endmsg; - - try { - detSvc()->addPreLoadItem(m_treeToLoad); - detSvc()->preLoad(); - } catch (GaudiException &x) { - fatal() << "Gaught GaudiException" << endmsg; - int i = 0; - for ( GaudiException *ex = &x; 0 != ex; ex = ex->previous() ) { - fatal() << std::string(i++,' ') << " ==> " << ex->what() << endmsg; - } - return StatusCode::FAILURE; - } catch (std::exception &x) { - fatal() << "Gaught exception '" << System::typeinfoName(typeid(x)) << "'" - << endmsg; - fatal() << " ==> " << x.what() << endmsg; - return StatusCode::FAILURE; - } catch (...) { - fatal() << "Gaught unknown exception!!" << endmsg; - return StatusCode::FAILURE; - } - info() << "done." << endmsg; - return StatusCode::SUCCESS; -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode LoadDDDB::finalize() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Finalize" << endmsg; - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -//============================================================================= diff --git a/Det/DetCond/src/component/LoadDDDB.h b/Det/DetCond/src/component/LoadDDDB.h deleted file mode 100755 index 584e4f0ac..000000000 --- a/Det/DetCond/src/component/LoadDDDB.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef LOADDDDB_H -#define LOADDDDB_H 1 - -// Include files -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" - - -/** @class LoadDDDB LoadDDDB.h - * - * Load entries in the detector transient store using IDataSvc::preLoad(). - * The node to be loaded is set with the option LoadDDDB.Node. - * - * @author Marco Clemencic - * @date 2005-10-14 - */ -class LoadDDDB : public GaudiAlgorithm { -public: - /// Standard constructor - LoadDDDB( const std::string& name, ISvcLocator* pSvcLocator ); - - virtual ~LoadDDDB( ); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization - -protected: - -private: - - std::string m_treeToLoad; - -}; -#endif // LOADDDDB_H diff --git a/Det/DetCond/src/component/RelyConverter.cpp b/Det/DetCond/src/component/RelyConverter.cpp deleted file mode 100755 index f9b5b8a11..000000000 --- a/Det/DetCond/src/component/RelyConverter.cpp +++ /dev/null @@ -1,479 +0,0 @@ -// Include files -#include "RelyConverter.h" - -#include "GaudiKernel/IConversionSvc.h" -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/IOpaqueAddress.h" -#include "GaudiKernel/IRegistry.h" -#include "GaudiKernel/ISvcLocator.h" -#include "GaudiKernel/DataObject.h" -#include "GaudiKernel/Time.h" -#include "GaudiKernel/IDataManagerSvc.h" - -#include "DetDesc/ValidDataObject.h" - -#include "CoolKernel/IObject.h" -#include "CoolKernel/IRecord.h" -#include "CoolKernel/RecordException.h" - -#include <string> -#include <sstream> - -// local - -//----------------------------------------------------------------------------- -// Implementation file for class : RelyConverter -// -// 2004-12-03 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------- -// Instantiation of a static factory class used by clients to create -// instances of this service -// ----------------------------------------------------------------------- -DECLARE_CONVERTER_FACTORY(RelyConverter) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -RelyConverter::RelyConverter(ISvcLocator* svc): - CondDBGenericCnv(svc,RelyConverter::classID()), - m_detPersSvc(NULL) -{} -//============================================================================= -// Destructor -//============================================================================= -RelyConverter::~RelyConverter() {} - -//========================================================================= -// Initialization -//========================================================================= -StatusCode RelyConverter::initialize() { - // Initializes the grand father - StatusCode sc = CondDBGenericCnv::initialize(); - - sc = serviceLocator()->service("DetectorPersistencySvc", m_detPersSvc, true); - if ( !sc.isSuccess() ) { - MsgStream log(msgSvc(),"RelyConverter"); - log << MSG::ERROR << "Cannot locate IConversionSvc interface of DetectorPersistencySvc" << endmsg; - return sc; - } else { - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved IConversionSvc interface of DetectorPersistencySvc" << endmsg; - } - return sc; -} - -//========================================================================= -// Finalization -//========================================================================= -StatusCode RelyConverter::finalize() { - m_detPersSvc->release(); - return CondDBGenericCnv::finalize(); -} - -//========================================================================= -// Create the transient representation -//========================================================================= -StatusCode RelyConverter::createObj (IOpaqueAddress* pAddress, DataObject *&pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering createObj" << endmsg; - - StatusCode sc = i_delegatedCreation(pAddress,pObject,CreateObject); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot create the object " << pAddress->registry()->identifier() << endmsg; - return sc; - } - - return StatusCode::SUCCESS; -} - -//========================================================================= -// Fill references of the transient representation -//========================================================================= -StatusCode RelyConverter::fillObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering fillObjRefs" << endmsg; - - StatusCode sc = i_delegatedCreation(pAddress,pObject,FillObjectRefs); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot fill object's refs" << endmsg; - return sc; - } - - return StatusCode::SUCCESS; -} - -//========================================================================= -// Update transient representation from persistent one -//========================================================================= -StatusCode RelyConverter::updateObj (IOpaqueAddress* pAddress, DataObject* pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Method updateObj starting" << endmsg; - - DataObject* pNewObject; // create a new object and copy it to the old version - StatusCode sc = i_delegatedCreation(pAddress,pNewObject,CreateObject); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot create the new object" << endmsg; - return sc; - } - - // do the real update - // - // Since DataObject::operator= operator is not virtual, dynamic cast first! - // Overloaded virtual method Condition::update() must be properly defined! - // The memory pointed to by the old pointer must contain the new object - // Andrea Valassi - - ValidDataObject* pVDO = dynamic_cast<ValidDataObject*>(pObject); - ValidDataObject* pNewVDO = dynamic_cast<ValidDataObject*>(pNewObject); - if ( 0 == pVDO || 0 == pNewVDO ) { - log << MSG::ERROR - << "Cannot update objects other than ValidDataObject: " - << "update() must be defined!" - << endmsg; - return StatusCode::FAILURE; - } - // Deep copy the new Condition into the old DataObject - pVDO->update( *pNewVDO ); - - // Delete the useless Condition - delete pNewVDO; - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Object successfully updated" << endmsg; - return StatusCode::SUCCESS; -} - -//========================================================================= -// Update references of the transient representation -//========================================================================= -StatusCode RelyConverter::updateObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering updateObjRefs" << endmsg; - - StatusCode sc = i_delegatedCreation(pAddress,pObject,UpdateObjectRefs); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot update object's refs" << endmsg; - return sc; - } - - return StatusCode::SUCCESS; -} - -//========================================================================= -// Create the persistent representation -//========================================================================= -StatusCode RelyConverter::createRep (DataObject* /*pObject*/, IOpaqueAddress*& /*pAddress*/) -{ - MsgStream log(msgSvc(),"RelyConverter"); - log << MSG::WARNING << "createRep() not implemented" << endmsg; - return StatusCode::SUCCESS; -} - -//========================================================================= -// Update the persistent representation -//========================================================================= -StatusCode RelyConverter::updateRep (IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) -{ - MsgStream log(msgSvc(),"RelyConverter"); - log << MSG::WARNING << "updateRep() not implemented" << endmsg; - return StatusCode::SUCCESS; -} - -//========================================================================= -// Create an object by delegation -//========================================================================= -StatusCode RelyConverter::i_delegatedCreation(IOpaqueAddress* pAddress, DataObject *&pObject, Operation op){ - StatusCode sc; - - MsgStream log(msgSvc(),"RelyConverter"); - - ICondDBReader::DataPtr data; - std::string description; - Gaudi::Time since,until; - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Entering \"i_delegatedCreation\"" << endmsg; - - std::string path = pAddress->par()[0]; - std::string data_field_name = "data"; - - // Extract the COOL field name from the condition path - std::string::size_type at_pos = path.find('@'); - if ( at_pos != path.npos ) { - std::string::size_type slash_pos = path.rfind('/',at_pos); - if ( slash_pos+1 < at_pos ) { // item name is not null - data_field_name = path.substr(slash_pos+1,at_pos - (slash_pos +1)); - } // if I have "/@", I should use the default ("data") - // always remove '@' from the path - path = path.substr(0,slash_pos+1) + path.substr(at_pos+1); - } - - sc = getObject(path, pAddress->ipar()[0], data, description, since, until); - if ( !sc.isSuccess() ) return sc; - - if ( !data ) { - switch (op) { - case CreateObject: - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Path points to a FolderSet: create a directory" << endmsg; - - // I hit a FolderSet!!! I handle it here (at least for the moment, since it's the only CondDB real converter) - pObject = new DataObject(); - - break; - - case FillObjectRefs: - { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Create addresses for sub-folders" << endmsg; - - // find subnodes - std::vector<std::string> children; - - sc = getChildNodes(path,children); - if ( !sc.isSuccess() ) return sc; - - // add registries for the sub folders - for ( std::vector<std::string>::iterator c = children.begin(); c != children.end(); ++c ) { - - IOpaqueAddress *childAddress; - std::string par[2]; - // in current implementation, the child folders have a '/' in front. - // So I need to treat in a different way the case of a parent COOL root folderset - // to avoid thing like "//folder" - if ( path == "/" ) { - par[0] = *c; - } else { - par[0] = path + *c; - } - par[1] = *c; - unsigned long ipar[2] = { 0,0 }; - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Create address for " << par[0] << endmsg; - sc = conversionSvc()->addressCreator()->createAddress(CONDDB_StorageType, - CLID_Catalog, - par, - ipar, - childAddress); - if ( !sc.isSuccess() ) return sc; - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Address created" << endmsg; - - sc = dataManager()->registerAddress(pAddress->registry(), *c, childAddress); - if ( !sc.isSuccess() ) return sc; - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Address registered" << endmsg; - } - } - break; - - case UpdateObjectRefs: - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Update references not supported for FolderSet" << endmsg; - break; - } - - return StatusCode::SUCCESS; - } - - long storage_type = getStorageType(path,description); - if (storage_type <= 0) { - log << MSG::ERROR << - "Folder description does not contain a valid storage type: " << endmsg; - log << MSG::ERROR << "desc = \"" << description << "\"" << endmsg; - return StatusCode::FAILURE; - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "delegate to DetectorPersistencySvc" << endmsg; - - std::string xml_data; - try { - xml_data = (*data.get())[data_field_name].data<std::string>(); - } catch (cool::RecordSpecificationUnknownField &e) { - log << MSG::ERROR << "I cannot find the data inside COOL object: " << e.what() << endmsg; - return StatusCode::FAILURE; - } - - // for XML string temporary address, I need a way to know which is the originating href - std::ostringstream src_href; - src_href << "conddb:" << pAddress->par()[0] << ":" << pAddress->ipar()[0]; - - // Create temporary address for the relevant type and classID - IOpaqueAddress *tmpAddress = createTmpAddress(src_href.str(), - storage_type, - pAddress->par()[1], - pAddress->clID(), - xml_data, - log, - conversionSvc()->addressCreator()); - if (!tmpAddress) return StatusCode::FAILURE; - - tmpAddress->addRef(); - if ( pAddress->registry() ){ - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "register tmpAddress to registry " << pAddress->registry()->identifier() - << endmsg; - } else { - log << MSG::WARNING << "the address does not have a registry" << endmsg; - } - tmpAddress->setRegistry(pAddress->registry()); - if (tmpAddress->registry()) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "tmpAddress registered to registry " << tmpAddress->registry()->identifier() - << endmsg; - } else { - log << MSG::WARNING << "tmpAddress not registered!" << endmsg; - } - - switch (op) { - case CreateObject: - sc = m_detPersSvc->createObj ( tmpAddress, pObject ); - break; - case FillObjectRefs: - sc = m_detPersSvc->fillObjRefs ( tmpAddress, pObject ); - break; - case UpdateObjectRefs: - sc = m_detPersSvc->updateObjRefs ( tmpAddress, pObject ); - break; - } - - tmpAddress->release(); - if ( sc.isFailure() ) { - log << MSG::ERROR - << "Persistency service could not create a new object" << endmsg; - return sc; - } - - if (op == CreateObject){ - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Setting object validity" << endmsg; - setObjValidity(since,until,pObject); - - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "New object successfully created" << endmsg; - - return StatusCode::SUCCESS; -} - -//============================================================================= - -long RelyConverter::getStorageType(const std::string &path, const std::string &desc){ - // the description string should contain a substring of the form (regexp) - // "< *storage_type *= *[0-9]+ *>" - - if ( path.rfind(".xml") != path.npos ) return XML_StorageType; - - const char delimiter_begin = '<'; - const char delimiter_end = '>'; - const char delimiter_sep = '='; - const std::string delimiter_keyword = "storage_type"; - - std::string::size_type pos_start; - std::string::size_type pos_end; - std::string::size_type pos_max; - - pos_start = pos_end = pos_max = desc.size(); - - std::string::size_type tmp_pos = 0; - - while ( pos_start == pos_max || pos_end <= pos_start ){ - // find the next occurrence of '<' - tmp_pos = desc.find(delimiter_begin,tmp_pos); - if (tmp_pos >= pos_max) break; // not found - - // skip spaces - ++tmp_pos; - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // check for the keyword - if (desc.compare(tmp_pos, delimiter_keyword.size(), delimiter_keyword) != 0) continue; - - // skip spaces - tmp_pos += delimiter_keyword.size(); - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // check for the separator - if ( desc[tmp_pos] != delimiter_sep ) continue; - - // skip spaces - ++tmp_pos; - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // here should start the "int" - pos_start = tmp_pos; - - // "count" the digits - while ( desc[tmp_pos] >= '0' && desc[tmp_pos] <= '9' ) ++tmp_pos; - - // here should be just after the "int" - pos_end = tmp_pos; - - if ( pos_start == pos_end ) continue; // no number found - - // skip spaces - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // check for the delimiter_end - if ( desc[tmp_pos] != delimiter_end ) { - // force another loop even if the number was found; - pos_start = pos_end = pos_max; - continue; - } - } - - if ( pos_start == pos_max || pos_end <= pos_start ) { // not found - return -1; - } - - std::istringstream i(desc.substr(pos_start, pos_end-pos_start)); - - long st; - i >> st; - - return st; -} - -IOpaqueAddress *RelyConverter::createTmpAddress(const std::string &src, - long storageType, - const std::string &name, - const CLID &clId, - const std::string &data, - MsgStream &log, - SmartIF<IAddressCreator>& creator) { - - if (storageType <= 0) { - log << MSG::ERROR << "invalid storage type " << storageType << endmsg; - return 0; - } - - // Create temporary address for the relevant type and classID - IOpaqueAddress *tmpAddress; - - // for XML string temporary address, I need a way to know which is the originating href - const std::string par[3] = { data, - name, - src }; - unsigned long ipar[2] = { 1,0 }; - StatusCode sc = creator->createAddress(storageType, clId , par, ipar, tmpAddress); - if (sc.isFailure()){ - log << MSG::ERROR - << "Persistency service could not create a new address" << endmsg; - return 0; - } - - return tmpAddress; -} diff --git a/Det/DetCond/src/component/RelyConverter.h b/Det/DetCond/src/component/RelyConverter.h deleted file mode 100755 index 0af71524c..000000000 --- a/Det/DetCond/src/component/RelyConverter.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef COMPONENT_RELYCONVERTER_H -#define COMPONENT_RELYCONVERTER_H 1 - -// Include files -#include "DetCond/CondDBGenericCnv.h" - -// Forward and external declarations -class ISvcLocator; -template <class TYPE> class CnvFactory; - -/** @class RelyConverter RelyConverter.h component/RelyConverter.cpp - * - * ConditionsDBCnvSvc rely on the functionalities provided by the XmlCnvSvc. - * RelyConverter delegate the creation of the object to the XmlCnvSvc - * (via DetectorPersistencySvc). - * - * @author Marco CLEMENCIC - * @date 2004-12-03 - */ -class RelyConverter: public CondDBGenericCnv { - - /// Friend needed for instantiation - friend class CnvFactory<RelyConverter>; - -public: - - /// Operations that can be performed by delegation - enum Operation { - CreateObject, - FillObjectRefs, - UpdateObjectRefs - }; - - /** - * Initializes the converter - * @return status depending on the completion of the call - */ - virtual StatusCode initialize(); - - /** - * Finalizes the converter - * @return status depending on the completion of the call - */ - virtual StatusCode finalize(); - - /** - * Creates the transient representation of an object. - * @param pAddress the address of the object representation - * @param pObject the object created - * @return status depending on the completion of the call - */ - virtual StatusCode createObj (IOpaqueAddress *pAddress, - DataObject *&pObject); - /** - * Resolve the references of the created transient object. - * @param pAddress the address of the object representation - * @param pObject the object created - * @return status depending on the completion of the call - */ - virtual StatusCode fillObjRefs (IOpaqueAddress *pAddress, - DataObject *pObject); - /** - * Resolve the references of the just updated transient object. - * @param pAddress the address of the object representation - * @param pObject the object created - * @return status depending on the completion of the call - */ - virtual StatusCode updateObjRefs (IOpaqueAddress *pAddress, - DataObject *pObject); - /** - * Updates the transient object from the other representation (not implemented). - * @param pAddress the address of the object representation - * @param pObject the object updated - * @return status depending on the completion of the call - */ - virtual StatusCode updateObj (IOpaqueAddress *pAddress, - DataObject *pObject); - - /** - * Converts the transient object to the requested representation (not implemented). - * @param refpAddress the address of the object representation - * @param pObject the object to convert - * @return status depending on the completion of the call - */ - virtual StatusCode createRep (DataObject* pObject, - IOpaqueAddress*& refpAddress); - - /** - * Updates the converted representation of a transient object. - * @param pAddress the address of the object representation - * @param pObject the object whose representation has to be updated - * @return status depending on the completion of the call - */ - virtual StatusCode updateRep (IOpaqueAddress* pAddress, - DataObject* pObject); - - /** - * Accessor to the type of elements that this converter converts. - * @return the classID for this type - */ - static const CLID& classID () { return CLID_Any; } - -protected: - /// Standard constructor - RelyConverter(ISvcLocator* svc); - virtual ~RelyConverter( ); ///< Destructor - -private: - - /** - * Do the needed steps to perform a creation by delegation. - */ - StatusCode i_delegatedCreation(IOpaqueAddress* pAddress, - DataObject *&pObject, - Operation op = CreateObject); - -public: - /** - * Extract the storage_type from the folder or description. - */ - static long getStorageType(const std::string &path, const std::string &desc); - - /** Generate a temporary IOpaqueAddress to be passed to a PersistencySvc for - * the actual conversion. - * - * @param src originating URL (required by the XML format) - * @param storageType storage type ID (@see getStorageType) - * @param name name of the object inside the storage container - * @param data data to embed in the address - * @param log MsgStream instance to report errors - * @param creator IAdressCreator to use - * - * @return an IOpaqueAddress pointer in case of success, 0 in case of failure. - */ - static IOpaqueAddress *createTmpAddress(const std::string &src, - long storageType, - const std::string &name, - const CLID &clId, - const std::string &data, - MsgStream &log, - SmartIF<IAddressCreator>& creator); - -private: - /// Handle to the IConversionSvc interface of the DetectorPersistencySvc - IConversionSvc* m_detPersSvc; - -}; -#endif // COMPONENT_XMLRELYCNV_H diff --git a/Det/DetCond/src/component/RunStampCheck.cpp b/Det/DetCond/src/component/RunStampCheck.cpp deleted file mode 100644 index ee7d310d0..000000000 --- a/Det/DetCond/src/component/RunStampCheck.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "GaudiKernel/Service.h" -#include "GaudiKernel/IIncidentListener.h" -#include "GaudiKernel/IIncidentSvc.h" -#include "GaudiKernel/Kernel.h" -#include "GaudiKernel/IDetDataSvc.h" -#include "GaudiKernel/IEventProcessor.h" -#include "DetCond/ICondDBReader.h" - -/** Simple service to check if the run stamp condition exists for the current - * event. - * - * To ensure that the content of the conditions database includes alignments - * and calibrations for the event being processed, when these conditions are - * stored we also store a special condition with closed Interval Of Validity - * (IOV) covering only the run for which they are valid (RunStamp condition). - * - * The time line of the RunStamp conditions is not completely covered, and the - * holes in the time line implicitly flag the events for which the alignments - * are not available. - * - * When RunStampCheck is instantiated in a Gaudi application, it checks for - * each event time if the RunStamp condition exists or not, in which case the - * application is terminated with an error code. - * - * So, to enable the check, it is enough to add to the options: - * \code{.py} - * from Configurables import ApplicationMgr, RunStampCheck - * ApplicationMgr().ExtSvc.append(RunStampCheck()) - * \endcode - * - * \see https://its.cern.ch/jira/browse/LBCORE-831 - * \see https://its.cern.ch/jira/browse/LHCBPS-1421 - */ -class RunStampCheck: public extends1<Service, IIncidentListener> { -public: - /// Constructor. Declares properties. - RunStampCheck(const std::string& name, ISvcLocator* svcloc): - base_class(name, svcloc) { - declareProperty("RunStamp", m_runStampCondition, - "Path in the conditions database of the RunStamp condition."); - declareProperty("CondDBReader", m_condDBReaderName, - "Name of the ICondDBReader instance to query for the RunStamp."); - } - /// Connect to the required services and register as BeginEvent listener. - StatusCode start() override { - StatusCode sc = Service::start(); - if (UNLIKELY(!sc)) return sc; - - // ensure that we have the EventClocksvc (to get the current event time in - // the DetectorDataSvc). - if (UNLIKELY(!serviceLocator()->service("EventClockSvc"))) { - error() << "Cannot get EventClockSvc" << endmsg; - return StatusCode::FAILURE; - } - - m_incSvc = serviceLocator()->service("IncidentSvc"); - if (UNLIKELY(!m_incSvc)) { - error() << "Cannot get IncidentSvc" << endmsg; - return StatusCode::FAILURE; - } - m_incSvc->addListener(this, IncidentType::BeginEvent); - - m_condDBReader = serviceLocator()->service(m_condDBReaderName); - if (UNLIKELY(!m_condDBReader)) { - error() << "Cannot get " << m_condDBReaderName << endmsg; - return StatusCode::FAILURE; - } - - m_detSvc = serviceLocator()->service("DetectorDataSvc"); - if (UNLIKELY(!m_detSvc)) { - error() << "Cannot get DetectorDataSvc" << endmsg; - return StatusCode::FAILURE; - } - - m_evtProc = serviceLocator(); - if (UNLIKELY(!m_detSvc)) { - error() << "Cannot get IEventProcessor" << endmsg; - return StatusCode::FAILURE; - } - - // reset the IOV for the current run (to something not valid) - m_currentRunIOV = {Gaudi::Time::epoch(), Gaudi::Time::epoch()}; - return sc; - } - /// Deregister as BeginEvent listener and release reference to services. - StatusCode stop() override { - m_incSvc->removeListener(this, IncidentType::BeginEvent); - m_incSvc.reset(); - m_condDBReader.reset(); - m_detSvc.reset(); - m_evtProc.reset(); - return Service::stop(); - } - /// Handle the BeginEvent incident to check if the RunStamp condition exists. - void handle(const Incident&) override { - auto when = m_detSvc->eventTime(); - // run the check only if the current event time falls outside the boundaries - // of the current run - if (when < m_currentRunIOV.since || when >= m_currentRunIOV.until) { - if (UNLIKELY(msgLevel(MSG::DEBUG))) - debug() << "Checking '" << m_runStampCondition - << "' for event time " << when << endmsg; - ICondDBReader::DataPtr p; - std::string desc; - StatusCode sc = m_condDBReader->getObject(m_runStampCondition, when, - p, desc, - m_currentRunIOV.since, m_currentRunIOV.until); - if (!sc) { - // we didn't manage to get the entry from the DB: we do not have data - // for this run - error() << "Database not up-to-date. No valid data for run at " - << when.format(false, "%Y-%m-%d %H:%M:%S") - << "." << when.nanoformat() << " UTC" << endmsg; - m_evtProc->stopRun(); - } else if (UNLIKELY(msgLevel(MSG::DEBUG))) { - debug() << "Found '" << m_runStampCondition - << "' valid in [" << m_currentRunIOV.since - << ", " << m_currentRunIOV.until << ")" << endmsg; - } - } - } -private: - /// Path in the conditions database of the RunStamp condition. - std::string m_runStampCondition = "/Conditions/Online/LHCb/RunStamp.xml"; - /// Path in the conditions database of the RunStamp condition. - std::string m_condDBReaderName = "CondDBCnvSvc"; - /// reference to the incident service. - SmartIF<IIncidentSvc> m_incSvc; - /// reference to the CondDB reader. - SmartIF<ICondDBReader> m_condDBReader; - /// reference to the detector transient store. - SmartIF<IDetDataSvc> m_detSvc; - /// reference to the event processor. - SmartIF<IEventProcessor> m_evtProc; - - /// IOV of the current RunStamp. - ICondDBReader::IOV m_currentRunIOV; -}; - -DECLARE_COMPONENT(RunStampCheck) diff --git a/Det/DetCond/src/dict/DetCondDict.h b/Det/DetCond/src/dict/DetCondDict.h deleted file mode 100755 index 48ebf7619..000000000 --- a/Det/DetCond/src/dict/DetCondDict.h +++ /dev/null @@ -1,38 +0,0 @@ -// ============================================================================ -#ifndef DETCOND_DETCONDDICT_H -#define DETCOND_DETCONDDICT_H 1 -// ============================================================================ -// Hack to get round gccxml parsing problem (SEAL bug 9704) -// ============================================================================ -#ifdef _WIN32 -#define LONG_LONG_MAX 0x7fffffffffffffffLL /*maximum signed __int64 value */ -#define LONG_LONG_MIN 0x8000000000000000LL /*minimum signed __int64 value */ -#define ULONG_LONG_MAX 0xffffffffffffffffLL /*maximum unsigned __int64 value */ -#endif -// ============================================================================ -// GaudiKernel -// ============================================================================ -#include "GaudiKernel/Time.h" -// ============================================================================ -// DetCond -// ============================================================================ -#include "DetCond/ICondDBAccessSvc.h" -#include "DetCond/ICondDBEditor.h" -#include "DetCond/ICondDBReader.h" -#include "DetCond/ICOOLConfSvc.h" -// ============================================================================ -// CORAL (not available through PyCool) -// ============================================================================ -#include "RelationalAccess/ConnectionService.h" -#include "RelationalAccess/IConnectionServiceConfiguration.h" -#include "RelationalAccess/IReplicaSortingAlgorithm.h" -// ============================================================================ -namespace _instantiations { - struct Instantiations { - ICondDBReader::IOVList _i1; - }; -} -// ============================================================================ -#endif // DETCOND_DETCONDDICT_H -// ============================================================================ - diff --git a/Det/DetCond/src/dict/DetCondDict.xml b/Det/DetCond/src/dict/DetCondDict.xml deleted file mode 100755 index f77b7e2a3..000000000 --- a/Det/DetCond/src/dict/DetCondDict.xml +++ /dev/null @@ -1,14 +0,0 @@ -<lcgdict> - - <class name="ICondDBReader" /> - <class name="ICondDBReader::IOV" /> - <class name="ICondDBReader::IOVList" /> - <class name="ICondDBEditor" /> - <class name="ICondDBAccessSvc" /> - <class name="ICOOLConfSvc" /> - - <class name="coral::IReplicaSortingAlgorithm" /> - <class name="coral::IConnectionService" /> - <class name="coral::IConnectionServiceConfiguration" /> - -</lcgdict> diff --git a/Det/DetCond/tests/data/DQFLAGS.db b/Det/DetCond/tests/data/DQFLAGS.db deleted file mode 100644 index 3d22d8afaf1d4504118821a0ce9ea7e18272305a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48128 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 diff --git a/Det/DetCond/tests/data/HBTEST.db b/Det/DetCond/tests/data/HBTEST.db deleted file mode 100644 index 9f920f0ad02fe5b7fa8eb3bd9665321079dd0863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76800 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 diff --git a/Det/DetCond/tests/data/RSTEST.db b/Det/DetCond/tests/data/RSTEST.db deleted file mode 100644 index 3515b986f69afa926d429fed453e8b8ec2bccefd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48128 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 RI0E+s0c!at2=p7{{{!*sn#TYD diff --git a/Det/DetCond/tests/data/TESTDB0.db b/Det/DetCond/tests/data/TESTDB0.db deleted file mode 100755 index 8b4accc2b6482e618dd4f1a4f2889ca964a149c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183296 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 OmqP}+Lj*P-f&UM@pb-H8 diff --git a/Det/DetCond/tests/data/TESTDB1.db b/Det/DetCond/tests/data/TESTDB1.db deleted file mode 100755 index 58d9abbd4b60ffef0f56a298db91069aaf558389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79872 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 diff --git a/Det/DetCond/tests/data/TESTDB2.db b/Det/DetCond/tests/data/TESTDB2.db deleted file mode 100755 index 85025de79ca3b6799d245910308c24dd3edbe17d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79872 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 baEUHTlnyT0JlQ$E|DD4fpAmumgTVg->-`Q9 diff --git a/Det/DetCond/tests/data/TESTDB3.db b/Det/DetCond/tests/data/TESTDB3.db deleted file mode 100755 index 2c58dab3ef0a1e0c3e6e9e95300a73ab98c08d0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183296 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 diff --git a/Det/DetCond/tests/data/genDQFLAGS.py b/Det/DetCond/tests/data/genDQFLAGS.py deleted file mode 100644 index 3d343c185..000000000 --- a/Det/DetCond/tests/data/genDQFLAGS.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -""" -Small script to generate the test database for the heart beat test. -(kept for reference) -""" - -from CondDBUI import CondDB -from PyCool import cool -from datetime import datetime, timedelta - -def toTimeStamp(dt): - t = dt - datetime(1970, 1, 1, 0) - return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 - -db = CondDB("sqlite_file:DQFLAGS.db/DQFLAGS", readOnly = False, create_new_db = True) - -db.createNode("/Conditions", storageType = "NODE") -db.createNode("/Conditions/DQ", storageType = "NODE") -db.createNode("/Conditions/DQ/Flags", versionMode = "SINGLE") - -def cond(d): - data = ['<item key="%s" value="%d"/>' % i for i in d.items()] - return """<?xml version='1.0' encoding='ISO-8859-1'?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> - <condition name="Flags"> - <map keytype="string" name="map" valuetype="int"> - %s - </map> - </condition> -</DDDB> -""" % ("\n ".join(data)) - -for since, until, d in [(datetime(2012, 1, 1, 0), datetime(2012, 1, 2, 0), {"DET1": 1}), - (datetime(2012, 1, 2, 0), datetime(2012, 1, 3, 0), {"DET2": 1}), - (datetime(2012, 1, 3, 0), datetime(2012, 1, 4, 0), {}), - (datetime(2012, 1, 5, 0), datetime(2012, 1, 6, 0), {"DET3": 1})]: - since, until = map(toTimeStamp, (since, until)) - db.storeXMLString("/Conditions/DQ/Flags", cond(d), since, until) diff --git a/Det/DetCond/tests/data/genHBTEST.py b/Det/DetCond/tests/data/genHBTEST.py deleted file mode 100644 index 9544d8d17..000000000 --- a/Det/DetCond/tests/data/genHBTEST.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -""" -Small script to generate the test database for the heart beat test. -(kept for reference) -""" - -from CondDBUI import CondDB -from PyCool import cool - -base_time = 1262304000 # (2010, 1, 1, 0, 0, 0, 4, 1, 0) GMT -unit = 60 - -db = CondDB("sqlite_file:HBTEST.db/HBTEST", readOnly = False, create_new_db = True) - -db.createNode("/Conditions", storageType = "NODE") -db.createNode("/Conditions/Online", storageType = "NODE") -db.createNode("/Conditions/Online/HeartBeatTest", storageType = "NODE") -db.createNode("/Conditions/Online/HeartBeatTest/Condition1", versionMode = "SINGLE") -db.createNode("/Conditions/Online/HeartBeatTest/Condition2", versionMode = "SINGLE") -db.createNode("/Conditions/Online/HeartBeatTest/Tick", versionMode = "SINGLE") - -cond = """<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> - <condition name = "Condition%d"> - <param name = "Data" type = "int"> %d </param> - </condition> -</DDDB> -""" - -db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, 0), 0, cool.ValidityKeyMax) -for t in [20, 40]: - db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) - -db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, 0), 0, cool.ValidityKeyMax) -for t in [20, 40, 80]: - db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) - -hb = """<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> -<condition name="Tick"> -<param name="Alive" type="int">1</param> -</condition> -</DDDB> -""" -db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, 0, cool.ValidityKeyMax) -db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, (base_time + 60 * unit) * 1000000000, cool.ValidityKeyMax) diff --git a/Det/DetCond/tests/data/genRSTEST.py b/Det/DetCond/tests/data/genRSTEST.py deleted file mode 100755 index b20f67c00..000000000 --- a/Det/DetCond/tests/data/genRSTEST.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -""" -Small script to generate the test database for the run stamp test. -(kept for reference) -""" - -from CondDBUI import CondDB -from PyCool import cool - -def ts(*args): - from datetime import datetime - epoch = datetime(1970, 1, 1) - return int((datetime(*args) - epoch).total_seconds() * 1000000000) - -db = CondDB("sqlite_file:RSTEST.db/RSTEST", readOnly = False, create_new_db = True) - -db.createNode("/Conditions", storageType = "NODE") -db.createNode("/Conditions/Online", storageType = "NODE") -db.createNode("/Conditions/Online/LHCb", storageType = "NODE") -db.createNode("/Conditions/Online/LHCB/RunInfo", versionMode = "SINGLE") -db.createNode("/Conditions/Online/LHCb/RunStamp.xml", versionMode = "SINGLE") - -rs = """<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> -<condition name="RunStamp"> -<param name="RunNumber" type="int">1</param> -</condition> -</DDDB> -""" -db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 9), ts(2015, 6, 10)) -db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 11), ts(2015, 6, 12)) diff --git a/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt b/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt deleted file mode 100755 index 3d63ec802..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") - -from Configurables import DetCondTest__bug_80076 -alg = DetCondTest__bug_80076("Bug80076") -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1"] -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 3) -#MessageSvc(OutputLevel = 1) - -#from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -</text></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check that we find the expected lines in the right order -expected = [ - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 0.0 -> 1262305200.0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262305200.0 -> 1262306400.0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - ] - -regexp = r"^---|^Validity" - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt b/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt deleted file mode 100755 index 3ccd88fd5..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/check_db_reading.py</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt b/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt deleted file mode 100755 index 75e6f9405..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/configuration_module_test.py</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt b/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt deleted file mode 100644 index 1a70fb044..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/connection_timeout.py</text></argument> -<argument name="validator"><text> -findReferenceBlock(""" -TEST ===> start -DDDB.TimeOutChe... INFO Disconnect from database after being idle for 5s (will reconnect if needed) -TEST ===> end -""") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt deleted file mode 100755 index 94bc9a6d0..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>1</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/ObjectA -/dd/AutoMap/FolderSet2/ObjectB -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt deleted file mode 100755 index fe3b24ca6..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>2</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -/dd/AutoMap/FolderSet3 -/dd/AutoMap/FolderSet3/Object1 -/dd/AutoMap/FolderSet3/Object2 -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt deleted file mode 100755 index e7c6714a0..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>3</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -/dd/AutoMap/FolderSet2/ObjectA -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt deleted file mode 100755 index 965dce340..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>0</text></set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt deleted file mode 100755 index ea4f3ebcf..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>4</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -/dd/AutoMap/FolderSet2/ObjectA -/dd/AutoMap/FolderSet2/ObjectB -/dd/AutoMap/FolderSet3 -/dd/AutoMap/FolderSet3/Object1 -/dd/AutoMap/FolderSet3/Object2 -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt deleted file mode 100755 index 90cc2a5a8..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import DetCondTest__DQScanTest as DQScanTest -from Configurables import CondDBDQScanner, DDDBConf, CondDB, EventClockSvc, FakeEventTime - -from datetime import datetime, timedelta -def toTimeStamp(dt): - if isinstance(dt, timedelta): - t = dt - else: - t = dt - datetime(1970, 1, 1, 0) - return (t.days * 60 * 60 * 24 + t.seconds) - -def toTimeStampNS(dt): - return toTimeStamp(dt) * 1000000000 - -dddbConf = DDDBConf() - -cdb = CondDB() -cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" -cdb.Tags["DQFLAGS"] = "" - -ecs = EventClockSvc(InitialTime=toTimeStampNS(datetime(2012,1,1,12))) -ecs.addTool(FakeEventTime, "EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = ecs.InitialTime -ecs.EventTimeDecoder.TimeStep = toTimeStampNS(timedelta(days=1)) - -alg = DQScanTest() -alg.DQScanner = CondDBDQScanner() - -tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0)), - (datetime(2012,1,1,12), datetime(2012,1,3,12)), - (datetime(2012,1,2,12), datetime(2012,1,5,12)), - (datetime(2012,1,4,12), datetime(2012,1,6,12)), - (datetime(2012,1,3,12), datetime(2012,1,4,12)), - ] - -alg.IOVs = [(toTimeStamp(a), toTimeStamp(b)) for a, b in tests] - -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) -MessageSvc(OutputLevel = WARNING) - -</text></argument> -<argument name="validator"><text> -findReferenceBlock(""" -ApplicationMgr INFO Application Manager Started successfully -DetCondTest::DQ...SUCCESS Process IOV 1325376000.0 -> 1325635200.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325419200.0 -> 1325592000.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325505600.0 -> 1325764800.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET2: 1, DET3: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325678400.0 -> 1325851200.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET3: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325592000.0 -> 1325678400.0 -DetCondTest::DQ...SUCCESS -> Flags: {} -ApplicationMgr INFO Application Manager Stopped successfully -""") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt b/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt deleted file mode 100644 index 22a8fb7c8..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/force_disconnect.py</text></argument> -<argument name="validator"><text> -findReferenceBlock(""" -TEST ===> start -LHCBCOND DEBUG Forced disconnect from database (will reconnect automatically) -LHCBCOND.TimeOu...VERBOSE Stopping -DQFLAGS DEBUG Database already disconnected -ONLINE_2008 DEBUG Forced disconnect from database (will reconnect automatically) -ONLINE_2008.Tim...VERBOSE Stopping -DDDB DEBUG Forced disconnect from database (will reconnect automatically) -DDDB.TimeOutChe...VERBOSE Stopping -TEST ===> reconnect -ONLINE_2008.Tim...VERBOSE Starting -DDDB.TimeOutChe...VERBOSE Starting -TEST ===> end -""") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt deleted file mode 100755 index 14360891b..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/getIOVs.py</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt b/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt deleted file mode 100755 index 3542de97d..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -import GaudiKernel.SystemOfUnits as Units -Units.hours = Units.s * 3600 -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" -HBTEST.QueryGranularity = 1 * Units.hours -HBTEST.OutputLevel = DEBUG - -MessageSvc().setDebug.append("HBTEST.Cache") - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") -CondDB().QueryGranularity = 1 * Units.hours - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] -alg.LoadDuringInitialize = True -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) -#MessageSvc(OutputLevel = 1) - -from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] -UpdateManagerSvc().OutputLevel = DEBUG -MessageSvc().setDebug += ["UpdateManagerSvc::Item"] -</text></argument> -<argument name="exit_code"><integer>0</integer></argument> -<argument name="validator"><text> -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 MISSING -HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 0 - 1262305200000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262306400000000000 - 9223372036854775807, channel : 0 -HBTEST.Cache DEBUG Conflict found: item not inserted -HBTEST.Cache DEBUG IOV : 1262306400000000000 - 9223372036854775807 -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 FOUND -''', signature_offset = 1, id = "first_cond1") - -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 MISSING -HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 0 - 1262305200000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262306400000000000 - 1262308800000000000, channel : 0 -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 FOUND -''', signature_offset = 1, id = "first_cond2") - -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262305800000000000 channel 0 FOUND -''', signature_offset = 1, id = "second_cond1") - -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262305800000000000 channel 0 FOUND -''', signature_offset = 1, id = "second_cond2") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt b/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt deleted file mode 100644 index f7bbfbeb5..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] -alg.LoadDuringInitialize = True -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 4) -#MessageSvc(OutputLevel = 1) - -from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] -UpdateManagerSvc().OutputLevel = DEBUG -MessageSvc().setDebug += ["UpdateManagerSvc::Item"] -</text></argument> -<argument name="exit_code"><integer>4</integer></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check for bug #66497 (Velo motion system updated several times during initialization) -# 'marker1' must appear only once before 'maker2' -marker1 = "Condition2 from data provider" -marker2 = "Conditions loaded at initialize" -count = 0 -for l in outputlines: - if marker2 in l: - break - if marker1 in l: - count += 1 -if count != 1: - causes.append("bug #66497") - result["GaudiTest.marker.value"] = result.Quote(marker1) - result["GaudiTest.marker.count"] = result.Quote(str(count)) - result["GaudiTest.marker.count_expected"] = result.Quote("1") - -## Check that we find the expected lines in the right order -expected = [ - 'DetCondTest::Te... INFO Conditions loaded at initialize', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262308800.0 -> 1262307600.0', - '(int) Data = 80', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - 'HBTEST ERROR Database not up-to-date. Latest known update is at 2010-01-01 01:00:00.0 UTC, event time is 2010-01-01 01:10:00.0 UTC' - ] - -regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Conditions loaded at initialize|HBTEST.*ERROR" - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt b/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt deleted file mode 100644 index d35694016..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc() -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = 5 -ecs.EventTimeDecoder.TimeStep = 10 - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/Conditions/This/Does/Not/Exist"] -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) -#MessageSvc(OutputLevel = 1) - -</text></argument> -<argument name="exit_code"><integer>4</integer></argument> -<argument name="validator"><text> -## Find the error message about the problematic condition -import re -regexp = r"ERROR.*Conditions/This/Does/Not/Exist" -if not re.findall(regexp, stdout): - causes.append("output") - result["GaudiTest.output.expected_regexp"] = result.Quote(regexp) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt b/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt deleted file mode 100644 index f92224120..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - UpdateManagerSvc, CondDBAccessSvc, RunStampCheck) - -def ts(*args): - from datetime import datetime - epoch = datetime(1970, 1, 1) - return int((datetime(*args) - epoch).total_seconds() * 1000000000) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = ts(2015, 6, 10, 12, 00)) # no RunStamp for this time -ecs.addTool(FakeEventTime, "EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = ts(2015, 6, 9, 12, 00) -ecs.EventTimeDecoder.TimeStep = 24 * 60 * 60 * 1000000000 # 1 day - -RSTEST = CondDBAccessSvc("RSTEST", ConnectionString="sqlite_file:../data/RSTEST.db/RSTEST") - -CondDB().addAlternative(RSTEST, "/Conditions/Online/LHCb/RunStamp.xml") -CondDB().EnableRunStampCheck = True -RunStampCheck(OutputLevel=DEBUG) - -algMgr = ApplicationMgr(EvtSel = "NONE", EvtMax = 4) -#MessageSvc(OutputLevel = 1) -</text></argument> -<argument name="exit_code"><integer>4</integer></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check that we find the expected lines in the right order -expected = ''' -RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433851200.0 -RunStampCheck DEBUG Found '/Conditions/Online/LHCb/RunStamp.xml' valid in [1433808000.0, 1433894400.0) -RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433937600.0 -RunStampCheck ERROR Database not up-to-date. No valid data for run at 2015-06-10 12:00:00.0 UTC -EventLoopMgr SUCCESS Terminating event processing loop due to a stop scheduled by an incident listener -EventLoopMgr SUCCESS Terminating event processing loop due to scheduled stop -'''.strip().splitlines() - -regexp = '^(RunStampCheck.*(Checking|Found|Database)|.*Terminating event processing)' -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt b/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt deleted file mode 100755 index 7f49cd9bd..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt +++ /dev/null @@ -1,71 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc() -ecs.addTool(FakeEventTime, "EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = 5 -ecs.EventTimeDecoder.TimeStep = 10 - -DBs = [] -for i in [0,3]: - data = { "name": "TESTDB%d"%i } - DBs.append(CondDBAccessSvc(data["name"], - ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) -readers = [] -for i in range(len(DBs)): - readers.append("'%s':(%d,%d)"%(DBs[i].getFullName(),i*10,(i+1)*10)) - -CondDB().addLayer(CondDBTimeSwitchSvc(Readers = readers, OutputLevel = DEBUG)) - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/AutoMap/FolderSet1/Object1"] -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) -#MessageSvc(OutputLevel = 1) - -</text></argument> -<argument name="validator"><text> -## 1st check: Find reference block -reference_block = """ -CondDBTimeSwitc... DEBUG Configured CondDBReaders: -CondDBTimeSwitc... DEBUG 0.0 - 0.00000001: CondDBAccessSvc/TESTDB0 -CondDBTimeSwitc... DEBUG 0.00000001 - 0.00000002: CondDBAccessSvc/TESTDB3 -""" -findReferenceBlock(reference_block) - -## 2nd check: find data -expected = [ - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/AutoMap/FolderSet1/Object1', - 'Validity: 0.0 -> 0.00000001', - '(int) Data = 1', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/AutoMap/FolderSet1/Object1', - 'Validity: 0.00000001 -> 0.00000002', - '(int) Data = 2'] - -regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions" -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt b/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt deleted file mode 100755 index 45a455863..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") - -from Configurables import DetCondTest__FinalizationEvtLoop -alg = DetCondTest__FinalizationEvtLoop() -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] -alg.InitialTime = ecs.EventTimeDecoder.StartTime -alg.Step = ecs.EventTimeDecoder.TimeStep -alg.FinalTime = alg.InitialTime + 3 * alg.Step -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) -#MessageSvc(OutputLevel = 1) - -#from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -</text></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check that we find the expected lines in the right order -expected = [ - 'DetCondTest::Fi... INFO Update for event time 1262304600.0', - 'DetCondTest::Fi... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - 'DetCondTest::Fi... INFO Update for event time 1262305800.0', - 'DetCondTest::Fi... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - 'DetCondTest::Fi... INFO Update for event time 1262307000.0', - 'DetCondTest::Fi... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - - ] - -regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Update for event time" - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/scripts/check_db_reading.py b/Det/DetCond/tests/scripts/check_db_reading.py deleted file mode 100755 index b3f23c080..000000000 --- a/Det/DetCond/tests/scripts/check_db_reading.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python - -import unittest - -import sys - -#import string -#import random - -class DetCondReadingTest(unittest.TestCase): - -# def assertEqualsConfig(self, lhs, rhs): -# self.assertEquals(lhs.getFullName(), rhs.getFullName()) - - def setUp(self): - unittest.TestCase.setUp(self) - self.testDB = 'sqlite_file:../data/TESTDB3.db/TESTDB3' - self.testFolder = '/lhcb.xml' - self.testout = '<?xml version="1.0" encoding="ISO-8859-1"?>\n<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd">\n<DDDB>\n <catalog name="dd">\n <catalogref href="AutoMap" />\n </catalog> \n</DDDB> \n' - self.Nmethods = 1 # number of methods - - def readDB(self): - from CondDBUI import CondDB - db = CondDB(self.testDB) - s = self.testFolder - if not db.db.existsFolder(s): return "" - data = db.getPayload(s,0,0) - if 'data' not in data: return "" - return data['data'] - -# def tearDown(self): -# unittest.TestCase.tearDown(self) - - def test_reading(self): - """Check CondDB reading """ - ret = self.readDB() - self.assertEquals(self.testout, ret) - -if __name__ == '__main__': - unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/configuration_module_test.py b/Det/DetCond/tests/scripts/configuration_module_test.py deleted file mode 100755 index 36276a6d7..000000000 --- a/Det/DetCond/tests/scripts/configuration_module_test.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python - -import unittest - -from Gaudi.Configuration import * -import GaudiKernel.Configurable -from GaudiKernel.Configurable import purge, applyConfigurableUsers -from Configurables import CondDB, DDDBConf -from Configurables import (CondDBCnvSvc, - CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc) - -#import logging -#from GaudiKernel.ProcessJobOptions import InstallRootLoggingHandler -#InstallRootLoggingHandler(level = logging.DEBUG) - -orig_reader = None -orig_dict = None -def equalConfigurable(lhs, rhs): - return lhs.getFullName() == rhs.getFullName() - -class DetCondConfigurationTest(unittest.TestCase): - - def assertEqualsConfig(self, lhs, rhs): - self.assertEquals(lhs.getFullName(), rhs.getFullName()) - - def setUp(self): - unittest.TestCase.setUp(self) - self.DDDB = DDDBConf() - self.CondDB = CondDB() - - def tearDown(self): - self.DDDB = self.CondDB = None - purge() - GaudiKernel.Configurable._appliedConfigurableUsers_ = False - unittest.TestCase.tearDown(self) - - def checkHeartBeat(self, conf, chkstr = ""): - conf = allConfigurables[eval(conf.split(':')[0]).split("/")[1]] - if isinstance(conf, CondDBLayeringSvc): - conf = conf.Layers[-1]# Only check the bottom layer - self.assertEquals(conf.getProp("HeartBeatCondition"), chkstr) - - - def test_000_originalConfiguration(self): - """Check the default configuration""" - applyConfigurableUsers() - global orig_reader, orig_dict - orig_reader = allConfigurables["CondDBCnvSvc"].CondDBReader - self.assertEquals(orig_reader.__class__.__name__, - "CondDBDispatcherSvc") - orig_dict = dict(orig_reader.Alternatives) - - def test_010_addCondDBLayer_1(self): - """Add one layer from CondDBAccessSvc instance""" - # Add the layer - layer = CondDBAccessSvc("layer") - self.CondDB.addLayer(layer) - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # check if we have a layering svc - self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") - # check for the new layer... - self.assertEqual(reader.Layers[0], layer) - # ... plus the original one - self.assertEqualsConfig(reader.Layers[1], orig_reader) - - def test_010_addCondDBLayer_2(self): - """Add layers from allowed Configurable instances""" - # Add the layers (one per type) - types = [CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc] - layers = [] - for i in range(len(types)): - layer = types[i]("layer_%d"%i) - layers.append(layer) - self.CondDB.addLayer(layer) - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # check if we have a layering svc - self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") - # correct size? - self.assertEquals(len(reader.Layers), len(layers) + 1) - # correct order (inverse of insertion order)... - layers.reverse() - for i in range(len(types)): - self.assertEqual(reader.Layers[i], layers[i]) - # ... plus the original one - self.assertEqualsConfig(reader.Layers[len(layers)], orig_reader) - - def test_020_addCondDBAlternative_1(self): - """Add one alternative from CondDBAccessSvc instance""" - # Add the alternative - alternative = CondDBAccessSvc("alternative") - self.CondDB.addAlternative(alternative, "/Test") - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # the reader should not have changed - self.assertEqualsConfig(reader, orig_reader) - # correct size? - self.assertEquals(len(reader.Alternatives), len(orig_dict) + 1) - # check the previous alternatives - for k in orig_dict: - self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) - # plus the new one - self.assertEqualsConfig(reader.Alternatives["/Test"], alternative) - - def test_020_addCondDBAlternative_2(self): - """Replace one alternative from CondDBAccessSvc instance""" - path = orig_dict.keys()[0] - - # Add the alternative - alternative = CondDBAccessSvc("alternative") - self.CondDB.addAlternative(alternative, path) - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # the reader should not have changed - self.assertEqualsConfig(reader, orig_reader) - # correct size? - self.assertEquals(len(reader.Alternatives), len(orig_dict)) - # check the previous alternatives - for k in orig_dict: - if k != path: - self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) - else: - self.assertEqualsConfig(reader.Alternatives[k], alternative) - - def test_030_heartbeat(self): - """HeartBeat condition (off-line, Oracle, default)""" - self.CondDB.Online = False - self.CondDB.UseOracle = True - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") - - def test_031_heartbeat(self): - """HeartBeat condition (off-line, Oracle, ignore)""" - self.CondDB.Online = False - self.CondDB.UseOracle = True - self.CondDB.IgnoreHeartBeat = True - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "") - - def test_032_heartbeat(self): - """HeartBeat condition (off-line, SQLite, default)""" - self.CondDB.Online = False - self.CondDB.UseOracle = False - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers[:-1]: - self.checkHeartBeat(conf, "") - conf = online.Readers[-1] - self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") - - def test_033_heartbeat(self): - """HeartBeat condition (off-line, SQLite, ignore)""" - self.CondDB.Online = False - self.CondDB.UseOracle = False - self.CondDB.IgnoreHeartBeat = True - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers: - self.checkHeartBeat(conf, "") - - def test_040_heartbeat(self): - """HeartBeat condition (on-line, Oracle, not ignore)""" - self.CondDB.Online = True - self.CondDB.UseOracle = True - self.CondDB.IgnoreHeartBeat = False - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") - - def test_041_heartbeat(self): - """HeartBeat condition (on-line, Oracle, default)""" - self.CondDB.Online = True - self.CondDB.UseOracle = True - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "") - - def test_042_heartbeat(self): - """HeartBeat condition (on-line, SQLite, not ignore)""" - self.CondDB.Online = True - self.CondDB.UseOracle = False - self.CondDB.IgnoreHeartBeat = False - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers[:-1]: - self.checkHeartBeat(conf, "") - conf = online.Readers[-1] - self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") - - def test_043_heartbeat(self): - """HeartBeat condition (on-line, SQLite, default)""" - self.CondDB.Online = True - self.CondDB.UseOracle = False - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers: - self.checkHeartBeat(conf, "") - -if __name__ == '__main__': - unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/connection_timeout.py b/Det/DetCond/tests/scripts/connection_timeout.py deleted file mode 100644 index aac17167b..000000000 --- a/Det/DetCond/tests/scripts/connection_timeout.py +++ /dev/null @@ -1,22 +0,0 @@ -## @file -# Small script forcing a time-out in the access to the -from Gaudi.Configuration import * -from Configurables import CondDB, CondDBAccessSvc, DDDBConf - -DDDBConf() - -DDDB = CondDBAccessSvc("DDDB") -DDDB.ConnectionTimeOut = 5 - -#MessageSvc(OutputLevel = ERROR) - -import GaudiPython -app = GaudiPython.AppMgr() -app.initialize() -app.start() - -import time -app.detSvc()["/dd"] # access the DB -print "TEST ===> start" -time.sleep(6) # wait enough -print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/direct_mapping_test.py b/Det/DetCond/tests/scripts/direct_mapping_test.py deleted file mode 100755 index 10515b6fe..000000000 --- a/Det/DetCond/tests/scripts/direct_mapping_test.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python -""" -Script for the test of possible use-cases of the direct mapping between -the COOL hierarchy and the transient store one. -Use-cases: - 0) basic mapping (CondDBAccessSvc) - 1) alternative for a folderset in the main DB - 2) alternative for a folderset _not_ in the main DB - 3) alternative for a folder _not_ in the main DB - 4) layers -""" -__author__ = "Marco Clemencic" - -def configure(version): - from Gaudi.Configuration import (importOptions, - ApplicationMgr, - MessageSvc) - from Configurables import DDDBConf, CondDB, CondDBAccessSvc - dddbConf = DDDBConf() - cdb = CondDB() - - DBs = [] - for i in range(3): - data = { "name": "TESTDB%d"%i } - DBs.append(CondDBAccessSvc(data["name"], - ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) - - cdb.PartitionConnectionString["DDDB"] = DBs[0].ConnectionString - cdb.Tags["DDDB"] = "" - if version == 1: - cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2') - elif version == 2: - cdb.addAlternative(DBs[2],'/AutoMap/FolderSet3') - elif version == 3: - cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2/ObjectA') - elif version == 4: - cdb.addLayer(DBs[1]) - cdb.addLayer(DBs[2]) - elif version != 0: - raise RuntimeError("Invalid version number") - - ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") - #MessageSvc(OutputLevel = 1) - -def datastore_walk(ds, top = "/"): - if top == "/": - top = ds._idm.rootName() - obj = ds[top] - if obj is not None: - yield ds[top] - nodes = [ i.identifier() for i in ds.leaves(ds[top]) ] - for n in nodes: - for obj in datastore_walk(ds,n): - yield obj - -def node_names(ds, top = "/"): - return [ obj.registry().identifier() for obj in datastore_walk(ds,top) ] - -def main(conf): - configure(conf) - - from Gaudi.Configuration import configurationDict - from pprint import pprint - import GaudiPython - app = GaudiPython.AppMgr() - pprint(configurationDict()) - app.initialize() - - dds = app.detsvc() - # load everything in the store - nodes = node_names(dds) - nodes.sort() - - print "=== Begin Nodes ===" - for n in nodes: - print n - print "=== End Nodes ===" - -if __name__ == '__main__': - import sys - if len(sys.argv) < 2: - version = 0 - else: - version = int(sys.argv[1]) - - main(version) diff --git a/Det/DetCond/tests/scripts/force_disconnect.py b/Det/DetCond/tests/scripts/force_disconnect.py deleted file mode 100644 index e504010ab..000000000 --- a/Det/DetCond/tests/scripts/force_disconnect.py +++ /dev/null @@ -1,28 +0,0 @@ -## @file -# Small script forcing a time-out in the access to the -from Gaudi.Configuration import * -from Configurables import CondDB, CondDBAccessSvc, DDDBConf - -DDDBConf(DataType="2008") - -#DDDB = CondDBAccessSvc("DDDB") -#DDDB.ConnectionTimeOut = 5 - -partitions = ['DDDB', 'ONLINE_2008', 'LHCBCOND', 'DQFLAGS'] -msg = MessageSvc(OutputLevel=WARNING) -msg.setDebug.extend(partitions) -msg.setVerbose.extend([p + '.TimeOutChecker' for p in partitions]) - -import GaudiPython -app = GaudiPython.AppMgr() -app.initialize() -app.start() - -import time -app.detSvc()["/dd/Conditions/Online/LHCb"] # access the DB -print "TEST ===> start" -reader = app.service('CondDBCnvSvc', GaudiPython.gbl.ICondDBReader) -reader.disconnect() -print "TEST ===> reconnect" -app.detSvc()["/dd/Conditions/Online/LHCb/Tick"] # access the DB -print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/getIOVs.py b/Det/DetCond/tests/scripts/getIOVs.py deleted file mode 100755 index 8aa9c2cd4..000000000 --- a/Det/DetCond/tests/scripts/getIOVs.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python -""" -Script for the test of IOV retrieval -""" -__author__ = "Marco Clemencic" - -import sys -from datetime import datetime, timedelta - -def toTimeStamp(dt): - if isinstance(dt, timedelta): - t = dt - else: - t = dt - datetime(1970, 1, 1, 0) - return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 - -def toDateTime(ts): - return datetime(1970, 1, 1, 0) + timedelta(seconds=ts/1000000000) - -def configure(): - from Gaudi.Configuration import (ApplicationMgr, - MessageSvc, ERROR) - from Configurables import DDDBConf, CondDB, CondDBAccessSvc, EventClockSvc, FakeEventTime - dddbConf = DDDBConf() - cdb = CondDB() - - cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" - cdb.Tags["DQFLAGS"] = "" - - ecs = EventClockSvc(InitialTime=toTimeStamp(datetime(2012,1,1,12))) - ecs.addTool(FakeEventTime, "EventTimeDecoder") - ecs.EventTimeDecoder.StartTime = ecs.InitialTime - ecs.EventTimeDecoder.TimeStep = toTimeStamp(timedelta(days=1)) - - ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") - MessageSvc(OutputLevel = ERROR) - -def checkIOVs(dbReader, since, until, expected): - import GaudiPython - IOV = GaudiPython.gbl.ICondDBReader.IOV - Time = GaudiPython.gbl.Gaudi.Time - - print "Checking %s -> %s ..." % (since, until), - t1 = Time(toTimeStamp(since)) - t2 = Time(toTimeStamp(until)) - iov = IOV(t1, t2) - result = dbReader.getIOVs("/Conditions/DQ/Flags", iov, 0) - - found = [(toDateTime(iov.since.ns()), toDateTime(iov.until.ns())) for iov in result] - - good = found == expected - if not good: - print "ERROR" - print " expected:", [tuple(map(str, iov)) for iov in expected] - print " found: ", [tuple(map(str, iov)) for iov in found] - else: - print "OK" - return good - -def main(): - configure() - - from Gaudi.Configuration import configurationDict - from pprint import pprint - import GaudiPython - app = GaudiPython.AppMgr() - pprint(configurationDict()) - app.initialize() - - dq = app.service("DQFLAGS", GaudiPython.gbl.ICondDBReader) - - dbData = [(datetime(2012,1,1,0), datetime(2012,1,2,0)), - (datetime(2012,1,2,0), datetime(2012,1,3,0)), - (datetime(2012,1,3,0), datetime(2012,1,4,0)), - (datetime(2012,1,5,0), datetime(2012,1,6,0))] - - tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0), dbData[0:3]), - (datetime(2012,1,1,12), datetime(2012,1,3,12), dbData[0:3]), - (datetime(2012,1,2,12), datetime(2012,1,5,12), dbData[1:4]), - (datetime(2012,1,4,12), datetime(2012,1,6,12), dbData[3:4]), - ] - print "\n=== Begin Tests ===" - bad = 0 - for since, until, expected in tests: - if not checkIOVs(dq, since, until, expected): - bad += 1 - print "=== End Tests ===" - - if bad: - print "\nFailed %d tests out of %d\n" % (bad, len(tests)) - sys.exit(1) - - print "" - -if __name__ == '__main__': - main() diff --git a/Det/DetCond/tests/src/DQScanTest.cpp b/Det/DetCond/tests/src/DQScanTest.cpp deleted file mode 100644 index 6ff5a6faa..000000000 --- a/Det/DetCond/tests/src/DQScanTest.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Local custom parsers must be defined very early in the file. -#include "GaudiKernel/ParsersFactory.h" - -namespace Gaudi { - namespace Parsers { - // Note: to be kept in sync with the property in DetCondTest::DQScanTest - StatusCode parse(std::vector<std::pair<unsigned int, unsigned int> >& result, const std::string& input) { - return Gaudi::Parsers::parse_(result, input); - } - } -} - -// Include files - -#include "DetCond/ICondDBReader.h" - -// local -#include "DQScanTest.h" - -#include "boost/foreach.hpp" - -namespace { - inline long long s2ns(unsigned int s) { - return static_cast<long long>(s) * 1000000000; - } -} - -// ---------------------------------------------------------------------------- -// Implementation file for class: DQScanTest -// -// 31/01/2012: Marco Clemencic -// ---------------------------------------------------------------------------- -DECLARE_NAMESPACE_ALGORITHM_FACTORY(DetCondTest, DQScanTest) - -namespace DetCondTest { -// ============================================================================ -// Standard constructor, initializes variables -// ============================================================================ -DQScanTest::DQScanTest(const std::string& name, ISvcLocator* pSvcLocator) - : GaudiAlgorithm(name, pSvcLocator), m_scanner(0) -{ - declareProperty("DQScanner", - m_DQScannerName = "CondDBDQScanner", - "Type/name of the IDQScanner instance to use."); - declareProperty("IOVs", - m_iovsProp, - "List of IOVs (specified in seconds) to scan."); -} - -// ============================================================================ -// Destructor -// ============================================================================ -DQScanTest::~DQScanTest() {} - -// ============================================================================ -// Initialization -// ============================================================================ -StatusCode DQScanTest::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; - - m_scanner = tool<IDQScanner>(m_DQScannerName); - - m_iovs.clear(); - BOOST_FOREACH(IOVPropType &iov, m_iovsProp) { - m_iovs.push_back(ICondDBReader::IOV(Gaudi::Time(s2ns(iov.first)), Gaudi::Time(s2ns(iov.second)))); - } - - return StatusCode::SUCCESS; -} - -// ============================================================================ -// Main execution -// ============================================================================ -StatusCode DQScanTest::execute() { - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; - - info() << "Execute" << endmsg; - - BOOST_FOREACH(ICondDBReader::IOV &iov, m_iovs) { - always() << "Process IOV " << iov.since << " -> " << iov.until << endmsg; - IDQFilter::FlagsType result = m_scanner->scan(iov.since, iov.until); - always() << "-> Flags: " << result << endmsg; - } - - return StatusCode::SUCCESS; -} - -// ============================================================================ -// Finalize -// ============================================================================ -StatusCode DQScanTest::finalize() { - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; - - if (release(m_scanner).isFailure()) { - warning() << "Failed to release tool " << m_DQScannerName << endmsg; - } - m_scanner = 0; - - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -// ============================================================================ -} // namespace DetCondTest diff --git a/Det/DetCond/tests/src/DQScanTest.h b/Det/DetCond/tests/src/DQScanTest.h deleted file mode 100644 index 78d13b015..000000000 --- a/Det/DetCond/tests/src/DQScanTest.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef SRC_DQSCANTEST_H -#define SRC_DQSCANTEST_H 1 -// Include files -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" - -#include "Kernel/IDQScanner.h" - -#include "DetCond/ICondDBReader.h" - -namespace DetCondTest { - -/** @class DQScanTest DQScanTest.h src/DQScanTest.h - * - * Algorithm to test the behavior of an IDQScanner implementation. - * - * @author Marco Clemencic - * @date 31/01/2012 - */ -class DQScanTest: public GaudiAlgorithm { -public: - typedef std::pair<unsigned int, unsigned int> IOVPropType; - typedef std::vector<IOVPropType> IOVListPropType; - - /// Standard constructor - DQScanTest(const std::string& name, ISvcLocator* pSvcLocator); - virtual ~DQScanTest(); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization -protected: -private: - - /// Type/name of the IDQScanner instance. - /// (property DQScanner) - std::string m_DQScannerName; - - /// List of IOVs (with time specified in seconds) to try to retrieve (property). - IOVListPropType m_iovsProp; - - /// List of IOVs to try to retrieve. - ICondDBReader::IOVList m_iovs; - - /// Pointer to the IDQScanner instance. - IDQScanner *m_scanner; -}; - -} - -#endif // SRC_DQSCANTEST_H diff --git a/Det/DetCond/tests/src/TestConditionAlg.cpp b/Det/DetCond/tests/src/TestConditionAlg.cpp deleted file mode 100755 index d749e5d05..000000000 --- a/Det/DetCond/tests/src/TestConditionAlg.cpp +++ /dev/null @@ -1,287 +0,0 @@ -// Include files -#include "GaudiKernel/Map.h" -#include "GaudiAlg/GaudiAlgorithm.h" -#include "GaudiKernel/IDetDataSvc.h" -#include "DetDesc/Condition.h" - -#include <vector> - -namespace DetCondTest { - -/** @class TestConditionAlg TestConditionAlg.h component/TestConditionAlg.h - * - * Simple algorithm that prints the requested conditions at every event. - * - * @author Marco CLEMENCIC - * @date 2008-06-27 - */ -class TestConditionAlg : public GaudiAlgorithm { -public: - /// Standard constructor - TestConditionAlg( const std::string& name, ISvcLocator* pSvcLocator ); - - virtual ~TestConditionAlg( ); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization - -protected: - - void i_dump(); - - /// Names of the conditions to print - std::vector<std::string> m_condPaths; - - /// Flag to decide if the conditions have to be loaded also during the - /// initialize step. - bool m_loadAtInit; - - /// Container of the conditions to print - std::vector<std::string> m_conditionDeps; - - /// Container of the conditions to print - GaudiUtils::Map<std::string,Condition*> m_conditions; -}; - -//----------------------------------------------------------------------------- -// Implementation file for class : TestConditionAlg -// -// 2008-06-27 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -TestConditionAlg::TestConditionAlg( const std::string& name, - ISvcLocator* pSvcLocator) - : GaudiAlgorithm ( name , pSvcLocator ) -{ - declareProperty("Conditions", m_condPaths, - "list of paths to conditions in the detector transient store"); - declareProperty("LoadDuringInitialize", m_loadAtInit = false, - "load the requested conditions already during the initialization"); - declareProperty("ConditionsDependencies", m_conditionDeps, - "declare dependencies between objects as a list of strings 'A -> B') " - "to indicate that the condition A depends on B."); -} -//============================================================================= -// Destructor -//============================================================================= -TestConditionAlg::~TestConditionAlg() {} - -namespace { - void printDepsError(MsgStream& stream, - size_t lineNo, const std::string& msg, - const std::string& line) { - stream << "Syntax error in item " << lineNo - << " of ConditionsDependencies: " << msg << endmsg; - stream << " '" << line << "'" << endmsg; - } -} -//============================================================================= -// Initialization -//============================================================================= -StatusCode TestConditionAlg::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; - - std::vector<std::string>::const_iterator path; - for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ - registerCondition<TestConditionAlg>(*path,m_conditions[*path],NULL); - } - - std::vector<std::string>::const_iterator deps; - for (deps = m_conditionDeps.begin(); deps != m_conditionDeps.end(); ++deps) { - std::string::size_type pos = deps->find("->"); - if (pos == std::string::npos) { - printDepsError(error(), deps - m_conditionDeps.begin(), "missing '->'", *deps); - return StatusCode::FAILURE; - } - std::string::size_type p0, p1; - p0 = deps->find_first_not_of(" \n\r\t"); - p1 = deps->find_last_not_of(" \n\r\t", pos - 1) + 1; - std::string first(*deps, p0, p1 - p0); - if (first.empty()) { - printDepsError(error(), deps - m_conditionDeps.begin(), "missing first argument", *deps); - return StatusCode::FAILURE; - } - p0 = deps->find_first_not_of(" \n\r\t", pos + 2); - p1 = deps->find_last_not_of(" \n\r\t") + 1; - std::string second(*deps, p0, p1 - p0); - if (second.empty()) { - printDepsError(error(), deps - m_conditionDeps.begin(), "missing second argument", *deps); - return StatusCode::FAILURE; - } - info() << "Declaring dependency of '" << first << "' on '" << second << "'" << endmsg; - updMgrSvc()->registerCondition(getDet<Condition>(first), second); - } - - if (m_loadAtInit) { - sc = updMgrSvc()->update(this); - info() << "Conditions loaded at initialize" << endmsg; - if (sc.isSuccess()){ - i_dump(); - } - else return sc; - } - return StatusCode::SUCCESS; -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode TestConditionAlg::execute() { - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; - i_dump(); - - return StatusCode::SUCCESS; -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode TestConditionAlg::finalize() { - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; - - updMgrSvc()->unregister(this); - m_conditions.clear(); - m_condPaths.clear(); - - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -//============================================================================= -// Print the conditions -//============================================================================= -void TestConditionAlg::i_dump() -{ - info() << "Requested Conditions:\n"; - GaudiUtils::Map<std::string,Condition*>::iterator it; - for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { - info() << "--- " << it->first << "\n" << *(it->second) << "\n"; - } - info() << endmsg; -} - -//============================================================================= - - -/** Small algorithm that runs a fake event loop during finalize to scan the - * values of the conditions (see bug #74255). - * - * @author Marco CLEMENCIC - * @date 2010-10-25 - */ -class FinalizationEvtLoop: public GaudiAlgorithm { -public: - /// Standard constructor - FinalizationEvtLoop(const std::string& name, ISvcLocator* pSvcLocator): - GaudiAlgorithm(name, pSvcLocator) - { - declareProperty("Conditions", m_condPaths, - "list of paths to conditions in the detector transient store"); - declareProperty("InitialTime", m_initTime = 0, // 1970-01-01 00:00:00UTC - "First event time of the fake event loop"); - declareProperty("FinalTime", m_finalTime = m_initTime + 10000000000LL, // init + 10s - "Final time of the loop"); - declareProperty("Step", m_step = 1000000000LL, // 1s - "Step of the loop"); - } - - virtual ~FinalizationEvtLoop() {} - - virtual StatusCode initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; - - std::vector<std::string>::const_iterator path; - for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ - registerCondition<FinalizationEvtLoop>(*path, m_conditions[*path], NULL); - } - - return StatusCode::SUCCESS; - } - - virtual StatusCode execute () { - return StatusCode::SUCCESS; - } - - virtual StatusCode finalize () { - Gaudi::Time t(m_initTime); - const Gaudi::Time fin(m_finalTime); - const Gaudi::TimeSpan step(m_step); - - SmartIF<IDetDataSvc> dds(detSvc()); - for ( ; t < fin; t += step) { - dds->setEventTime(t); - info() << "Update for event time " << t << endmsg; - if (updMgrSvc()->newEvent().isSuccess()) { - info() << "Requested Conditions:\n"; - GaudiUtils::Map<std::string,Condition*>::iterator it; - for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { - info() << "--- " << it->first << "\n" << *(it->second) << "\n"; - } - info() << endmsg; - } - else { - error() << "Failure updating" << endmsg; - return StatusCode::FAILURE; - } - } - - return StatusCode::SUCCESS; - } - -private: - /// First event time of the fake event loop - Gaudi::Time::ValueType m_initTime; - /// First event time of the fake event loop - Gaudi::Time::ValueType m_finalTime; - /// First event time of the fake event loop - Gaudi::Time::ValueType m_step; - - /// Names of the conditions to print - std::vector<std::string> m_condPaths; - - /// Container of the conditions to print - GaudiUtils::Map<std::string,Condition*> m_conditions; -}; - -/** Test algorithm that triggers the bug #80076 - * https://savannah.cern.ch/bugs/?80076 - */ -class bug_80076: public TestConditionAlg { -public: - /// Constructor. - bug_80076(const std::string& name, ISvcLocator* pSvcLocator): - TestConditionAlg(name, pSvcLocator) {} - - /// Override the initialize to ensure that the conditions are already loaded - /// during the initialize. - StatusCode initialize() { - StatusCode sc = TestConditionAlg::initialize(); - if (sc.isFailure()) return sc; - - std::vector<std::string>::const_iterator path; - for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ - // this ensures that the objects are loaded in the transient store - exist<DataObject>(detSvc(), *path); - } - - return sc; - } -}; - -} - -// Declaration of the Algorithm Factory -DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, TestConditionAlg ) -DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, FinalizationEvtLoop ) -DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, bug_80076 ) -- GitLab From 2686175bca41a0ac3c26ccd3f7d2d49a08e01017 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 10:59:19 +0200 Subject: [PATCH 24/37] Add commented out debug code --- .../src/component/#HpdUkL1DisableTool.h# | 373 ++++++++++++++++++ .../src/component/.#HpdUkL1DisableTool.h | 1 + .../src/component/HpdUkL1DisableTool.cpp | 18 +- .../src/component/HpdUkL1DisableTool.h | 25 +- 4 files changed, 395 insertions(+), 22 deletions(-) create mode 100755 Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# create mode 120000 Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h diff --git a/Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# b/Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# new file mode 100755 index 000000000..2d1bc109a --- /dev/null +++ b/Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# @@ -0,0 +1,373 @@ +// $Id: HpdUkL1DisableTool.h,v 1.17 2009-10-08 15:17:57 ukerzel Exp $ +#ifndef HPDUKL1DISABLETOOL_H +#define HPDUKL1DISABLETOOL_H 1 + +#include <map> +#include <string> +#include <time.h> +#include <memory> + +// boost +#include "boost/regex.hpp" +#include "boost/circular_buffer.hpp" +#include "boost/lexical_cast.hpp" + +// from Gaudi +#include "GaudiKernel/ToolFactory.h" +#include "GaudiKernel/IIncidentListener.h" +#include "GaudiKernel/IIncidentSvc.h" + +// Workaround for https://its.cern.ch/jira/browse/GAUDI-1168 +#include "GaudiKernel/Algorithm.h" + +// DIM +#include "dis.hxx" +#include "dic.hxx" +#include "RTL/rtl.h" + +// CAMERA +#include "Camera/ICameraTool.h" + +// histo +#include "AIDA/IHistogram2D.h" + +// RunChange incident. +#include "DetDesc/RunChangeIncident.h" + +// RichDet +#include "RichDet/DeRichSystem.h" + +// RichKernel +#include "RichKernel/RichHistoToolBase.h" +#include "RichKernel/RichDAQDefinitions.h" +#include "RichKernel/RichSmartIDCnv.h" + +// Local +#include "RichMonitoringTools/IHpdUkL1DisableTool.h" +#include "RichMonitoringTools/RichDimClasses.h" + +// Histogramming +#include "AIDA/IHistogram2D.h" +#include "TH2D.h" +#include "GaudiUtils/Aida2ROOT.h" + +namespace Rich +{ + namespace Mon + { + + /// Instance counter for HpdUkL1DisableTool + static int s_HpdUkL1DisableTool_InstanceCounter; + + /** @class HpdUkL1DisableTool HpdUkL1DisableTool.h + * + * Online tool to disable HPDs + * + * @author Ulrich Kerzel + * @date 2008-06-30 + */ + + class HpdUkL1DisableTool : public Rich::HistoToolBase, + public CheckLHCState, + virtual public IHpdUkL1DisableTool, + virtual public IIncidentListener + { + + private: + + /// HPD Warning level + const int HPDWarningLevel = 1; + /// HPD Error level + const int HPDErrorLevel = 2; + + public: + + /// Standard constructor + HpdUkL1DisableTool( const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~HpdUkL1DisableTool( ); ///< Destructor + + StatusCode initialize (); + StatusCode finalize (); + + private: + + /// Class to monitor the L1 DIM strings + class L1DimString : public DimInfo + { + private: + std::string m_hpdList{""}; + bool m_newState{false}; + private: + void infoHandler() { m_hpdList = std::string(getString()); m_newState = true; } + public : + explicit L1DimString( const std::string & name ) + : DimInfo(name.c_str(),(char*)"") { } + public: + bool newState() const { return m_newState; } + const std::string& hpdList() const { return m_hpdList; } + void setRead( const bool read = true ) { m_newState = !read; } + }; + + /// Wrap two DIM strings (RICH1 and RICH2) into one + class L1DimStringWrap + { + public: + L1DimStringWrap( const std::string & name ) + : m_name ( name ), + m_dimR1 ( "RICH1_L1/" + name ), + m_dimR2 ( "RICH2_L1/" + name ), + m_cache ( "" ) { } + public: + const std::string & name() const { return m_name; } + void setRead( const bool read = true ) + { + m_dimR1.setRead(read); + m_dimR2.setRead(read); + } + const std::string hpdList() const + { + return ( m_dimR1.hpdList().empty() ? m_dimR2.hpdList() : + m_dimR2.hpdList().empty() ? m_dimR1.hpdList() : + m_dimR1.hpdList() + " " + m_dimR2.hpdList() ); + } + bool newState() + { + bool updated = false; + if ( m_dimR1.newState() || m_dimR2.newState() ) + { + const std::string tmp = hpdList(); + if ( tmp != m_cache ) { updated = true; m_cache = tmp; } + else { setRead(); } + } + return updated; + } + void reset() + { + m_cache = ""; + m_dimR1.setRead(false); + m_dimR2.setRead(false); + } + private: + const std::string m_name; + L1DimString m_dimR1, m_dimR2; + mutable std::string m_cache; + }; + + private: + + typedef Rich::Mon::IHpdUkL1DisableTool::HPDData HPDData; + + public: + + /// send disable request + void DisableHPD( const LHCb::RichSmartID &smartID, + const std::string & reason = "" ); + /// send disable request + void DisableHPD( const HPDData& data, + const std::string & reason = "" ); + + /// report HPD as having some issue but not necessarily so severe you'd want to disable it + void ReportHPD ( const LHCb::RichSmartID &smartID, + const std::string & reason = "" ); + /// report HPD as having some issue but not necessarily so severe you'd want to disable it + void ReportHPD ( const HPDData& data, + const std::string & reason = "" ); + + /// Reset all information + void ResetAll(); + + private: + + typedef std::map<HPDData,long int> HPDCountMap; + typedef std::map<std::string,long int> CountReasonMap; + class CountReasonMapAndTime + { + public: + CountReasonMapAndTime() { } + public: + CountReasonMap cMap; + time_t timeLast{0}; + }; + typedef std::map<HPDData,CountReasonMapAndTime> HPDCountReasonMap; + typedef boost::circular_buffer<unsigned long> Buffer; + typedef std::pair< Buffer, CountReasonMap > BufferAndReasons; + typedef std::map< HPDData, BufferAndReasons > HPDBuffer; + + private: + + void PrintReasons (const CountReasonMap & reasons); + void ResetHistograms (); + void RefreshReports (const bool camPrint = true); + void RemoveOldReports (); + void RemoveOldDisables (); + virtual void handle (const Incident &incident); + void DisableAndPublish (); + std::string GetDisableString (const HPDData & data); + std::string GetDisableString (const LHCb::RichSmartID &smartID); + StatusCode Book2DHisto (const Rich::DetectorType rich, + const Rich::Side panel); + + void fillDisabledHisto( const LHCb::RichSmartID& smartID, + const double errorWeight ); + + const LHCb::RichSmartID smartId( const HPDData& data ); + const HPDData hpdData( const LHCb::RichSmartID smartID ); + + /// Get a vector of HPDData objects from a DIM string + const HPDData::Vector hpdDataFromDIM( const std::string & dimS ) const; + + void processUKL1DimString( L1DimStringWrap * dim ); + + /// Is the HPD disabling active ? + inline bool isHpdDisablingActive() const + { + //return true; + return ( m_AlwaysDisable || + lhcbState() == LHCbState::InPhysics || + lhcState() == "PHYSICS" || + ( lhcStateObj() && + lhcState() == "PHYS_ADJUST" && + lhcStateObj()->timeSinceLastUpdate() > 5*60 ) + ); + } + + /// (Re)load the UKL1 Dim strings + void LoadUKL1DIMStrings(); + + /// Reset the Dim strings + void ResetDIMStrings(); + + /// Remove a given HPD from the disabled list + void removeFromDimString( const HPDData& data ); + + /// Returns if an HPD has zero disabling weight in the L1 PVSS projects + inline bool hpdHasZeroWeight( const HPDData& data ) const + { + return ( std::find( m_zeroWeightHPDsV.begin(), + m_zeroWeightHPDsV.end(), + data ) != m_zeroWeightHPDsV.end() ); + } + + /// Checks if a given HPD is already disabled + bool isDisabled( const LHCb::RichSmartID& hpdID ) const; + + /// Checks if an HPD has been software disabled + inline bool isSoftwareDisabled( const HPDData& data ) const + { + return ( std::find( m_softwareDisabledHPDs.begin(), + m_softwareDisabledHPDs.end(), + data ) != m_softwareDisabledHPDs.end() ); + } + + /// Update the HPD DIsable DIM string + inline void updateHPDDisableDIMString( const std::string & dimS ) const + { + if ( m_HPDDisableDimService ) + { + info() << "Updating HPD Disable DIM service with '" << dimS << "'" << endmsg; + m_HPDDisableDimService->updateService( (char*) dimS.c_str() ); + } + } + + private: + + double m_failureRateThreshold; ///< Fraction of times and HPD is allowed to fail. + int m_bufferSize; ///< Size of buffer + HPDCountReasonMap m_HpdErrorReportMap; ///< HPDs reported with errors (via ReportHPD function) + HPDCountReasonMap m_DisabledHpdMap; ///< holds HPDs already disabled + HPDBuffer m_disableCandidates; ///< Internal list of candidate HPDs for disabling + + std::string m_Name; ///< algorithm name (including partition) + + DeRichSystem *m_RichSys = nullptr; ///< Pointer to RICH system detector element + + ICameraTool *m_CamTool = nullptr; ///< CAMERA error reporting tool + + std::string m_DisabledHpdString; ///< The string containing the disabled HPDs, to pass to DIM + std::unique_ptr<DimService> m_HPDDisableDimService; ///< The DIM service for disabled HPDs + + bool m_Plot2DHisto; ///< Turn on/off the filling of the 2D plot + bool m_SendDisableCommands; ///< Switch off sending the disable commands + int m_HistoryTime; ///< How long to keep record of a given incident (in seconds) + bool m_AlwaysDisable; ///< Always enable the HPD disabling + + bool m_ClearListAtNewRun; ///< Clear list of disabled HPDs at the beginning of a new run + + time_t m_TimeLastUpdate{0}; ///< The time of the last camera update + time_t m_TimeLastHPDDisable{0}; ///< The time of the last search for HPDs to disable + time_t m_TimeLastCamSummary{0}; ///< The time of the last summaries sent to camera + + int m_UpdateTimerInterval; ///< Interval at which to update histograms + int m_CamSummaryInterval; ///< Interval to send summaries to camera + int m_DisableCheckInterval; ///< Number of events between checks for new HPDs to disable + int m_DisableCheckHeartBeat; ///< Max time between HPD Disable searches + + /// Number of monitored events + unsigned long long m_nMonitoredEvents{0}; + + /// L1 GT inhibit + std::unique_ptr<L1DimStringWrap> m_l1FELinkDown; + + /// L1 disabled by firmware or monitoring + std::unique_ptr<L1DimStringWrap> m_l1FESquashed; + + /// L1 permanently disabled + std::unique_ptr<L1DimStringWrap> m_l1FEDisabledByRecipe; + + /// L1 'zero weight' HPDs + std::unique_ptr<L1DimStringWrap> m_l1ZeroWeight; + + /// Cache pointers to histograms + AIDA::IHistogram2D * m_hpdHistos[Rich::NRiches][Rich::NPDPanelsPerRICH]; + + /// Set of disabled HPDs (as defined by UKL1 DIM strings) + HPDData::Set m_disabledHPDsV; + + /// Vector of HPDs with zero weights in the L1, so we should not send any warnings for + HPDData::Vector m_zeroWeightHPDsV; + + /// List of software disabled HPDs + HPDData::Set m_softwareDisabledHPDs; + + }; // class + + //============================================================================= + + inline const HpdUkL1DisableTool::HPDData + HpdUkL1DisableTool::hpdData( const LHCb::RichSmartID smartID ) + { + const auto in = m_RichSys->level1InputNum(smartID); + return HPDData( smartID.rich(), + m_RichSys->level1LogicalID(m_RichSys->level1HardwareID(smartID)), + in.ingressID(), + in.l1InputWithinIngress() ); + } + + //============================================================================= + + inline std::string HpdUkL1DisableTool::GetDisableString(const HPDData & data) + { + std::ostringstream hpdIDString; + hpdIDString << " (" + << (int)data.rich() << "," + << data.l1LogID().data() << "," + << data.l1IngressInput().data() << "," + << data.l1Ingress().data() << ")"; + return hpdIDString.str(); + } + + //============================================================================= + + inline std::string + HpdUkL1DisableTool::GetDisableString( const LHCb::RichSmartID &smartID ) + { + return GetDisableString( hpdData(smartID) ); + } + + } //namespace Mon +} // namespace Rich + +#endif // HPDUKL1DISABLETOOL_H diff --git a/Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h b/Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h new file mode 120000 index 000000000..25c699ce9 --- /dev/null +++ b/Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h @@ -0,0 +1 @@ +jonesc@plus15.lbdaq.cern.ch.20878:1465480327 \ No newline at end of file diff --git a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp index b136b6ca4..674418f5c 100755 --- a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp +++ b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp @@ -305,11 +305,7 @@ void HpdUkL1DisableTool::ResetAll() m_softwareDisabledHPDs.clear(); m_zeroWeightHPDsV.clear(); - if ( m_HPDDisableDimService ) - { - info() << "Reset HPD Disable DIM string to empty" << endmsg; - m_HPDDisableDimService->updateService( (char*)"" ); - } + updateHPDDisableDIMString(""); ResetDIMStrings(); @@ -491,11 +487,7 @@ void HpdUkL1DisableTool::DisableAndPublish() m_CamTool->SendAndClearTS( ICameraTool::ERROR , m_Name, mess.str(), ICameraTool::ERROR_PVSS, m_Name, "HPD automatically disabled" ); - if ( m_HPDDisableDimService ) - { - info() << "Update HPD Disable DIM service with '" << m_DisabledHpdString << "'" << endmsg; - m_HPDDisableDimService->updateService( (char*) m_DisabledHpdString.c_str() ); - } + updateHPDDisableDIMString( m_DisabledHpdString ); } else { @@ -1037,11 +1029,7 @@ void HpdUkL1DisableTool::RemoveOldDisables() info() << mess.str() << endmsg; // Update the DIM string - if ( m_HPDDisableDimService ) - { - info() << "Update HPD Disable DIM service with '" << m_DisabledHpdString << "'" << endmsg; - m_HPDDisableDimService->updateService( (char*) m_DisabledHpdString.c_str() ); - } + updateHPDDisableDIMString( m_DisabledHpdString ); } diff --git a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h index 660a274af..426cfac49 100755 --- a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h +++ b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h @@ -224,13 +224,14 @@ namespace Rich /// Is the HPD disabling active ? inline bool isHpdDisablingActive() const { - return ( m_AlwaysDisable || - lhcbState() == LHCbState::InPhysics || - lhcState() == "PHYSICS" || - ( lhcStateObj() && - lhcState() == "PHYS_ADJUST" && - lhcStateObj()->timeSinceLastUpdate() > 5*60 ) - ); + return true; + // return ( m_AlwaysDisable || + // lhcbState() == LHCbState::InPhysics || + // lhcState() == "PHYSICS" || + // ( lhcStateObj() && + // lhcState() == "PHYS_ADJUST" && + // lhcStateObj()->timeSinceLastUpdate() > 5*60 ) + // ); } /// (Re)load the UKL1 Dim strings @@ -261,6 +262,16 @@ namespace Rich data ) != m_softwareDisabledHPDs.end() ); } + /// Update the HPD DIsable DIM string + inline void updateHPDDisableDIMString( const std::string & dimS ) const + { + if ( m_HPDDisableDimService ) + { + info() << "Updating HPD Disable DIM service with '" << dimS << "'" << endmsg; + m_HPDDisableDimService->updateService( (char*) dimS.c_str() ); + } + } + private: double m_failureRateThreshold; ///< Fraction of times and HPD is allowed to fail. -- GitLab From faf098bde7125a578a19b9d38ec8dc1a0e029d5e Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 11:00:25 +0200 Subject: [PATCH 25/37] remove temp files --- .../src/component/#HpdUkL1DisableTool.h# | 373 ------------------ .../src/component/.#HpdUkL1DisableTool.h | 1 - 2 files changed, 374 deletions(-) delete mode 100755 Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# delete mode 120000 Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h diff --git a/Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# b/Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# deleted file mode 100755 index 2d1bc109a..000000000 --- a/Rich/RichMonitoringTools/src/component/#HpdUkL1DisableTool.h# +++ /dev/null @@ -1,373 +0,0 @@ -// $Id: HpdUkL1DisableTool.h,v 1.17 2009-10-08 15:17:57 ukerzel Exp $ -#ifndef HPDUKL1DISABLETOOL_H -#define HPDUKL1DISABLETOOL_H 1 - -#include <map> -#include <string> -#include <time.h> -#include <memory> - -// boost -#include "boost/regex.hpp" -#include "boost/circular_buffer.hpp" -#include "boost/lexical_cast.hpp" - -// from Gaudi -#include "GaudiKernel/ToolFactory.h" -#include "GaudiKernel/IIncidentListener.h" -#include "GaudiKernel/IIncidentSvc.h" - -// Workaround for https://its.cern.ch/jira/browse/GAUDI-1168 -#include "GaudiKernel/Algorithm.h" - -// DIM -#include "dis.hxx" -#include "dic.hxx" -#include "RTL/rtl.h" - -// CAMERA -#include "Camera/ICameraTool.h" - -// histo -#include "AIDA/IHistogram2D.h" - -// RunChange incident. -#include "DetDesc/RunChangeIncident.h" - -// RichDet -#include "RichDet/DeRichSystem.h" - -// RichKernel -#include "RichKernel/RichHistoToolBase.h" -#include "RichKernel/RichDAQDefinitions.h" -#include "RichKernel/RichSmartIDCnv.h" - -// Local -#include "RichMonitoringTools/IHpdUkL1DisableTool.h" -#include "RichMonitoringTools/RichDimClasses.h" - -// Histogramming -#include "AIDA/IHistogram2D.h" -#include "TH2D.h" -#include "GaudiUtils/Aida2ROOT.h" - -namespace Rich -{ - namespace Mon - { - - /// Instance counter for HpdUkL1DisableTool - static int s_HpdUkL1DisableTool_InstanceCounter; - - /** @class HpdUkL1DisableTool HpdUkL1DisableTool.h - * - * Online tool to disable HPDs - * - * @author Ulrich Kerzel - * @date 2008-06-30 - */ - - class HpdUkL1DisableTool : public Rich::HistoToolBase, - public CheckLHCState, - virtual public IHpdUkL1DisableTool, - virtual public IIncidentListener - { - - private: - - /// HPD Warning level - const int HPDWarningLevel = 1; - /// HPD Error level - const int HPDErrorLevel = 2; - - public: - - /// Standard constructor - HpdUkL1DisableTool( const std::string& type, - const std::string& name, - const IInterface* parent); - - virtual ~HpdUkL1DisableTool( ); ///< Destructor - - StatusCode initialize (); - StatusCode finalize (); - - private: - - /// Class to monitor the L1 DIM strings - class L1DimString : public DimInfo - { - private: - std::string m_hpdList{""}; - bool m_newState{false}; - private: - void infoHandler() { m_hpdList = std::string(getString()); m_newState = true; } - public : - explicit L1DimString( const std::string & name ) - : DimInfo(name.c_str(),(char*)"") { } - public: - bool newState() const { return m_newState; } - const std::string& hpdList() const { return m_hpdList; } - void setRead( const bool read = true ) { m_newState = !read; } - }; - - /// Wrap two DIM strings (RICH1 and RICH2) into one - class L1DimStringWrap - { - public: - L1DimStringWrap( const std::string & name ) - : m_name ( name ), - m_dimR1 ( "RICH1_L1/" + name ), - m_dimR2 ( "RICH2_L1/" + name ), - m_cache ( "" ) { } - public: - const std::string & name() const { return m_name; } - void setRead( const bool read = true ) - { - m_dimR1.setRead(read); - m_dimR2.setRead(read); - } - const std::string hpdList() const - { - return ( m_dimR1.hpdList().empty() ? m_dimR2.hpdList() : - m_dimR2.hpdList().empty() ? m_dimR1.hpdList() : - m_dimR1.hpdList() + " " + m_dimR2.hpdList() ); - } - bool newState() - { - bool updated = false; - if ( m_dimR1.newState() || m_dimR2.newState() ) - { - const std::string tmp = hpdList(); - if ( tmp != m_cache ) { updated = true; m_cache = tmp; } - else { setRead(); } - } - return updated; - } - void reset() - { - m_cache = ""; - m_dimR1.setRead(false); - m_dimR2.setRead(false); - } - private: - const std::string m_name; - L1DimString m_dimR1, m_dimR2; - mutable std::string m_cache; - }; - - private: - - typedef Rich::Mon::IHpdUkL1DisableTool::HPDData HPDData; - - public: - - /// send disable request - void DisableHPD( const LHCb::RichSmartID &smartID, - const std::string & reason = "" ); - /// send disable request - void DisableHPD( const HPDData& data, - const std::string & reason = "" ); - - /// report HPD as having some issue but not necessarily so severe you'd want to disable it - void ReportHPD ( const LHCb::RichSmartID &smartID, - const std::string & reason = "" ); - /// report HPD as having some issue but not necessarily so severe you'd want to disable it - void ReportHPD ( const HPDData& data, - const std::string & reason = "" ); - - /// Reset all information - void ResetAll(); - - private: - - typedef std::map<HPDData,long int> HPDCountMap; - typedef std::map<std::string,long int> CountReasonMap; - class CountReasonMapAndTime - { - public: - CountReasonMapAndTime() { } - public: - CountReasonMap cMap; - time_t timeLast{0}; - }; - typedef std::map<HPDData,CountReasonMapAndTime> HPDCountReasonMap; - typedef boost::circular_buffer<unsigned long> Buffer; - typedef std::pair< Buffer, CountReasonMap > BufferAndReasons; - typedef std::map< HPDData, BufferAndReasons > HPDBuffer; - - private: - - void PrintReasons (const CountReasonMap & reasons); - void ResetHistograms (); - void RefreshReports (const bool camPrint = true); - void RemoveOldReports (); - void RemoveOldDisables (); - virtual void handle (const Incident &incident); - void DisableAndPublish (); - std::string GetDisableString (const HPDData & data); - std::string GetDisableString (const LHCb::RichSmartID &smartID); - StatusCode Book2DHisto (const Rich::DetectorType rich, - const Rich::Side panel); - - void fillDisabledHisto( const LHCb::RichSmartID& smartID, - const double errorWeight ); - - const LHCb::RichSmartID smartId( const HPDData& data ); - const HPDData hpdData( const LHCb::RichSmartID smartID ); - - /// Get a vector of HPDData objects from a DIM string - const HPDData::Vector hpdDataFromDIM( const std::string & dimS ) const; - - void processUKL1DimString( L1DimStringWrap * dim ); - - /// Is the HPD disabling active ? - inline bool isHpdDisablingActive() const - { - //return true; - return ( m_AlwaysDisable || - lhcbState() == LHCbState::InPhysics || - lhcState() == "PHYSICS" || - ( lhcStateObj() && - lhcState() == "PHYS_ADJUST" && - lhcStateObj()->timeSinceLastUpdate() > 5*60 ) - ); - } - - /// (Re)load the UKL1 Dim strings - void LoadUKL1DIMStrings(); - - /// Reset the Dim strings - void ResetDIMStrings(); - - /// Remove a given HPD from the disabled list - void removeFromDimString( const HPDData& data ); - - /// Returns if an HPD has zero disabling weight in the L1 PVSS projects - inline bool hpdHasZeroWeight( const HPDData& data ) const - { - return ( std::find( m_zeroWeightHPDsV.begin(), - m_zeroWeightHPDsV.end(), - data ) != m_zeroWeightHPDsV.end() ); - } - - /// Checks if a given HPD is already disabled - bool isDisabled( const LHCb::RichSmartID& hpdID ) const; - - /// Checks if an HPD has been software disabled - inline bool isSoftwareDisabled( const HPDData& data ) const - { - return ( std::find( m_softwareDisabledHPDs.begin(), - m_softwareDisabledHPDs.end(), - data ) != m_softwareDisabledHPDs.end() ); - } - - /// Update the HPD DIsable DIM string - inline void updateHPDDisableDIMString( const std::string & dimS ) const - { - if ( m_HPDDisableDimService ) - { - info() << "Updating HPD Disable DIM service with '" << dimS << "'" << endmsg; - m_HPDDisableDimService->updateService( (char*) dimS.c_str() ); - } - } - - private: - - double m_failureRateThreshold; ///< Fraction of times and HPD is allowed to fail. - int m_bufferSize; ///< Size of buffer - HPDCountReasonMap m_HpdErrorReportMap; ///< HPDs reported with errors (via ReportHPD function) - HPDCountReasonMap m_DisabledHpdMap; ///< holds HPDs already disabled - HPDBuffer m_disableCandidates; ///< Internal list of candidate HPDs for disabling - - std::string m_Name; ///< algorithm name (including partition) - - DeRichSystem *m_RichSys = nullptr; ///< Pointer to RICH system detector element - - ICameraTool *m_CamTool = nullptr; ///< CAMERA error reporting tool - - std::string m_DisabledHpdString; ///< The string containing the disabled HPDs, to pass to DIM - std::unique_ptr<DimService> m_HPDDisableDimService; ///< The DIM service for disabled HPDs - - bool m_Plot2DHisto; ///< Turn on/off the filling of the 2D plot - bool m_SendDisableCommands; ///< Switch off sending the disable commands - int m_HistoryTime; ///< How long to keep record of a given incident (in seconds) - bool m_AlwaysDisable; ///< Always enable the HPD disabling - - bool m_ClearListAtNewRun; ///< Clear list of disabled HPDs at the beginning of a new run - - time_t m_TimeLastUpdate{0}; ///< The time of the last camera update - time_t m_TimeLastHPDDisable{0}; ///< The time of the last search for HPDs to disable - time_t m_TimeLastCamSummary{0}; ///< The time of the last summaries sent to camera - - int m_UpdateTimerInterval; ///< Interval at which to update histograms - int m_CamSummaryInterval; ///< Interval to send summaries to camera - int m_DisableCheckInterval; ///< Number of events between checks for new HPDs to disable - int m_DisableCheckHeartBeat; ///< Max time between HPD Disable searches - - /// Number of monitored events - unsigned long long m_nMonitoredEvents{0}; - - /// L1 GT inhibit - std::unique_ptr<L1DimStringWrap> m_l1FELinkDown; - - /// L1 disabled by firmware or monitoring - std::unique_ptr<L1DimStringWrap> m_l1FESquashed; - - /// L1 permanently disabled - std::unique_ptr<L1DimStringWrap> m_l1FEDisabledByRecipe; - - /// L1 'zero weight' HPDs - std::unique_ptr<L1DimStringWrap> m_l1ZeroWeight; - - /// Cache pointers to histograms - AIDA::IHistogram2D * m_hpdHistos[Rich::NRiches][Rich::NPDPanelsPerRICH]; - - /// Set of disabled HPDs (as defined by UKL1 DIM strings) - HPDData::Set m_disabledHPDsV; - - /// Vector of HPDs with zero weights in the L1, so we should not send any warnings for - HPDData::Vector m_zeroWeightHPDsV; - - /// List of software disabled HPDs - HPDData::Set m_softwareDisabledHPDs; - - }; // class - - //============================================================================= - - inline const HpdUkL1DisableTool::HPDData - HpdUkL1DisableTool::hpdData( const LHCb::RichSmartID smartID ) - { - const auto in = m_RichSys->level1InputNum(smartID); - return HPDData( smartID.rich(), - m_RichSys->level1LogicalID(m_RichSys->level1HardwareID(smartID)), - in.ingressID(), - in.l1InputWithinIngress() ); - } - - //============================================================================= - - inline std::string HpdUkL1DisableTool::GetDisableString(const HPDData & data) - { - std::ostringstream hpdIDString; - hpdIDString << " (" - << (int)data.rich() << "," - << data.l1LogID().data() << "," - << data.l1IngressInput().data() << "," - << data.l1Ingress().data() << ")"; - return hpdIDString.str(); - } - - //============================================================================= - - inline std::string - HpdUkL1DisableTool::GetDisableString( const LHCb::RichSmartID &smartID ) - { - return GetDisableString( hpdData(smartID) ); - } - - } //namespace Mon -} // namespace Rich - -#endif // HPDUKL1DISABLETOOL_H diff --git a/Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h b/Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h deleted file mode 120000 index 25c699ce9..000000000 --- a/Rich/RichMonitoringTools/src/component/.#HpdUkL1DisableTool.h +++ /dev/null @@ -1 +0,0 @@ -jonesc@plus15.lbdaq.cern.ch.20878:1465480327 \ No newline at end of file -- GitLab From 3fa8a96855ee31251fc89bbea6b1152126cbe95c Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 11:03:28 +0200 Subject: [PATCH 26/37] added Det/DetCond from LHCb (LHCb/2016-patches) --- .git-lb-checkout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.git-lb-checkout b/.git-lb-checkout index 5acc14dc1..28809b65c 100644 --- a/.git-lb-checkout +++ b/.git-lb-checkout @@ -1,3 +1,3 @@ [lb-checkout "LHCb.Det/DetCond"] - base = c3b386de48127ddf3f818a41b6c043589b8a1ee7 + base = faf098bde7125a578a19b9d38ec8dc1a0e029d5e imported = 00b37002d748170a320ef743cb30b53f871a898a -- GitLab From 828b7eb423137fab33bc525d2f96aeadf21edaca Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 11:03:52 +0200 Subject: [PATCH 27/37] added Det/DetCond from LHCb (LHCb/2016-patches) --- .git-lb-checkout | 2 +- Det/DetCond/CMakeLists.txt | 37 + Det/DetCond/DetCond/CondDBGenericCnv.h | 126 ++ Det/DetCond/DetCond/ICOOLConfSvc.h | 36 + Det/DetCond/DetCond/ICondDBAccessSvc.h | 108 ++ Det/DetCond/DetCond/ICondDBEditor.h | 75 + Det/DetCond/DetCond/ICondDBReader.h | 110 ++ Det/DetCond/cmt/requirements | 79 + Det/DetCond/doc/release.notes | 1247 ++++++++++++++ Det/DetCond/options/UseOracle.py | 3 + Det/DetCond/python/DetCond/Configuration.py | 788 +++++++++ Det/DetCond/python/DetCond/HistoCond.py | 104 ++ Det/DetCond/python/DetCond/__init__.py | 0 Det/DetCond/src/Lib/CondDBGenericCnv.cpp | 139 ++ Det/DetCond/src/component/COOLConfSvc.cpp | 281 ++++ Det/DetCond/src/component/COOLConfSvc.h | 94 ++ Det/DetCond/src/component/CondDBAccessSvc.cpp | 1492 +++++++++++++++++ Det/DetCond/src/component/CondDBAccessSvc.h | 506 ++++++ Det/DetCond/src/component/CondDBCache.cpp | 444 +++++ Det/DetCond/src/component/CondDBCache.h | 279 +++ Det/DetCond/src/component/CondDBCnvSvc.cpp | 197 +++ Det/DetCond/src/component/CondDBCnvSvc.h | 123 ++ Det/DetCond/src/component/CondDBCommon.cpp | 90 + Det/DetCond/src/component/CondDBCommon.h | 29 + Det/DetCond/src/component/CondDBDQScanner.cpp | 147 ++ Det/DetCond/src/component/CondDBDQScanner.h | 56 + .../src/component/CondDBDispatcherSvc.cpp | 294 ++++ .../src/component/CondDBDispatcherSvc.h | 109 ++ .../src/component/CondDBLayeringSvc.cpp | 288 ++++ Det/DetCond/src/component/CondDBLayeringSvc.h | 103 ++ Det/DetCond/src/component/CondDBLogger.cpp | 250 +++ Det/DetCond/src/component/CondDBLogger.h | 147 ++ Det/DetCond/src/component/CondDBReplayAlg.cpp | 162 ++ Det/DetCond/src/component/CondDBReplayAlg.h | 60 + .../src/component/CondDBSQLiteCopyAccSvc.cpp | 135 ++ .../src/component/CondDBSQLiteCopyAccSvc.h | 55 + .../src/component/CondDBTimeSwitchSvc.cpp | 363 ++++ .../src/component/CondDBTimeSwitchSvc.h | 198 +++ Det/DetCond/src/component/IOVListHelpers.cpp | 23 + Det/DetCond/src/component/IOVListHelpers.h | 10 + Det/DetCond/src/component/LoadDDDB.cpp | 101 ++ Det/DetCond/src/component/LoadDDDB.h | 35 + Det/DetCond/src/component/RelyConverter.cpp | 479 ++++++ Det/DetCond/src/component/RelyConverter.h | 148 ++ Det/DetCond/src/component/RunStampCheck.cpp | 140 ++ Det/DetCond/src/dict/DetCondDict.h | 38 + Det/DetCond/src/dict/DetCondDict.xml | 14 + Det/DetCond/tests/data/DQFLAGS.db | Bin 0 -> 48128 bytes Det/DetCond/tests/data/HBTEST.db | Bin 0 -> 76800 bytes Det/DetCond/tests/data/RSTEST.db | Bin 0 -> 48128 bytes Det/DetCond/tests/data/TESTDB0.db | Bin 0 -> 183296 bytes Det/DetCond/tests/data/TESTDB1.db | Bin 0 -> 79872 bytes Det/DetCond/tests/data/TESTDB2.db | Bin 0 -> 79872 bytes Det/DetCond/tests/data/TESTDB3.db | Bin 0 -> 183296 bytes Det/DetCond/tests/data/genDQFLAGS.py | 39 + Det/DetCond/tests/data/genHBTEST.py | 48 + Det/DetCond/tests/data/genRSTEST.py | 32 + .../tests/qmtest/detcond.qms/bug_80076.qmt | 60 + .../qmtest/detcond.qms/check_db_reading.qmt | 4 + .../detcond.qms/configuration_module.qmt | 4 + .../qmtest/detcond.qms/connection_timeout.qmt | 11 + .../detcond.qms/direct_mapping_altern1.qmt | 22 + .../detcond.qms/direct_mapping_altern2.qmt | 25 + .../detcond.qms/direct_mapping_altern3.qmt | 23 + .../detcond.qms/direct_mapping_base.qmt | 19 + .../detcond.qms/direct_mapping_layers.qmt | 27 + .../detcond.qms/dqscanner.qms/basic.qmt | 63 + .../qmtest/detcond.qms/force_disconnect.qmt | 20 + .../qmtest/detcond.qms/get_iovs.qms/basic.qmt | 4 + .../tests/qmtest/detcond.qms/granularity.qmt | 79 + .../tests/qmtest/detcond.qms/heart_beat.qmt | 105 ++ .../qmtest/detcond.qms/missing_condition.qmt | 35 + .../tests/qmtest/detcond.qms/run_stamp.qmt | 59 + .../tests/qmtest/detcond.qms/time_switch.qmt | 71 + .../qmtest/detcond.qms/update_in_finalize.qmt | 82 + Det/DetCond/tests/scripts/check_db_reading.py | 40 + .../scripts/configuration_module_test.py | 231 +++ .../tests/scripts/connection_timeout.py | 22 + .../tests/scripts/direct_mapping_test.py | 86 + Det/DetCond/tests/scripts/force_disconnect.py | 28 + Det/DetCond/tests/scripts/getIOVs.py | 96 ++ Det/DetCond/tests/src/DQScanTest.cpp | 106 ++ Det/DetCond/tests/src/DQScanTest.h | 51 + Det/DetCond/tests/src/TestConditionAlg.cpp | 287 ++++ 84 files changed, 11522 insertions(+), 1 deletion(-) create mode 100644 Det/DetCond/CMakeLists.txt create mode 100755 Det/DetCond/DetCond/CondDBGenericCnv.h create mode 100755 Det/DetCond/DetCond/ICOOLConfSvc.h create mode 100755 Det/DetCond/DetCond/ICondDBAccessSvc.h create mode 100755 Det/DetCond/DetCond/ICondDBEditor.h create mode 100755 Det/DetCond/DetCond/ICondDBReader.h create mode 100755 Det/DetCond/cmt/requirements create mode 100755 Det/DetCond/doc/release.notes create mode 100644 Det/DetCond/options/UseOracle.py create mode 100755 Det/DetCond/python/DetCond/Configuration.py create mode 100644 Det/DetCond/python/DetCond/HistoCond.py create mode 100644 Det/DetCond/python/DetCond/__init__.py create mode 100755 Det/DetCond/src/Lib/CondDBGenericCnv.cpp create mode 100755 Det/DetCond/src/component/COOLConfSvc.cpp create mode 100755 Det/DetCond/src/component/COOLConfSvc.h create mode 100755 Det/DetCond/src/component/CondDBAccessSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBAccessSvc.h create mode 100755 Det/DetCond/src/component/CondDBCache.cpp create mode 100755 Det/DetCond/src/component/CondDBCache.h create mode 100755 Det/DetCond/src/component/CondDBCnvSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBCnvSvc.h create mode 100755 Det/DetCond/src/component/CondDBCommon.cpp create mode 100755 Det/DetCond/src/component/CondDBCommon.h create mode 100644 Det/DetCond/src/component/CondDBDQScanner.cpp create mode 100644 Det/DetCond/src/component/CondDBDQScanner.h create mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.h create mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.h create mode 100755 Det/DetCond/src/component/CondDBLogger.cpp create mode 100755 Det/DetCond/src/component/CondDBLogger.h create mode 100755 Det/DetCond/src/component/CondDBReplayAlg.cpp create mode 100755 Det/DetCond/src/component/CondDBReplayAlg.h create mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h create mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp create mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.h create mode 100644 Det/DetCond/src/component/IOVListHelpers.cpp create mode 100644 Det/DetCond/src/component/IOVListHelpers.h create mode 100755 Det/DetCond/src/component/LoadDDDB.cpp create mode 100755 Det/DetCond/src/component/LoadDDDB.h create mode 100755 Det/DetCond/src/component/RelyConverter.cpp create mode 100755 Det/DetCond/src/component/RelyConverter.h create mode 100644 Det/DetCond/src/component/RunStampCheck.cpp create mode 100755 Det/DetCond/src/dict/DetCondDict.h create mode 100755 Det/DetCond/src/dict/DetCondDict.xml create mode 100644 Det/DetCond/tests/data/DQFLAGS.db create mode 100644 Det/DetCond/tests/data/HBTEST.db create mode 100644 Det/DetCond/tests/data/RSTEST.db create mode 100755 Det/DetCond/tests/data/TESTDB0.db create mode 100755 Det/DetCond/tests/data/TESTDB1.db create mode 100755 Det/DetCond/tests/data/TESTDB2.db create mode 100755 Det/DetCond/tests/data/TESTDB3.db create mode 100644 Det/DetCond/tests/data/genDQFLAGS.py create mode 100644 Det/DetCond/tests/data/genHBTEST.py create mode 100755 Det/DetCond/tests/data/genRSTEST.py create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt create mode 100644 Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt create mode 100755 Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt create mode 100755 Det/DetCond/tests/scripts/check_db_reading.py create mode 100755 Det/DetCond/tests/scripts/configuration_module_test.py create mode 100644 Det/DetCond/tests/scripts/connection_timeout.py create mode 100755 Det/DetCond/tests/scripts/direct_mapping_test.py create mode 100644 Det/DetCond/tests/scripts/force_disconnect.py create mode 100755 Det/DetCond/tests/scripts/getIOVs.py create mode 100644 Det/DetCond/tests/src/DQScanTest.cpp create mode 100644 Det/DetCond/tests/src/DQScanTest.h create mode 100755 Det/DetCond/tests/src/TestConditionAlg.cpp diff --git a/.git-lb-checkout b/.git-lb-checkout index 28809b65c..956923af6 100644 --- a/.git-lb-checkout +++ b/.git-lb-checkout @@ -1,3 +1,3 @@ [lb-checkout "LHCb.Det/DetCond"] - base = faf098bde7125a578a19b9d38ec8dc1a0e029d5e + base = ed48beeb1a3925e97bfde21fd887f861b032263e imported = 00b37002d748170a320ef743cb30b53f871a898a diff --git a/Det/DetCond/CMakeLists.txt b/Det/DetCond/CMakeLists.txt new file mode 100644 index 000000000..4f314aebe --- /dev/null +++ b/Det/DetCond/CMakeLists.txt @@ -0,0 +1,37 @@ +################################################################################ +# Package: DetCond +################################################################################ +gaudi_subdir(DetCond v12r47) + +gaudi_depends_on_subdirs(Det/DetDesc + GaudiAlg + GaudiKernel + Kernel/LHCbKernel) + +find_package(Boost COMPONENTS system thread filesystem) +find_package(COOL COMPONENTS CoolKernel CoolApplication) +find_package(CORAL COMPONENTS CoralBase CoralKernel RelationalAccess) + +gaudi_add_library(DetCondLib + src/Lib/*.cpp + PUBLIC_HEADERS DetCond + INCLUDE_DIRS Boost COOL CORAL + LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel) + +gaudi_add_module(DetCond + src/component/*.cpp + tests/src/*.cpp + INCLUDE_DIRS Boost COOL CORAL + LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib) + +gaudi_add_dictionary(DetCond + src/dict/DetCondDict.h + src/dict/DetCondDict.xml + INCLUDE_DIRS Boost COOL CORAL + LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib + OPTIONS "-U__MINGW32__") + +gaudi_install_python_modules() + + +gaudi_add_test(QMTest QMTEST) diff --git a/Det/DetCond/DetCond/CondDBGenericCnv.h b/Det/DetCond/DetCond/CondDBGenericCnv.h new file mode 100755 index 000000000..08f112058 --- /dev/null +++ b/Det/DetCond/DetCond/CondDBGenericCnv.h @@ -0,0 +1,126 @@ +#ifndef DETCOND_CONDDBGENERICCNV_H +#define DETCOND_CONDDBGENERICCNV_H 1 + +// Include files +#include <string> +#include <functional> + +#include "GaudiKernel/Converter.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +#include "DetCond/ICondDBReader.h" + +#include "CoolKernel/types.h" + +// Forward and external declarations +class ISvcLocator; +class IDetDataSvc; +class DataObject; + +template <class TYPE> class CnvFactory; + +/** @class CondDBGenericCnv CondDBGenericCnv.h DetCond/CondDBGenericCnv.h + * + * Generic converter for the CondDBCnvSvc. This generic converter + * provides common functions to access the CondDB in order to make it + * easier to write specific converters. + * + * @author Marco CLEMENCIC + * @date December 2004 + */ +class CondDBGenericCnv: public Converter { +public: + /** + * Initializes the converter. + * Here the pointers to common services are taken: + * <ul> + * <li> CondDBCnvSvc + * <li> DetectorDataSvc + * </ul> + * @return status depending on the completion of the call + */ + virtual StatusCode initialize(); + + /** + * Finalizes the converter. + * It releases the pointers to the taken services. + * @return status depending on the completion of the call + */ + virtual StatusCode finalize(); + + /** + * Accessor to the StorageType value + * @return the storage type for this object + */ + static long storageType() { + return CONDDB_StorageType; + } + + /** + * Accessor to the StorageType value + * @return the storage type for this object + */ + virtual long repSvcType() const { + return CONDDB_StorageType; + } + +protected: + + /// Standard constructor + CondDBGenericCnv(ISvcLocator* svc,const CLID& clid); + + virtual ~CondDBGenericCnv( ); ///< Destructor + + /** + * Ask to the DetectorDataSvc the curren event time. + * @return StatusCode::SUCCESS if the event time was defined. + */ + StatusCode eventTime(Gaudi::Time &time) const; + + /** + * Set the validity of the DataObject if it inherits from IValidity. + */ + void setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject); + + /// Pointer to the DetectorDataService. + SmartIF<IDetDataSvc> m_detDataSvc; + /// Pointer to the ICondDBReader interface; + SmartIF<ICondDBReader> m_condDBReader; + + /** + * Get an object from the Conditions DB. It tries all the CondDBReaders + * known by CondDBCnvSvc before returing a failure code. + * @param[in] path the path inside the CondDB + * @param[in] channel CondDB channel id + * @param[out] obj shared pointer to the COOL object + * @param[out] descr folder description string (used to know the storage type by RelyConverter) + * @param[out] since start of the IOV + * @param[out] until end of the IOV + * The IOV is inside the object itself as two cool::ValidityKey, the since and until are + * used to avoid the conversion outside this method.<BR> + * If the path point to a FolderSet, channel is ignored and the boost::shared_ptr obj is + * set to NULL. + */ + StatusCode getObject(const std::string &path, const cool::ChannelId &channel, + ICondDBReader::DataPtr &obj, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until); + + /// Method kept for backward compatibility + inline StatusCode getObject(const std::string &path, + ICondDBReader::DataPtr &obj, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until) + { + return getObject(path,0,obj,descr,since,until); + } + + /// Find the children nodes of a given FolderSet path. + /// When using multiple databases, only the first one which contains + /// this folderset is used, so it must have at least dummy entries for each sub-node + /// (to be changed in the future). + StatusCode getChildNodes(const std::string &path,std::vector<std::string> &node_names); + +private: + +}; +#endif // DETCOND_CONDDBGENERICCNV_H diff --git a/Det/DetCond/DetCond/ICOOLConfSvc.h b/Det/DetCond/DetCond/ICOOLConfSvc.h new file mode 100755 index 000000000..5636805cf --- /dev/null +++ b/Det/DetCond/DetCond/ICOOLConfSvc.h @@ -0,0 +1,36 @@ +#ifndef DETCOND_ICOOLCONFSVC_H +#define DETCOND_ICOOLCONFSVC_H 1 + +// Include files +#include <GaudiKernel/IInterface.h> + +// Forward declarations +namespace coral { + class IConnectionService; +} +namespace cool { + class IDatabaseSvc; +} + +/** @class ICOOLConfSvc ICOOLConfSvc.h DetCond/ICOOLConfSvc.h + * + * Class used as interface to instantiate a COOL application and configure it + * (and CORAL). + * + * @author Marco CLEMENCIC + * @date 2007-12-07 + */ +class ICOOLConfSvc : virtual public IInterface { +public: + /// InterfaceID + DeclareInterfaceID(ICOOLConfSvc, 3, 0); + + /// Access to the CORAL connection service used by COOL (if needed). + virtual coral::IConnectionService& connectionSvc() = 0; + + /// Get the COOL Database service (used to connect to the databases). + virtual cool::IDatabaseSvc& databaseSvc() = 0; + +}; + +#endif // DETCOND_ICOOLCONFSVC_H diff --git a/Det/DetCond/DetCond/ICondDBAccessSvc.h b/Det/DetCond/DetCond/ICondDBAccessSvc.h new file mode 100755 index 000000000..85ae8d611 --- /dev/null +++ b/Det/DetCond/DetCond/ICondDBAccessSvc.h @@ -0,0 +1,108 @@ +#ifndef DETCOND_ICONDDBACCESSSVC_H +#define DETCOND_ICONDDBACCESSSVC_H 1 + +// Include files +// from STL +#include <string> +#include <vector> +#include <set> +#include <map> + +// from Gaudi +#include <GaudiKernel/IInterface.h> + +// from COOL +#include "CoolKernel/types.h" +#include "CoolKernel/ChannelId.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/ValidityKey.h" + +// Forward declarations +namespace Gaudi { + class Time; +} +namespace cool { + class IRecord; + class IRecordSpecification; +} + +/** @class ICondDBAccessSvc ICondDBAccessSvc.h DetCond/ICondDBAccessSvc.h + * + * Class used as interface to LCG COOL library API. It should expose as less as + * possible COOL internal details. + * + * CondDBAccessSvc can be operated with only an in-memory CondDB, setting both the options NoBD and useCache to true. The memory + * database can be populated using cacheAddFolder and cacheAddObject (or their XML counter parts). The CondDB folders of the + * memory db are equivalent to COOL single-version folders (see COOL documentation for details). + * + * @author Marco CLEMENCIC + * @date 2005-01-11 + */ +class ICondDBAccessSvc : virtual public IInterface { +public: + /// InterfaceID + DeclareInterfaceID(ICondDBAccessSvc, 2, 0); + + /// Used to obtain direct access to the database. + virtual cool::IDatabasePtr& database() = 0; + + /// Convert from Gaudi::Time class to cool::ValidityKey. + virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const = 0; + + /// Convert from cool::ValidityKey to Gaudi::Time class. + virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const = 0; + + /// Return the currently set TAG to use. + virtual const std::string &tag() const = 0; + + /// Set the TAG to use. + virtual StatusCode setTag(const std::string &_tag) = 0; + + /// Return the connection string used to connect to the database. + virtual const std::string &connectionString() const = 0; + + /// Add a folder to the cache (bypass the DB) + virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec) = 0; + + /// Add a folder-set to the cache (bypass the DB) + virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr) = 0; + + /// Add an XML folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path) = 0; + + /// Add an XML folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) = 0; + + /// Add an object to the cache (bypass the DB) + virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const cool::IRecord &payload, cool::ChannelId channel = 0) = 0; + + /// Deprecated: use ICondDBAccessSvc::cacheAddXMLData instead + inline StatusCode cacheAddXMLObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string &data, cool::ChannelId channel = 0) + { + return cacheAddXMLData(path, since, until, data, channel); + } + + + /// Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string &data, cool::ChannelId channel = 0) = 0; + + /// Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::map<std::string,std::string> &data, cool::ChannelId channel = 0) = 0; + + /// Clear the cache + virtual void clearCache() = 0; + + /// Dump the cache (debug) + virtual void dumpCache() const = 0; + +protected: + +private: + +}; +#endif // DETCOND_ICONDDBACCESSSVC_H diff --git a/Det/DetCond/DetCond/ICondDBEditor.h b/Det/DetCond/DetCond/ICondDBEditor.h new file mode 100755 index 000000000..0edce1b8b --- /dev/null +++ b/Det/DetCond/DetCond/ICondDBEditor.h @@ -0,0 +1,75 @@ +#ifndef DETCOND_ICONDDBEDITOR_H +#define DETCOND_ICONDDBEDITOR_H 1 + +// Include files +// from STL +#include <string> +#include <map> +#include <set> + +// from Gaudi +#include "GaudiKernel/IInterface.h" + +// from COOL +#include "CoolKernel/types.h" +#include "CoolKernel/ChannelId.h" + +/** @class ICondDBEditor ICondDBEditor.h DetCond/ICondDBEditor.h + * + * + * @author Marco CLEMENCIC + * @date 2006-07-10 + */ +class ICondDBEditor : virtual public IInterface { +public: + /// InterfaceID + DeclareInterfaceID(ICondDBEditor, 2, 0); + + /// Possible recognized node types. + enum StorageType { FOLDERSET, XML, Native }; + /// Known types of leaf nodes (aka Folders). + enum VersionMode { SINGLE, MULTI }; + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + StorageType storage = XML, + VersionMode vers = MULTI) const = 0; + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + const std::set<std::string> &fields, + StorageType storage = XML, + VersionMode vers = MULTI) const = 0; + + /// Deprecated: use ICondDBEditor::storeXMLData instead. + inline StatusCode storeXMLString(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const + { + return storeXMLData(path, data, since, until, channel); + } + + /// Utility function that simplifies the storage of an XML string. + virtual StatusCode storeXMLData(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; + + /// Utility function that simplifies the storage of a set of XML strings. + virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; + + /// Tag the given leaf node with the given tag-name. + virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, + const std::string &description = "") = 0; + + /// Tag the given middle node with the given tag-name, recursively tagging the head + /// of child nodes with automatically generated tag-names. + virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, + const std::string &description = "") = 0; + +protected: + +private: + +}; +#endif // DETCOND_ICONDDBEDITOR_H diff --git a/Det/DetCond/DetCond/ICondDBReader.h b/Det/DetCond/DetCond/ICondDBReader.h new file mode 100755 index 000000000..0131d2e01 --- /dev/null +++ b/Det/DetCond/DetCond/ICondDBReader.h @@ -0,0 +1,110 @@ +#ifndef DETCOND_ICONDDBREADER_H +#define DETCOND_ICONDDBREADER_H 1 + +// Include files +// from STL +#include <string> + +// from Gaudi +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/Time.h" + +// from LHCb +#include "Kernel/ICondDBInfo.h" + +// from COOL +#include "CoolKernel/types.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/ChannelId.h" + +// Forward declarations +namespace cool { + class IRecord; +} + +/** @class ICondDBReader ICondDBReader.h DetCond/ICondDBReader.h + * + * Interface to retrieve data from the conditions database. + * + * @author Marco Clemencic + * @date 2006-07-10 + */ +class ICondDBReader : virtual public ICondDBInfo { +public: + /// InterfaceID + DeclareInterfaceID(ICondDBReader, 2, 1); + + /// virtual destructor + virtual ~ICondDBReader() {} + +#ifdef COOL_HAS_CPP11 + typedef std::shared_ptr<const cool::IRecord> DataPtr; +#else + typedef boost::shared_ptr<const cool::IRecord> DataPtr; +#endif + + /// Helper class to easily manage an interval of validity as a pair of Gaudi::Time + /// instances. + struct IOV { + /// Constructor + IOV(Gaudi::Time _since = Gaudi::Time::epoch(), + Gaudi::Time _until = Gaudi::Time::max()): + since(_since), until(_until) + {} + /// Boundaries of the interval. + Gaudi::Time since, until; + /// Define a simple order between two IOV instances. + inline bool operator<(const IOV& rhs) const { + return since < rhs.since; + } + }; + + /// List of IOV instances. + typedef std::vector<IOV> IOVList; + + /// Retrieve data from the condition database. + /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0) = 0; + + /// Retrieve data from the condition database. + /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. + /// (Version with alphanumeric channel id) + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) = 0; + + /// @{ + /// Return the list of occupied IOVs in the given path and channel, for the given IOV. + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0) = 0; + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel) = 0; + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names) = 0; + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) = 0; + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path) = 0; + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path) = 0; + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path) = 0; + + /// Disconnect from the database. + virtual void disconnect() = 0; + +protected: + +private: + +}; + +#endif // DETCOND_ICONDDBREADER_H diff --git a/Det/DetCond/cmt/requirements b/Det/DetCond/cmt/requirements new file mode 100755 index 000000000..2770d40a8 --- /dev/null +++ b/Det/DetCond/cmt/requirements @@ -0,0 +1,79 @@ +# ==================================================================== +package DetCond +version v12r47 + +# =========== structure =================================================== +branches DetCond doc cmt src + +# =========== dependencies ================================================ +use GaudiKernel v* +use GaudiAlg v* +use COOL v* LCG_Interfaces +use CORAL v* LCG_Interfaces +use Boost v* LCG_Interfaces +use DetDesc v* Det + +# This one is for the interface ICondDBInfo and IDQScanner +use LHCbKernel v* Kernel + +macro_append Boost_linkopts " $(Boost_linkopts_system) " + + +# =========== own includes ================================================ +apply_pattern install_more_includes more=DetCond + +#===================================================================== +# Needed to resolve external symbols +apply_tag NEEDS_COOL_FACTORY +apply_tag NEEDS_CORAL_RELATIONAL_ACCESS +# Work-around for a problem in COOL/CORAL requirements files (after fix to bug #41579) +macro CORAL_linkopts ' $(CORAL_libs) $(CORAL_relacc_libs) ' + +# =============== LCG Dictionary =========================================== +apply_pattern reflex_dictionary \ + dictionary=DetCond \ + headerfiles=$(DETCONDROOT)/src/dict/DetCondDict.h \ + selectionfile=$(DETCONDROOT)/src/dict/DetCondDict.xml \ + options="-U__MINGW32__" +# Disable some compiler warnings in the automatically generated dict code +macro_append DetCondDict_cppflags "" \ + target-icc " -wd2259" + +# =========== constituents ================================================= +library DetCondLib Lib/*.cpp +library DetCond component/*.cpp ../tests/src/*.cpp + +# =========== standard patterns (the order is essential!) ====================== +apply_pattern component_library library=DetCond +apply_pattern linker_library library=DetCondLib + +private +# DetCond Configurable uses the generated configurables +macro_append DetCondGenConfUser_dependencies DetCondConfDbMerge +# Have to look in local DetCondConf.py, install_python has to come later +path_prepend PYTHONPATH ${DETCONDROOT}/genConf +end_private +apply_pattern install_python_modules + +# ==================================================================== +private + +macro_append DetCond_use_linkopts " $(Boost_linkopts_thread) $(Boost_linkopts_filesystem_mt) $(Boost_linkopts_date_time) " + +apply_pattern QMTest +# ===================================== +# Packages needed for tests +macro DetCond_use_CondDBUI "" QMTest "CondDBUI v* Tools" +use $(DetCond_use_CondDBUI) + +macro DetCond_use_DDDB "" QMTest "DDDB v* Det" +use $(DetCond_use_DDDB) + +macro DetCond_use_DetDescSvc "" QMTest "DetDescSvc v* Det" +use $(DetCond_use_DetDescSvc) + +macro DetCond_use_DetDescCnv "" QMTest "DetDescCnv v* Det" +use $(DetCond_use_DetDescCnv) +# ===================================== + +end_private diff --git a/Det/DetCond/doc/release.notes b/Det/DetCond/doc/release.notes new file mode 100755 index 000000000..71d560ebc --- /dev/null +++ b/Det/DetCond/doc/release.notes @@ -0,0 +1,1247 @@ +!----------------------------------------------------------------------------- +! Package : Det/DetCond +! Responsible : Marco Clemencic +! Purpose : Interface between LHCb and LGC/COOL project +!----------------------------------------------------------------------------- + +! 2016-03-31 - Roel Aaij + - Fix CondDB configuration. The online snapshots were configured even if + UseDBSnapshot was set to True. + +!========================= DetCond v12r47 2016-03-18 ========================= +! 2016-03-18 - Roel Aaij + - Remove configuration of environment variables meant to setup access to the + LHCb online oracle instance. This should be done online as part of the + environment. + +!========================= DetCond v12r46 2016-01-27 ========================= +! 2016-01-06 - Gerhard Raven + - prefer SmartIF over raw pointer to interface + +! 2015-12-17 - Christopher Burr + - Prevent CondDBCache from logging " FOUND" as a warning + +!========================= DetCond v12r45 2015-11-23 ========================= +! 2015-11-02 - Gerhard Raven + - pass sink arguments by value, and std::move them + - replace deprecated std::auto_ptr with std::unique_ptr + - prefer range-based for loops + - prefer emplace_back over push_back + +!========================= DetCond v12r44 2015-10-12 ========================= +! 2015-09-25 - Liang Sun + - Remove references to SQLDDDB*.py option files + - If UseOracle & Online options are both set to True, the Oracle ONLINE db is used, instead of sqlite db files + +! 2015-08-03 - Gerhard Raven + - remove #include of obsolete Gaudi headers + +!========================= DetCond v12r43 2015-07-20 ========================= +! 2015-06-30 - Marco Clemencic + - Fixed LHCBPS-1425: ensure that the "InitialTime" is stable. + +! 2015-06-25 - Eduardo Rodrigues + - Undid the reference update from yesterday as the difference is in fact + *not* expected nor understood, see https://its.cern.ch/jira/browse/LHCBPS-1425. + +! 2015-06-24 - Eduardo Rodrigues + - Updated expected reference block for test force_disconnect. + +!========================= DetCond v12r42 2015-06-17 ========================= +! 2015-06-16 - Marco Clemencic + - LHCBPS-1421: Modified RunStampCheck to instantiate EventClockSvc. + To ensure that it does get a "current event time", RunStampCheck triggers + the instantiation of EventClockSvc, so that it is not needed to explicitly + do it in the configuration. + +! 2015-06-16 - Marco Clemencic + - LHCBPS-1421: Updated CondDB configurable to enable/disable RunStampCheck + The RunStampCheck is enabled by default for "Offline" (i.e. not Online + nor Simulation). + +! 2015-06-11 - Marco Clemencic + - LHCBPS-1421: added a first implementation of RunStampCheck + The optional service RunStampCheck can be instantiated (via + ApplicationManager::ExtSvc) to check if a special "run stamp" + condition exist for the current run. + +! 2015-06-05 - Liang Sun + - Set LoadCALIBDB default value to HLT1 for Simulation option + +! 2015-06-05 - Liang Sun + - Set LoadCALIBDB default value to HLT1 for Online and Upgrade options + - Change in detcond.configuration_module to avoid checking layered ONLINE partition + +! 2015-06-04 - Liang Sun + - Finalized support for CALIBOFF by loading the partition as an additional layer only above every ONLINE snapshot no earlier than 2015 + - Bug fix for mistakenly loading CALIBOFF for upgrade CondDB + +!========================= DetCond v12r41 2015-04-20 ========================= +! 2015-04-16 - Liang Sun + - Further support for loading CALIBOFF.db file as an additional layer above all partitions, for testing purpose only + +! 2015-03-18 - Liang Sun + - Fix the nightlies after the last commit. The XML extensions of the condition files within TESTDB?.db are now removed. + +! 2015-03-12 - Marco Clemencic + - Changed the policy of CondDB::generateXMLCatalog to exclude folders with + names ending with ".xml" from the generated catalog. + This is required to allow mixed content in the Online CondDB partition for + the split Hlt, where the files with ".xml" are not meant to be automatically + mapped. + +!========================= DetCond v12r40p1 2015-01-14 ========================= +! 2015-01-07 - Marco Cattaneo + - Fix gcc49 unused function warning in DQScanTest.cpp + +!========================= DetCond v12r40 2014-12-11 ========================= +! 2014-12-03 - Liang Sun + - In Configuration.py: Fixing the cases without valid DQFLAGS tags + +! 2014-12-02 - Liang Sun + - In Configuration.py: Adding option LatestGlobalTagByDataTypes to allow for multiple datatypes. + - In Configuration.py: Inclusion of DQFLAGS to assign the most recent tag for a given datatype + +!========================= DetCond v12r39 2014-10-14 ========================= +! 2014-10-07 - Gerhard Raven + - DetCond configurable: remove explicit paritition name and defer this to the + keys (i.e. filename) in the RunChangeHandlerCondiions map. + +!========================= DetCond v12r38 2014-09-30 ========================= +! 2014-09-30 - Gerhard Raven + - DetCond configurable: combine the RunChangeHandlerConditions and XMLFilename + properties into a single dictioary of filename -> list of conditions so that + the RunChangeHandler can be configured to use multiple <subsystem>_<runnr>.xml + files. + - avoid a spurios warning about ONLINE tag + +!========================= DetCond v12r37 2014-09-08 ========================= +! 2014-09-02 - Liang Sun + - In Configuration.py: Keep the lines related to the import of SQLDDDB-Oracle.py for the UseOracle option, in order not to fail the nightlies + +! 2014-09-01 - Liang Sun + - Changes in Configuration.py: + - Removal of the support for Oracle by commenting out the lines related to the option "UseOracle" + - Added a layer of CALIBOFF above LHCBCOND when LoadCALIBDB option is OFFLINE + +! 2014-07-24 - Liang Sun + - Added qmtest module "detcond.check_db_reading" to check the db reading functionality in Tools/CondDBUI + + +!========================= DetCond v12r36 2014-05-12 ========================= +! 2014-05-05 - Gerhard Raven + - do not truncate partitionname + +!========================= DetCond v12r35 2014-04-29 ========================= + +!========================= DetCond v12r34 2014-04-29 ========================= + +! 2014-04-28 - Gerhard Raven + - make the conditions which the RunChangeHanderSvc updates a property + - make the (last part of the) filename used by the RunChangeHandlerSvc a property + +! 2014-03-26 - Liang Sun + - CondDB preparation for 2015 in Configuration.py: new CondDB partitions 'CALIB' + and 'CALIBOFF' as additional layers above 'ONLINE' partition. New options for + 'LoadCALIBDB' to enable/disable loading the new layers. The default option is + to add the new layers from $SQLITEDBPATH/CALIB-[YEAR].db and $SQLITEDBPATH/CALIBOFF.db + files automatically if exist. + +!========================= DetCond v12r33 2014-02-17 ========================= +! 2013-12-05 - Marco Clemencic + - Fixed the use of boost::shared_ptr according to the macro COOL_HAS_CPP11 (the + one used in COOL headers). + +! 2013-12-05 - Marco Clemencic + - Do not explicitly use boost::shared_ptr. + See https://sft.its.cern.ch/jira/browse/ROOT-5806 + +! 2013-07-18 - Marco Clemencic + - Minor change. + +!========================= DetCond v12r32 2013-07-17 ========================= +! 2013-06-12 - Marco Cattaneo + - Add virtual destructor to ICondDBReader interface class. Fixes gcc48 warning + virtual-move-assign, see explanation in https://sft.its.cern.ch/jira/CFHEP-87 + +!========================= DetCond v12r31 2013-06-03 ========================= +! 2013-05-07 - Marco Clemencic + - Moved the class CondDBCompression to Tools/CondDBEntityResolver, including + dictionary and tests. + +! 2013-05-02 - Liang Sun + - Removed one defunct line to please Coverity. Added in GaudiException() to handle LZMA errors + +!========================= DetCond v12r30 2013-04-29 ========================= +! 2013-04-26 - Liang Sun + - Removed all references to BZip2. We still need 32Bit machines + +! 2013-04-26 - Marco Clemencic + - Removed the temporary hack used for C++11 (it was needed only because Boost + was not yet built with C++11 enabled). + +! 2013-04-25 - Marco Clemencic + - Fixed an issue with the previous change (the environment variable expansion + was prevented in too many places). + +! 2013-04-24 - Illya Shapoval + - A bug fix: an expansion of the SQLITEUPGRADEDBPATH env. variable is prevented. + +! 2013-04-18 - Liang Sun + - Two redundant variables removed to quell the warning messages. + +! 2013-04-17 - Liang Sun + - Added the compression method of LZMA from ROOT with the assigned method number at 0, the method number for BZip2 now changed to 1. + +! 2013-04-02 - Marco Cattaneo + - Fix UNINIT_CTOR defects + +! 2013-03-21 - Liang Sun + - Minor fix on a few potential memory leaks + - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45083&defectInstanceId=156348385&fileInstanceId=111518946 + - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45084&defectInstanceId=156348386&fileInstanceId=111518946 + +! 2013-03-18 - Vanya Belyaev + + - comment usage of python module from removed package HistoStrings + +! 2013-03-12 - Marco Clemencic + - Added hints to Coverity to fix a few flas positives: + - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45071&defectInstanceId=156278261&fileInstanceId=111423297 + - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45070&defectInstanceId=156277446&fileInstanceId=111423297 + - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45069&defectInstanceId=156277445&fileInstanceId=111423297 + +! 2013-03-12 - Liang Sun + - Minor fix on coverity defects (0&i++) + +! 2013-03-11 - Liang Sun + - Set up prototype to allow multiple compression methods, with an additional byte identifying the method prepended to the compressed string + +! 2013-03-08 - Marco Clemencic + - Fixed compilation on 32 bits with a hack (the 32 bits dev version of bz2 + cannot be installed on lxbuild because of missing templates). + +! 2013-02-27 - Liang Sun + - Fix the type conversions to quell the -pedantic warnings + +! 2013-02-23 - Marco Clemencic + - Forgot to add -lbz2 after removing the 'use' statement. + +! 2013-02-22 - Marco Clemencic + - Added use of BZip2 in CMakeLists.txt and removed the use of LCG_Interfaces/bz2lib + from the requirements (we must pick up the system version because the one in + lcg/externals is obsolete and deprecated). + +! 2013-02-21 - Liang Sun + - Added functionalities of compression and decompression on CondDB with new class CondDBCompression + +!========================= DetCond v12r29 2013-02-04 ========================= +! 2012-12-20 - Marco Clemencic + - Stop the TimeOutChecker thread when explicitly disconnected. The thread is + restarted automatically when we reconnect. + +!========================= DetCond v12r28 2012-11-26 ========================= +! 2012-11-21 - Marco Clemencic + - Modified the ICondDBReader interface to allow explicit disconnection from + databases (useful after a fork). + +! 2012-11-15 - Marco Clemencic + - Added CMake configuration file. + +!========================= DetCond v12r27 2012-09-28 ========================= +! 2012-09-26 - Marco Clemencic + - Removed comments from __init__.py + +! 2012-09-21 - Marco Clemencic + - Temporary hack to compile with -std=c++11 (-std=c++0x). + +! 2012-08-09 - Marco Clemencic + - Workaround for bug #96673. + +! 2012-08-08 - Marco Clemencic + - Added python/DetCond/__init__.py. + +!========================= DetCond v12r26 2012-07-24 ========================= +! 2012-07-10 - Patrick Koppenburg + - Bug: https://savannah.cern.ch/bugs/?94454 + . Allow _configureDBSnapshot to work without UseOracle = True statement + . Remove MagneticFieldSvc().UseSetCurrent = True that should be set + in the application's configuration. + +!========================= DetCond v12r25 2012-06-25 ========================= +! 2012-06-12 - Illya Shapoval + - Configuration.py: + + new property is added. "CondDB().Upgrade = True" will switch the CondDB + machinery to talk to the Upgrade database. + + three new properties are added: + CondDB().LatestGlobalTagByDataType = "DataType0" + CondDB().LatestLocalTagsbyDataType = ["DataType1","DataType2",...] + CondDB().AllLocalTagsbyDataType = ["DataType1","DataType2",...] + Setting this will launch the SAX machinery to fetch and set the latest + global tags, latest locals tags, and all local tags, respectively, marked + with requested DataType(s). This is an extension to the previous configuration + machinery (CondDB().UseLatestTags = ["DataType"]) which is still supported. + +!========================= DetCond v12r24 2012-05-02 ========================= +! 2012-04-26 - Patrick Koppenburg + - Configuration: add properties allowing to configure from online_RunNumber.xml + snapshots. For Online Brunel. This is stolen from Moore. + +!========================= DetCond v12r23 2012-02-01 ========================= +! 2012-02-01 - Marco Clemencic + - Modified DQScanTest to work around a small problem in the configuration on + 32 bits builds. + +! 2012-01-31 - Marco Clemencic + - Implemented CondDBDQScanner: a tool to collect (merge) the DQ flags from the + Conditions Database in a given IOV. + - Added a test to validate the output of CondDBDQScanner. + +! 2012-01-31 - Marco Clemencic + - Fixed a couple of compilation warnings. + +! 2012-01-30 - Marco Clemencic + - Added new methods to the ICondDBReader interface (getIOVs), to retrieve the + list of IOVs in a folder for an IOV. + - Added a test for the implementation of getIOVs in CondDBAccessSvc, and fixes. + +! 2012-01-06 - Marco Clemencic + - Modified LoadDDDB to trigger the initialization of the UpdateManagerSvc in + the initialize (to avoid that is gets triggered in the middle of an event). + +! 2012-01-05 - Marco Clemencic + - Fixed ICC warning (Boost 1.48). + +!========================= DetCond v12r22 2011-12-14 ========================= +! 2011-12-09 - Marco Cattaneo + - Add explicit Boost_linkopts for compatibility with Gaudi v23 + +!========================= DetCond v12r21 2011-08-30 ========================= +! 2011-08-26 - Alexander Mazurov + - Update of parser function in CondDBTimeSwitchSvc. This version works only with + Gaudi version > v22r2 (where the new parser model is provided) + +!========================= DetCond v12r20 2011-07-25 ========================= +! 2011-07-20 - Marco Cattaneo + - Create MSG::VERBOSE and MSG::DEBUG messages only when output level requires + it, also using UNLIKELY macro + +!========================= DetCond v12r19 2011-06-14 ========================= +! 2011-06-06 - Illya Shapoval + - Another minor add-on for the 'UseLatestTags' warning output case. + +! 2011-06-03 - Illya Shapoval + - Added a missing configuration bit for the case of per-year-made ONLINE + snapshots: if per-year scheme is met 'CondDBAccessSvc' services are also + created per-year (before they were created per-month but pointing to a single + per-year ONLINE snapshot). SQLDDDB needs a minor change to enable this + configuration change. + - Warnings about latest tags usage are made more meaningful. + +!========================= DetCond v12r18 2011-04-04 ========================= + **** requires LHCbKernel > v12r8 **** +! 2011-03-31 - Marco Clemencic + - Modified the interfaces to use the pattern of Gaudi v21. + - Fixed a few Eclipse warnings. + - Removed CVS keywords. + - Added the possibility to fetch condition for a range of times instead of + only for the current event time. The CondDBAccessSvc property QueryGranularity + can be used to define the width of the time range (around the event time) to + use. The boundaries are rounded so that the requested range is stable. For + example, with a granularity of one hour, the event times 19:10:00, 19:23:15, + 19:56:10 will all fetch the same range 19:00:00-20:00:00. + The set the QueryGranularity property in a standard configuration: + + import GaudiKernel.SystemOfUnits as Units + Units.hours = Units.s * 3600 + + from Configurables import CondDB + CondDB(QueryGranularity = 2 * Units.hours) + +! 2011-03-28 - Marco Clemencic + - Added a test to expose bug #80076 (wrong condition used on first event). + +!========================= DetCond v12r17 2011-01-31 ========================= +! 2011-01-28 - Illya Shapoval + - Configuration machinery is upgraded to load DQFLAGS partition (implemeted in + standalone SQLite file in SQLDDDB) to populate '/Conditions/DQ/Flags' + condition of LHCBCOND partition. SIMCOND has a placeholder for this condition + too but remains empty (there is no need in DQ flags in simulations). + +! 2011-01-10 - Marco Cattaneo + - Fix icc warnings and remarks + +!========================= DetCond v12r16 2010-10-28 ========================= + +! 2010-10-28 - Marco Clemencic + - Fixed a 32bit compilation problem in some new test code. + +! 2010-10-25 - Marco Clemencic + - Added a test to expose bug #74255 + (fake event loop during finalize doesn't work). + +! 2010-10-17 - Illya Shapoval + - CondDBAccessSvc method getChildNodes is modified to load only those Online + folders in SIMCOND which are tagged with a tag being set to load db. + Modification is done in a binary backwards compatible way. + +!===================== Det/DetCond v12r15 2010-09-28 ========================= +! 2010-09-28 - Marco Clemencic + - Updated tests to expect the return codes of Gaudi (v21r11). + +! 2010-09-24 - Marco Clemencic + - Added a test to verify that a failure to load a condition in the + UpdateManagerSvc is properly reported. + +!===================== Det/DetCond v12r14 2010-08-25 ========================= +! 2010-08-06 - Marco Clemencic + - Improved DetCondTest::TestConditionAlg to allow testing artificial + dependencies between conditions. + - Modified test detcond.heart_beat to expose bug #66497 (velo motor positions + updated several times). + +!===================== Det/DetCond v12r13 2010-05-21 ========================= +! 2010-05-18 - Marco Clemencic + - Fixed few Windows warnings. + +! 2010-05-12 - Marco Clemencic + - Modified the message printed in case of a failure of the heart-beat check to + show the time in human-readable format (UTC). + +!===================== Det/DetCond v12r12 2010-04-09 ========================= +! 2010-03-27 - Illya Shapoval + - CondDB configurable is tuned to override all default and user tags settings + by the latest tags for defined DataType if the 'UseLatestTags' property is + set (before an exception was thrown if found multiple definitions). + +! 2010-03-26 - Illya Shapoval + - Added new CondDB().UseLatestTags = [DataType,OnlyGlobalTags=False] property. + Previous CondDB().useLatestTags(DataType,OnlyGlobalTags=False) method is + preserved. Now it is possible to set the latest tags also for the simulation + case. + +!===================== Det/DetCond v12r11 2010-03-17 ========================= +! 2010-03-17 - Marco Clemencic + - Changes to the CondDB configurable + - in the online environment (Online == True) the IgnoreHeartBeat property is + defaulted to True + - added the property HeartBeatCondition to set the location of the heart-beat + condition + +! 2010-03-05 - Marco Clemencic + - Fixed a problem in the CondDB configurable for the usage of Oracle in the + PIT. + +! 2010-02-25 - Marco Clemencic + - Removed the dependency on rx (obsolete). + +!===================== Det/DetCond v12r10 2010-02-12 ========================= +! 2010-02-12 - Illya Shapoval + - Minor change to the CondDB.useLatestTags(DataType) function. Added the + mode for it to find and set only the latest global tag for a + particular DataType, dropping the latest local tags on top of it. + New syntax: CondDB.useLatestTags(DataType,OnlyGlobalTags = False). + +! 2010-02-05 - Marco Clemencic + - Added the function CondDB.useLatestTags(DataType) to automatically select + the latest local and global tags for a given data type from the SQLDDDB + release notes. + +!===================== Det/DetCond v12r9 2010-01-20 ========================== +! 2010-01-19 - Marco Clemencic + - Fixes to the first implementation of task #13270. + - Handle properly cool and coral exceptions when retrieving the heart beat + condition to be able to issue a meaningful error. + - Modified the automatic setting of the HeartBeatCondition property for the + readers of CondDBTimeSwitchSvc. The property is added only to the last + reader because the other readers are (by construction) accessing limited + partitions. + +! 2010-01-12 - Marco Clemencic + - Completed task #13270: Block access to conditions in ONLINE partition if + validity interval is not closed + - Modified CondDBAccessSvc to accept a new property (HeartBeatCondition). The + property specified the path in the database to be used as heart beat, i.e. + the partition is considered not up-to-date if the latest update of that + condition is less recent than the event time being processed. + Since the test is done only when actually accessing the CondDBAccessSvc, + to ensure that we get there when the event exceeds the validity of the + database, the returned validities are artificially cut at the latest heart + beat. + - Modified the ConfigurableUser CondDB to set the HeartBeatCondition for the + Online partition and snapshots (can be disabled with the property + IgnoreHeartBeat). + - Removed the OnlineDBValidatorSvc because it is not needed anymore. + - Adapted the TestCondition algorithm to test the new feature and added the + relative test. + NOTE: In the special case when there are conditions with initial validity + after the latest heart beat, there may be problem during the initialize + if exposed validity (artificially cut) is checked (the UpdateManagerSvc + and the DetectorDataSvc are not doing it). + - Added the properties "DisableLFC" and "Online" to the ConfigurableUser CondDB + to be able to ignore the LFC when using Oracle and enable special + configuration for the Online environment (Oracle). + +!===================== Det/DetCond v12r8 2009-12-11 ========================== +! 2009-12-11 - Marco Cattaneo + - Remove obsolete file DetCond_dll.cpp + +! 2009-12-05 - Dmitry GOLUBKOV + - python/DetCond/HistoCond.py: new python module to decorate the Condition + object with functions which extract the histograms from the parameters and to + define functions which convert histograms to Condition parameter xml strings. + - cmt/requirements: version increment to v12r8 + +!===================== Det/DetCond v12r7 2009-06-16 ========================== +! 2009-06-03 - Marco Clemencic + - Changes in the CondDB ConfigurableUser: + - Fixed a bug causing a failure when using SQLite local copies and + CondDBTimeSwitchSvc. + - Changed the policy when both UseOracle and SQLiteLocalCopiesDir are active: + issue a warning and ignores SQLiteLocalCopiesDir instead of raising an + exception. + +!===================== Det/DetCond v12r6 2009-05-28 ========================== +! 2009-04-28 - Marco Cattaneo + - In Configurable, do not access MessageSvc() directly, use instead + getConfigurable("MessageSvc"), allow to replace MessageSvc instance online + +! 2009-05-27 - Marco Clemencic + - Modified the way CondDBAccessSvc::finalize() synchronizes with the second + thread. + - Updated the usage of the Boost Thread module (use more recent classes). + - Added a test triggering the connection time-out. + +!===================== Det/DetCond v12r5p3 2009-05-06 ======================== +! 2009-04-17 - Marco Cattaneo + - Replace endreq by endmsg + +!===================== Det/DetCond v12r5p2 2009-03-09 ======================== +! 2009-03-09 - Marco Cattaneo + - Add options/UseOracle.py: additional options for gaudirun.py command line + to get conditions from Oracle DB + +!===================== Det/DetCond v12r5p1 2009-02-18 ======================== +! 2009-01-29 - Marco Cattaneo + - Fix compilation warning from Boost 1.38 + +!===================== Det/DetCond v12r5 2009-01-08 ========================== +! 2009-01-07 - Marco Clemencic + - Improvements to the CondDB configurable: + - added the possibility to use local copies of the SQLite databases (through + CondDBSQLiteCopyAccSvc) + - added the possibility of specifying alternatives and layers with only the + connection string or the SQLite filename + +!===================== Det/DetCond v12r4 2008-11-17 ========================== +! 2008-11-17 - Marco Cattaneo + - Fix to requirements avoid warnings when making configurables database + - Add LoadDDDB algorithm, moved from DetDescChecks to avoid tests dependency + on DetDescChecks package + - Add missing dependencies for QMTest + +! 2008-11-14 - Marco Cattaneo + - In Configurable, set up VFSSvc, e.g. for use by ParticlePropertySvc + +! 2008-11-11 - Marco Clemencic + - Fixed configuration problems in the test after the changes in DDDB. + +! 2008-11-06 - Marco Clemencic + - Added the ConfigurableUser CondDB for the high level configuration of the + conditions database. The old configuration function (addCondDBLayer etc.) are + still available for backward compatibility, but implemented using the new + configurable which allows to specify local tags too. + +! 2008-10-31 - Marco Cattaneo + - Fix for gcc 4.3 + + NEEDS: LCGCMT > 55a + +! 2008-10-10 - Marco Clemencic + - Modified the requirements file following the changes in the CORAL interface + package (see bug #41579). + +!===================== Det/DetCond v12r3 2008-09-30 ========================== +! 2008-09-29 - Marco Clemencic + - Fixed a bug in CondDBCommon::generateXMLCatalog, failing for folders with + names shorter than 4 chars. + +!===================== Det/DetCond v12r2 2008-07-30 ========================== +! 2008-07-30 - Marco Clemencic + - Changed the name of the configurables for online partition from ONLINE-YYYYMM + to ONLINE_YYYYMM. + +! 2008-07-28 - Marco Cattaneo + - Fix windows compilation + +! 2008-07-23 - Marco Clemencic + - Changed the type of CondDBDispatcherSvc.Alternatives from list of strings + to map<string,string>. + - Added tests for DetCond.Configuration. + - Fixed a problem with conversion between 'double' and 'long long' in + CondDBTimeSwitchSvc. + +! 2008-07-21 - Marco Clemencic + - Added a function to DetCond.Configuration (configureOnlineSnapshots) to + prepare the configuration using monthly snapshots of the ONLINE partition. + The first and last snapshot used extend their validity to 0 and +infinity + respectively. + +!===================== Det/DetCond v12r1 2008-07-16 ========================== +! 2008-07-10 - Marco Clemencic + - Fixed a tiny memory leak introduced in COOLConfSvc during the deSEALing. + +!===================== Det/DetCond v12r0 2008-06-30 ========================== +! 2008-07-02 - Marco Clemencic + - Introduced a work-around for COOL bug #38422, which was preventing the usage + of local tags as overlays. + - Removed a left-over in the requirements file needed for some tests. + (It was breaking compilation on win32) + +! 2008-06-27 - Marco Clemencic + - Introduced the ICondDBReader implementation CondDBTimeSwitch. + - it allows to use different partitions for different IOVs + - added a simple test for it (using a test algorithm added to the package: + DetCondTest::TestConditionAlg). + +! 2008-06-26 - Marco Clemencic + - Improved direct mapping between the COOL hierarchy and the transient store + one: + - direct mapping enabled by default (can be turned off via options to improve + the performances of CondDBLayeringSvc and CondDBDispatcherSvc) + - correct mapping in CondDBDispatcherSvc and CondDBLayeringSvc: + - CondDBDispatcherSvc: add entries implied by alternatives + - CondDBLayeringSvc: expose all the possible entries + - modified ICondDBReader (needed for a generic implementation of the mapping) + - added tests for foreseen use-cases + - the code to generate the XML catalog has been moved to a separate file to + be shared among the implementations of ICondDBReader + - Added dictionaries for few CORAL interfaces that are not available through + COOL. + +! 2008-06-24 - Marco Clemencic + - Fixed a bug in the direct mapping between the hierarchy of the COOL + database and the transient store one. + +! 2008-06-10 - Marco Clemencic + - Adapted to the new SEAL-less COOL and CORAL. Needs LCG_55 (Gaudi v20r0) + +!===================== Det/DetCond v11r11 2008-05-19 ========================= +! 2008-05-19 - Marco Clemencic + - Added the possibility of direct mapping between the hierarchy of the COOL + database and the transient store one. + Disabled by default, but needed to use the Online partition of the condition + database. + The implementation still lacks few features: + - does not work if the cache is not enabled + - it is implemented only at the CondDBAccessSvc (it should work at the + CondDBDispatcherSvc and CondDBLayeringSvc level too) + +!===================== Det/DetCond v11r10 2008-04-24 ========================= +! 2008-04-24 - Marco Clemencic + - Improved the algorithm to select the closest replica of the database when + using LFCReplicaSvc. The local site (preferred replica), can be specified, in + order of priority, with job option (of COOLConfSvc), the environment + variables DIRACSITE and LHCBPRODSITE or the hard-coded default "CERN.ch". The + value of local site can be any substring (case insensitive) to be matched in + the "host" field of the CORAL LFC entries. The fall-back servers are used in + random order. + +! 2008-04-22 - Marco Clemencic + - Fixed a problem in CondDBAccessSvc related to the usage of local tags. + +! 2008-04-09 - Marco Clemencic + - Modified default idle connection time-out in CondDBAccessSvc from 600s to + 120s. + +!===================== Det/DetCond v11r9 2008-03-03 ========================== +! 2008-03-03 - Marco Clemencic + - Added the function "useCondDBLogger" to DetCond.Configuration. + - Modified DetCond.Configuration to expose the configurables provided by the + package when imported. + +! 2008-02-29 - Marco Clemencic + - Added the Python module DetCond.Configuration to provide useful functions + for the configuration of the CondDB: + - addCondDBLayer + - addCondDBAlternative + +! 2008-02-22 - Marco Cattaneo + - Remove hacks in requirements no longer needed with Gaudi v19r7 + +! 2008-02-12 - Marco Clemencic + - Fixed a problem occurring when trying to retrieve a folder which is not in + the database (typical case for CondDBLayeringSvc), due to an uninitialized + variable. + +!===================== Det/DetCond v11r8 2008-01-28 ========================== + NEEDS: LCGCMT >= 54 +! 2008-01-26 - Marco Clemencic + - Added the service CondDBLogger (implementation of ICondDBReader) that, if put + between a user and a provider of the ICondDBReader interface, stores in a + file all the requests that were made to the CondDBReader, with the time of + the request. + The class allows to generate some history of the CondDB traffic to be able to + analyze and replay it afterward. + - Added the algorithm CondDBReplayAlg. It can read a file produced with + CondDBLogger to replay the requests to the database. + - Modified ICondDBReader and CondDBAccessSvc to allow the retrieval of objects + from the conditions database using the channel name (available since COOL + 2.3.0, LCGCMT 54). + +! 2008-01-21 - Marco Clemencic + - Improved error messages in case of CORAL exceptions. + +! 2007-12-20 - Marco Clemencic + - Allow to use tags that are not global in CondDBAccessSvc. + - Added a service (COOLConfSvc/ICOOLConfSvc) dedicated to the instantiation and + configuration of COOL/CORAL. The options to configure COOL and CORAL have + been moved from CondDBAccessSvc to the new service. + +! 2007-12-20 - Marco Cattaneo + - Replace homemade linkopts with new Boost_linkopts_filesystem_mt + - Remove slc3 specific set, no longer supported in LCG_54 + +!===================== Det/DetCond v11r7 2007-12-03 ========================== +! 2007-11-29 - Marco Clemencic + - Added two options to CondDBAccessSvc to control the retrial period and + retrial time-out of CORAL. + +!===================== Det/DetCond v11r6 2007-09-04 ========================== +! 2007-08-01 - Marco Clemencic + - Fixed a bug connected to "lazy connection" feature. I was using an instance + of a cool object to call a static member function. + +! 2007-07-31 - Marco Clemencic + - Fixed a bug with the "lazy connection" feature. The thread to disconnect from + the database was started even if we never connect. + Now it is started only at the first connection. + +!===================== Det/DetCond v11r5 2007-07-05 ========================== +! 2007-07-05 - Marco Clemencic + - Added the possibility to connect to the database only when needed (and made + it the default), so a job does not need the database does not need to be + able to connect to it or to be reconfigured. + To restore the old behavior (connection at initialize) use the option: + CondDBAccessSvc.LazyConnect = False; + +!===================== Det/DetCond v11r4 2007-06-15 ========================== + NEEDS: LCGCMT >= 52 +! 2007-06-06 - Marco Clemencic + - Removed the check on macro CORAL_1_8_x (use always the new CORAL feature). + +!===================== Det/DetCond v11r3 2007-05-16 ========================== + NEEDS: LHCbKernel >= v7r3 (ICondDBInfo) + LCGCMT >= 51 (if macro CORAL_1_8_x is set, + for CORAL 1.8.0) + +! 2007-05-16 - Marco Clemencic + - The parts that depend on CORAL 1.8.0 API are now enclosed in #ifdef/#endif + directives, so that DetCond can be compiled with the old version of CORAL. + +! 2007-05-11 - Marco Clemencic + - Extended ICondDBReader with the interface ICondDBInfo from LHCbKernel and + implemented the new function in all the ICondDBReader's (CondDBCnvSvc, + CondDBAccessSvc, CondDBLayeringSvc, CondDBDispatcherSvc). + NOTE: this introduce a dependency on LHCbKernel. + +! 2007-05-03 - Marco Clemencic + - Added service OnlineDBValidatorSvc to check if the Online CondDB replica + is recent enough. (see doxygen documentation) + +! 2007-05-02 - Marco Clemencic + - First implementation of the algorithm to sort DB replicas extracted from + LFC. + +!===================== Det/DetCond v11r2 2007-04-23 ========================== +! 2007-04-20 - Marco Clemencic + - Added ICondDBAccessSvc::connectionString() to be able to find the + connection string that was used without looking in the options. + - Use a static std::auto_ptr instead of a basic pointer and a counter of + instances (for CondDBAccessSvc::s_XMLstorageSpec). + - Added class CondDBSQLiteCopyAccSvc to copy an SQLite file and connect to + the copy. + +!===================== Det/DetCond v11r1 2007-03-22 ========================== +! 2007-03-22 - Marco Clemencic + - Small improvement to the database disconnect message. + +! 2007-03-16 - Marco Clemencic + - Added an option to enable CORAL LFCReplicaService (off by default). + - Added an option to enable CORAL automatic connection purge. + - Added a check on the database in CondDBAccessSvc::i_checkTag to avoid + segmentation possible faults. + - Disable some compiler optimizations in libstdc++ on slc3, because it seems + that on SLC3 there are problems with multithreaded applications. + +!===================== Det/DetCond v11r0 2007-03-05 ========================== + NEEDS LCGCMT >= 50 + +! 2007-03-05 - Marco Cattaneo + - Removed obsolete DetCond_load.cpp file + +! 2007-02-28 - Marco Clemencic + - Removed a work-around for missing library in LCG_Interfaces/COOL + +! 2007-02-22 - Marco Clemencic + - Fixed a bug (segfault) occurring when requiring the time-out task without + a connection (pure memory cache). + - Moved few message from DEBUG to INFO and added few more messages (like + the connection string and the tag used). + - Activated by default the disconnect on time-out feature (with time out set + to 10 min.) + +! 2007-02-19 - Marco Clemencic + - Minor change in RelyConverter.cpp (removed a useless line) + +! 2007-02-14 - Marco CLEMENCIC + - Updated to changes in COOL API + - Added to CondDBAccessSvc a function to clear the cache + +!================ Det/DetCond v10r0 2007-01-31 ============================= +! 2007-01-31 - Marco Cattaneo + - Fix and retag requirements to link on Windows. + +! 2006-12-06 - Florence RANJARD + - apply_pattern install_more_includes + - fixes for new plugins (P.Mato) + +!================= Det/DetCond v9r1 2006-09-04 ============================== +! 2006-09-04 - Marco Clemencic + - Modified the way of specifying one of the element of the condition. Now the + path to a condition in XML is: + + "conddb:/path/to/condition/[attribute@]Folder.xml[:channel][#Name]" + +! 2006-08-31 - Marco Clemencic + - Added the possibility of using one CondDB condition to store more than one + file using elements of the attribute list. + Backward compatible chages in the API (with deprecated functions). + +! 2006-08-31 - Marco Clemencic + - Added the possibility of disconnection from the DB after an inactivity + period defined by CondDBAvvessSvc.ConnectionTimeOut. + (The feature is implemented using Boost.Thread) + +! 2006-08-30 - Marco Clemencic + - Fixed a bug in CondDBDispatcherSvc: the correct alternative database was + never selected + - Fixed a bug in RelyConverter that was causing a segmentation fault if the + retreived XML string didn't start with "<?xml" (it is not a valid XML + string, but it does not justfy a segfault ;) + +!================= Det/DetCond v9r0 2006-07-18 ============================== +! 2006-07-18 - Marco CLEMENCIC + - Added to CondDBAccessSvc the possibility of chosing between read-only and + read-write connections to the database. (default is read-only) + +! 2006-07-17 - Marco CLEMENCIC + - Using Gaudi random generator service instad of the posix one in + CondDBAccessSvc (needed for recursive tagging) + +! 2006-07-14 - Marco CLEMENCIC + - Removed interface ICondDBCnvSvc. Now CondDBCnvSvc is an ICondDBReader and + the layering of databases is delegated to the class CondDBLayeringSvc. + - Removed the obsolete method ICondDBEditor::createFolder + +! 2006-07-12 - Marco CLEMENCIC + - Fixed a small bug in the code for the selection of the alternative in + CondDBDispatcherSvc. + +! 2006-07-11 - Marco CLEMENCIC + *** will be v9r0 *** + - Completely redesigned the support for alternative DBs: + - Reverted to previous implementation of CondDBAccessSvc + - Splitted ICondDBAccessSvc in 3: + 1) ICondDBReader: read only functions + 2) ICondDBEditor: write functions (storeXML, createNode, etc.) + 3) ICondDBAccessSvc: access function (setTag, etc.) + - Added the class CondDBDispatcherSvc as an implementation of ICondDBReader. + This one is selecting the appropriate alternative AccessSvc to use. + The alternative is declared with something like: + CondDBDispatcherSvc.Alternatives += { "/OnLine=CondDBAccessSvc/OnlineAccSvc" }; + The new functionality is not tested, but it is backward compatible even using + CondDBDispatcherSvc with only the default access service (CondDBAccessSvc). + - Dictionary updated to include the 2 new interfaces. + - Removed dependency on PCRE (not needed anymore) + - Documentation still to be updated. + +! 2006-07-07 - Marco CLEMENCIC + - Added the possibility of specifying alternative databases for certain + sub trees to a CondDBAccessSvc. + Now you have a default DB (backward compatible) and you can use a different + COOL DB for all the directories under e.g. "/OnLine", with an option like + CondDBAccessSvc.AlternativeDBs += { "/OnLine=<connectionString>" }; + Note: it still has to be tested, but it is backward compatible. + - Added dependency on PCRE (used to parse the string to specify alternative DB) + +! 2006-06-16 - Marco CLEMENCIC + - Removed some code used for debugging which is not needed. + - Added the possibility to wait that the requested tag appears + (configurable number of trials and time between trials) + +! 2006-06-12 - Marco CLEMENCIC + - Many API changes + - remamed ICondDBAccessSvc::createFolder to ICondDBAccessSvc::createNode + - removed the version of ICondDBAccessSvc::storeXMLString taking two doubles + because it was obsolete and confunding + - replaced ICondDBAccessSvc::tagFolder with the two functions + ICondDBAccessSvc::tagLeafNode and ICondDBAccessSvc::recursiveTag + (the first for Folders, the second for sub-trees) + - removed obsolete properties: HostName, User, Password, HidePassword, + Database, Schema, BackEnd + - property TAG renamed to DefaultTAG + - default value for property UseCache set to true (it was false) + - Enabled tagging functionalities (based on COOL HVS) + +!================= Det/DetCond v8r0 2006-04-25 ============================== +! 2006-04-25 - Marco Clemencic + **** requires LCGCMT_43 **** + - Updated to COOL_1_3_x + +! 2006-04-13 - Marco Clemencic + - Fixed a problem with uninitialized variables just affecting the case of + a FolderSet stored in the CondDB cache. + +!================= Det/DetCond v7r10p1 2006-03-29 ============================ +! 2006-03-29 - Marco Cattaneo + - Trivial fix in requirements for GCCXML+Boost on Windows with LCG_v42a + +!================= Det/DetCond v7r10 2006-03-22 ============================== +! 2006-03-22 - Marco Cattaneo + - Add DetCondDict (to remove dependency on DetCond in DetSys) + +!================= Det/DetCond v7r9 2006-02-03 =============================== +! 2006-02-01 - Marco Clemencic + - Updated to Gaudi v18r2 (use Gaudi::Time instead of ITime+TimePoint) + - Added Boost and SEAL to the dependencies because they are not inherited + from other packages anymore + +! 2006-01-25 - Nicolas Gilardi + - Allow to use a COOL connection string instead of the splitted credentials + - Modified Function CondDBAccessSvc::createFolder() to use large (16M) + strings by default in the CondDB folders. + +! 2006-01-22 - Marco Clemencic + Nicolas Gilardi + - Updated to improved COOL API. + +================= Det/DetCond v7r8 2006-01-20 ================================ +! 2006-01-20 - Marco Cattaneo + - Add use CORAL to requirements. N.B.: this is temporary, should be done + directly in COOL interface package + +! 2005-12-08 - Marco Clemencic + - Use GaudiUtils::HashMap in CondDBCache.h + +================= Det/DetCond v7r7 2005-11-04 ================================ +! 2005-10-18 - Marco Clemencic + - Cosmetic improvements + (RelyConverter, CondDBGenericCnv, CondDBAccessSvc, CondDBCnvSvc) + - Added `#include <vector>' in ICondDBAccessSvc.h and ICondDBCnvSvc.h + +! 2005-10-05 - Marco Clemencic + - Minimal update to follow API changes from COOL_1_1_0 to COOL_1_2_4 + +================= Det/DetCond v7r6 2005-09-19 ================================ +! 2005-09-18 - Marco Clemencic + - Allow direct mapping of the CondDB structure to the DetectorDataSvc tree + (no need to pass through an XML file/string with only catalogs) + - Use the 3rd string of the GenericAddress to store the origin of the XML + string (needed for self referencing XML string with DetDescCnv > v2r8) + +! 2005-08-31 - Marco Clemencic + - Implemented RelyConverter::updateObjRefs in order to re-initialize + correctly the updated conditions. + +! 2005-08-30 - Marco Clemencic + - Added support to cool::ChannelId (needs DetDescCnv > v2r8) + - Fixed a bug in CondDBCache + (the search of conflicts in the IOVs worked only in a well defined case, + the one tested!) + +================= Det/DetCond v7r5 2005-07-21 ================================ +! 2005-07-21 - Marco Clemencic + - Apply always tag NEEDS_COOL_FACTORY (is needed by Windows and Python) + +! 2005-07-11 - Marco Clemencic + - Removed unused pointers from CondDBCnvSvc + +! 2005-07-07 - Marco Cattaneo + - Fix a doxygen warning + +! 2005-07-07 - Marco Clemencic + - Abstract interfaces moved to DetDesc (to allow python bindings) + - Added CondDBAccessSvc::dumpCache(), it prints (level=DEBUG) the content + of the cache. + +! 2005-06-30 - Marco Clemencic + - Added RelyConverter::fillObjectRefs (was missing, but needed for + initialization of objects) + +================= Det/DetCond v7r4 2005-06-23 ================================ +! 2005-06-23 - Marco Clemencic + - Added the possibility of having an in-memory copy of the CondDB. + +! 2005-06-14 - Marco Clemencic + - Renamed ConditionsDBCnvSvc to CondDBCnvSvc and added the interface + ICondDBCnvSvc + +================= Det/DetCond v7r3 2005-06-14 ================================ +! 2005-06-14 - Marco Cattaneo + - Move ConditionsDbCnvSvc and RelyConverter to component library. + +! 2005-06-14 - Marco Clemencic + - CondDBAccessSvc does not complain anymore if the user is not specified + (adapted to POOL XML authentication service, COOL > 1.1.0) + +! 2005-06-08 - Marco Clemencic + - Changed from "component library" to "component + link library" + +================= Det/DetCond v7r2 =========================================== +! 2005-05-27 - Marco Clemencic + - fixed compilation issue for Windows + +! 2005-05-25 - Marco Clemencic + - Adapted to COOL 1.1.0 (LCG_35) + +================= Det/DetCond v7r1 =========================================== +! 2005-05-12 - Marco Clemencic + - Fixed the compilation on WIN32 + - Added support to multiple databases through option + ConditionsDBCnvSvc.CondDBAccessServices + +================= Det/DetCond v7r0 =========================================== +! 2005-04-25 - Marco CLEMENCIC + - Upgrade to COOL_1_0_0 (first production release) + - Works with LHCb v18r3 + +================= Det/DetCond v6r1 =========================================== +! 2005-04-22 - Marco CLEMENCIC + - Upgrade to COOL_0_1_0-pre2 + - Support for tagging + - almost all the technicalities (POOL/COOL) moved to CondDBAccessSvc + - some clean up + - commit before the first production release + +============================================================================== +! 2005-02-09 - Marco CLEMENCIC + - Upgrade to first public preliminary version of COOL (COOL_0_0_3-pre1) + - Renamed XMLRelyCnv to RelyConverter (it can use, in principle, any + conversion service). + - Moved CondDBGenericCnv to the public interface in order to allow public + usage of RelyConverter. + +============================================================================== +! 2005-01-27 - Marco CLEMENCIC + - Upgrade to first preliminary version of the Conditions Database API: + COOL_0_0_1 + +============================================================================== +! 2004-12-08 - Marco Clemencic + - Upgrade to latest stable version of CondDB (CONDDB_0_2_0) and fixed for the +changes in Gaudi/LHCb + - Moved and modified part of the ConditionsDBCnvSvc to a dedicated converter +(XmlRelyCnv) + a generic CondDB converter to put common Converter functions in +one place + - Implemented the possibility to use a fall back Converter (the one relying on +DetectorPersistencySvc) if no dedicated converter is found. +Requirements v5r0 + +============================================================================== +!20030131 - Andrea Valassi +Upgrade to DetDesc v11r8. +Only change is in recommended CMTPATH. +- DetDesc is included in LHCB_v11r5 for all of rh61dbx, rh73dbx and Windows +- This makes it easier to distribute as DetDesc does not need to be recompiled +Requirements v4r3, private tag h20030131 + +============================================================================== +!20021203 - Andrea Valassi +Include the MySQL implementation for both RH73 and WIN32 +- DetCond on RH73/WIN32 now depends on both Oracle and MySQL implementations + > multiple "use..." in the requirements + > if the "use..." statement is removed, some code is #ifndef'd away + (as the base packages propagate to DetCond the relevant cppflags) + > to make the code more readable, implementation-specific init() and + i_buildCondDBInfo() have been introduced (#ifdef'd in only if necessary!) + > I assume RH61 is always Objy only +- Implementation is read at runtime from the job options + > ConditionsDBGate.condDBImpl = one of CondDBObjy, CondDBOracle, CondDBMySQL +- Remove CondDBKey.h from DetCond (I forgot to remove it on h20020301!) +Requirements v4r2, private tag h20021203 + +============================================================================== +!20021125 - Andrea Valassi +Upgrade to CondDBOracle v4r16, Gaudi v11r2 and DetDesc v11r2. +Upgrade to RedHat73 on lxplus7. +- no major change to DetCond code + > disable WIN32 compilation warning 4786 in ConditionsDBGate.cpp + > print out ORA_NLS33 and NLS_LANG to keep track of their values +- dependency on Det/CondDBOracle changed from v4r15 to v4r16 (RH7,WIN) +- dependency on Gaudi changed to v13r* (tested with v13r2) +- dependency on GaudiSvc changed to v10r* (tested with v10r1) +- dependency on Det/DetDesc changed to v11r* (tested with v11r2) +Modify CMT requirements to allow for runtime choice between Oracle and MySQL. +- precompiler directives are inherited from CondDB package(s) +- dependency on CONDDB (using Objectivity) changed to v3r02p3 (RH6) +Requirements v4r1, private tag h20021125 + +============================================================================== +!20020725 - Andrea Valassi +Upgrade to CondDBOracle v4r15 and Gaudi v10r4. +- no change to DetCond code +- dependency on Det/CondDBOracle changed from v3r10p1 to v4r15 (RH7,WIN) +- dependency on CONDDB (using Objectivity) remains v3r02p2 (RH6) +- dependency on Gaudi tested with GaudiKernel v12r3 and GaudiSvc v8r3 +- dependency on Det/DetDesc (v10r*) tested with v10r3 +Requirements v4r0, private tag h20020725 + +============================================================================== +!20020417 - Andrea Valassi +Upgrade to Gaudi v10 +- use RedHat7.2 tag rh72_gcc2952 (not rh72_gcc29521), defined in GaudiPolicy +- dependency on Det/CondDBOracle changed from v3r10 to v3r10p1 +- dependency on CONDDB changed from v3r02p1 to v3r02p2 (bug fix) +- adapt to new version of MsgStream.h in GaudiKernel for longlong printout +- dependency on Det/DetDesc changed from v9r* to v10r* +Requirements v3r0, private tag h20020417 + +============================================================================== +!20020405 - Andrea Valassi +Minor modifications to requirements +- dependency on CONDDB changed from v3r02 to v3r02p1 +- env. variable CONDDB_implementation is defined in CONDDB or Det/CondDBOracle +Requirements v2r1, private tag h20020405 + +============================================================================== +!20020328 - Andrea Valassi +First Oracle implementation ported to Linux (RedHat 7.2 only) +See doc/README.RedHat72 in Ex/DetCondExample for more details +Corresponds to Emil's first official release of ConditionsDB (0.3.1.0) +- change WIN32 dependency on Det/CondDBOracle package to version v3r10 +- add rh72_gcc29521 dependency on Det/CondDBOracle v3r10 +- keep rh61_gcc29521 dependency on CONDDB v3r02 +Requirements v2r1, private tag h20020328. + +============================================================================== +!20020308 - Andrea Valassi +Change dependency on CondDBOracle package to version v2r10 (0.2.1.0). +Requirements v2r1, private tag h20020308. + +============================================================================== +!20020301 - Andrea Valassi +First version supported on Windows using an Oracle implementation of CondDB. +- Platform-specific support + > remove CondDBKey.h from DetCond: use that from the ConditionsDB package + > interchange the contents of DetCond_dll and DetCond_load + > remove #ifdef's with dummy failure codes for non-Linux platforms +- Support of Oracle (needed also to suppport Oracle under Linux) + > implementation specified in the requirements is propagated via #ifdef's + > new init string for the Oracle database including host, user and password + > CondDBOracleMgrFactory or CondDBObjyDBMgrFactory called in either case +Requirements v2r1, private tag h20020301. + +============================================================================== +!20020110 - Flr + requirements - apply packageShr instead of ld_library_path pattern because + it is a component library. + do not apply package_Lshlibflags, there is no linker library. + +!20011220 - Andrea Valassi +Simplify dependencies on the Gaudi framework. + +============================================================================== +!20011216 - Andrea Valassi +Major changes due to tighter coordination with DetDesc and XmlDDDB packages. +- Update cannot be delegated to XmlCnvSvc until major changes in DetDes + > code creating and interpreting DOM trees in each Xml converter should be + executed also in updateObj(): to avoid duplicating code, a solution is + to move it from createObj() to updateObj() or better updateObjRefs(), + which should be called internally from createObj() + > my (temporary?) solution is to create a new object using the address, and + deep copy part of it into the old one by a Condition::update(Condition&) + method to deep copy only those properties of a DataObject that refer + to a Condition (eg validity and parameters); the registry, address, + reference counts and other DataObject properties should not be deep + copied instead (hence an overloaded operator= is not introduced) + > update of DataObjects is only possible for Conditions (and derived classes) + because this method exists only for Conditions + > this is the only reason to have a dependency on DetDesc + > however, DataObjects not implementing IValidity are now assumed valid + (previously, an error was returned when updating them) +- Changes in folder description + > classID are removed from all XML refs: remove it from folder description + > assume that secondary storage type is always read from folder description +- Remove ConditionsDBAddress (a GenericAddress of type CONDDB is enough) + > par[0] is still the COndDB folder name + > the tag name is not anymore in the CONDDB address + > par[1] is now the name of the element (e.g. the name of an XML element) + > the string storage type is not in the CONDDB address + (it is now assumed that it is always read from the folder description) + > ipar{0,1] are not used anymore +- Registry entry (can be 0) is used in creating and updating Conditions + > for instance: this is needed for catalog conversion + > it is set in the secondary temporary address (e.g. an XML catalog address) +- Minor changes in messaging: use VERBOSE tag for verbose comments +- Overload methods for writing representations in ConditionsDBCnvSvc + > they must be overloaded because this CnvSvc has no converters + > they are empty for the moment (not yet implemented) +- Upgrade to CMT v1r10: remove scripts and hacks needed to cure a bug in CMT +Requirements v2r0, private tag h20011216. + +============================================================================== +!20011130 - Andrea Valassi +Modified version of DetDataSvc in GaudiSvc committed to CVS +- Contains main features of ConditionDataSvc and ConditionsDBDataSvc +- Remove ConditionDataSvc and ConditionsDBDataSvc from this package + +============================================================================== +!20011129 - Andrea Valassi +- Remove the IConditionsDBDataSvc special interface + > ConditionsDBDataSvc now does little more than ConditionDataSvc +- Implement a dummy IIncidentListener interface in ConditionDataSvc +- Redefine ConditionsDBAddress_undefinedClassID = CLID_NULL (it will disappear) + +============================================================================== +!20011128 - Andrea Valassi +Move the global tag from the ConditionsDBDataSvc to the ConditionsDBCnvSvc +- Use IAddressCreator interface of CnvSvc to create addresses with global tag + > "DEFAULT" becomes a reserved word to indicate the global tag +- Remove method setGlobalTag (the tag can only be set in the job options) + +============================================================================== +!20011127 - Andrea Valassi +A few more changes before including my detector data service in GaudiSvc +- The event time is not passed in an address from the DataSvc to the CnvSvc + > remove IConditionAddress + > ConditionsDBCnvSvc now reads the event time from the DetDataSvc + > ConditionDataSvc::updateObject now just checks validity before delegating +- Move interface IDetDataSvc (formerly IConditionDataSvc) to GaudiKernel + > needed to retrieve the event time within the ConditionsDBCnvSvc + > the setEventTime method is temporary (eventually: use the IncidentService) +- Store ConditionsDBAddress private data as GenericAddress private data + +============================================================================== +!20011126 - Andrea Valassi +A few changes before including my data service in GaudiSvc. +- Move ConditionData from DetCond/src/Lib to DetCondExample + > only DataObjects are manipulated, with dynamic casts to IValidity + > no Lib anymore in DetCond/src +- Manipulate ITime and TimePoint objects rather than ITime pointers + > add bool method to check if the event time is defined in ConditionDataSvc + +============================================================================== +!20011123 - Andrea Valassi +Upgrade to Gaudi v9 +- Addresses now inherit from GenericAddress (which has been simplified a lot) +- There are no address factories any more +- Adapt to changes in RegistryEntry (which now implements IRegistry) +- Add dummy methods fillObjRefs and updateObjRefs in ConditionsDBCnvSvc +- Notify (by flag "true") ServiceLocator to create services not existing yet +Requirements v2, private tag h20011123. + +============================================================================== +!20010914 - Andrea Valassi +New package. +Requirements v1, private tag v1. + diff --git a/Det/DetCond/options/UseOracle.py b/Det/DetCond/options/UseOracle.py new file mode 100644 index 000000000..142aec20d --- /dev/null +++ b/Det/DetCond/options/UseOracle.py @@ -0,0 +1,3 @@ +# Additional options for accessing Oracle conditions DB. +from Configurables import CondDB +CondDB(UseOracle = True) diff --git a/Det/DetCond/python/DetCond/Configuration.py b/Det/DetCond/python/DetCond/Configuration.py new file mode 100755 index 000000000..038fa6b7e --- /dev/null +++ b/Det/DetCond/python/DetCond/Configuration.py @@ -0,0 +1,788 @@ +""" +High level configuration tools for Conditions Database. +""" +__author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>" + +from Gaudi.Configuration import allConfigurables, ConfigurableUser, importOptions, getConfigurable, log +from Configurables import ( CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBCnvSvc, + CondDBSQLiteCopyAccSvc, + CondDBLogger, + COOLConfSvc, + ApplicationMgr ) + +import os, re +from os.path import exists, join + +class CondDB(ConfigurableUser): + """ + Configurable user to allow high-level configuration of the access to the + conditions database. + """ + __slots__ = { "Tags" : {}, + "Simulation" : False, + "Upgrade" : False, + "UseOracle" : False, + "LocalTags" : {}, + "LogFile" : "", + "Overrides" : [], + "PartitionConnectionString": {}, + "SQLiteLocalCopiesDir": "", + "OverwriteSQLiteLocalCopy": False, + "DisableLFC" : False, + "Online" : False, + "IgnoreHeartBeat": False, + "HeartBeatCondition" : "/Conditions/Online/LHCb/Tick", + "EnableRunStampCheck": False, + "RunStampCondition": "", + "LatestGlobalTagByDataType" : "", + "LatestGlobalTagByDataTypes" : [], + "LatestLocalTagsByDataType": [], + "AllLocalTagsByDataType": [], + "UseLatestTags" : [], + "QueryGranularity" : 0, + "UseDBSnapshot" : False , + "DBSnapshotDirectory" : "/group/online/hlt/conditions" , + 'EnableRunChangeHandler' : False, + 'RunChangeHandlerConditions' : { 'online_%d.xml' : [ "Conditions/Online/LHCb/Magnet/Set" + , "Conditions/Online/Velo/MotionSystem" + , "Conditions/Online/LHCb/Lumi/LumiSettings" + , "Conditions/Online/LHCb/LHCFillingScheme" + , "Conditions/Online/LHCb/RunParameters" + , "Conditions/Online/Rich1/R1HltGasParameters" + , "Conditions/Online/Rich2/R2HltGasParameters" ] }, + 'LoadCALIBDB' : "OFFLINE" + } + _propertyDocDct = { + 'Tags' : """ Dictionary of tags (partition:tag) to use for the COOL databases """, + 'Simulation' : """ Boolean flag to select the simulation or real-data configuration """, + 'Upgrade' : """ Boolean flag to select the Upgrade simulation configuration """, + 'UseOracle' : """ Boolean flag to enable the usage of the CondDB from Oracle servers. NB: Obsolete as Oracle support is now dropped""", + 'LocalTags' : """ Dictionary with local tags to use to override the global ones (partition: list of local tags) """, + 'LogFile' : """ Record the requests to the database the specified file """, + 'Overrides' : """ Internal property used to add layers or alternatives """, + 'PartitionConnectionString' : """ Dictionary with alternative connection strings for the CondDB partitions """, + 'SQLiteLocalCopiesDir' : """ The directory where to copy the SQLite files before accessing them """, + 'OverwriteSQLiteLocalCopy' : """ When using SQLite local copies, overwrite existing files """, + 'DisableLFC' : """ Do not use LFC lookup even if we are connecting to Oracle """, + 'Online' : """ Flag to activate configuration options specific for the Online environment """, + 'IgnoreHeartBeat' : """ Do not set the HeartBeatCondition for the Online partition """, + 'HeartBeatCondition' : """ Location of the heart-beat condition in the database """, + 'EnableRunStampCheck': """ Enable the check for the special RunStamp condition """, + 'RunStampCondition': """ Path (in the CondDB) to the special RunsTamp condition. """, + 'LatestGlobalTagByDataType' : """ Use latest CondDB global tag marked with the data type""", + 'LatestGlobalTagByDataTypes' : """ Use latest CondDB global tag marked with the data type, will override LatestGlobalTagByDataType if set""", + 'LatestLocalTagsByDataType' : """ Use all latest CondDB local tags marked with the data type """, + 'AllLocalTagsByDataType' : """ Use all CondDB local tags marked with the data type """, + 'UseLatestTags' : """ List of the form [DataType, OnlyGlobalTags = False] to turn on the usage of the latest tags """, + 'QueryGranularity': """Granularity of the query in the database (in time units)""", + 'LoadCALIBDB': """ Load CALIB*.db file as additional layers on top of ONLINE-*.db file, could be either "HLT1" (w/o layering, ONLINE only), or "OFFLINE" (Layer CALIBOFF above CALIB & ONLINE ), Do not set it for the Online environment""", + } + LAYER = 0 + ALTERNATIVE = 1 + # List of known implementations of ICondDBReader (str is used for backward compatibility) + __CondDBReaders__ = [ CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc, + str ] + + def _checkOverrideArgs(self, accessSvc, connStr, dbFile, dbName): + """ + Check if the accessSvc is a valid CondDBReader or build one using the + other arguments. + """ + kwargs = { "accessSvc": accessSvc, "connStr": connStr, "dbFile": dbFile, "dbName": dbName } + if accessSvc is None: + if not connStr: + if dbFile: + if not dbName: + dbName = os.path.basename(dbFile) + m = re.match(r'([A-Z][A-Z0-9_]{0,7})(_\w+)?.db', dbName) + if m: + dbName = m.group(1) + else: + raise ValueError('invalid arguments %r' % kwargs) + connStr = "sqlite_file:%s/%s" % (dbFile, dbName) + else: + raise ValueError('invalid arguments %r' % kwargs) + name = dbName + else: + name = connStr.rsplit('/')[-1] + if not re.match(r'[A-Z][A-Z0-9_]{0,7}', name): + name = 'CondDBAccessSvc' + # make a unique name for the configurable + name = "automatic_" + name + name_format = name + '_%d' + i = 0 + while name in allConfigurables: + i += 1 + name = name_format % i + accessSvc = CondDBAccessSvc(name, ConnectionString = connStr) + elif type(accessSvc) not in __CondDBReaders__: # Check for supported types + raise TypeError("'%s' not supported as CondDBReader"%accessSvc.__class__.__name__) + return accessSvc + + def addLayer(self, accessSvc = None, connStr = None, dbFile = None, dbName = None): + """ + Add the given CondDBReader as a layer on top of the existing configuration. + + Example: + CondDB().addLayer(myDB) + """ + # Check the arguments and/or prepare a valid access svc + accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) + self.Overrides.append((self.LAYER, accessSvc)) + def _addLayer(self, accessSvc): + cnvSvc = allConfigurables["CondDBCnvSvc"] + + originalReader = cnvSvc.CondDBReader + if type(originalReader) == CondDBLayeringSvc: + # If the original reader is already a layering svc, we can extend the + # configuration. + originalReader.Layers.insert(0,accessSvc) + else: + # We have to create a new layering svc. + name = "CondDBLayeringSvc" + i = 0 + while name in allConfigurables: + i += 1 + name = "CondDBLayeringSvc_%d"%i + cnvSvc.CondDBReader = CondDBLayeringSvc(name, + Layers = [accessSvc, + originalReader]) + + def addAlternative(self, accessSvc = None, path = None, connStr = None, dbFile = None, dbName = None): + """ + Add the given CondDBReader as an alternative to the existing configuration + for the specified path. + + Example: + CondDB().addAlternative(myDB,"/Conditions/MyDetector/Alignment") + """ + if path is None: + raise ValueError("'path' must be specified") + # Check the arguments and/or prepare a valid access svc + accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) + self.Overrides.append((self.ALTERNATIVE, accessSvc, path)) + + def _addAlternative(self, accessSvc, path): + cnvSvc = allConfigurables["CondDBCnvSvc"] + + originalReader = cnvSvc.CondDBReader + if type(originalReader) == CondDBDispatcherSvc: + # If the original reader is already a dispatcher, we can extend the + # configuration: + originalReader.Alternatives[path] = accessSvc + else: + # We have to create a new dispatcher + name = "CondDBDispatcherSvc" + i = 0 + while name in allConfigurables: + i += 1 + name = "CondDBDispatcherSvc_%d"%i + cnvSvc.CondDBReader = CondDBDispatcherSvc(name, + MainAccessSvc = originalReader, + Alternatives = { path: accessSvc } + ) + + def useLatestTags(self, DataType, OnlyGlobalTags = False): + self.UseLatestTags = [DataType, OnlyGlobalTags] + + def _useLatestTags(self, DataTypes, OnlyGlobalTags = False, OnlyLocalTags = False): + """ + Configure the conditions database to use the latest local tags on top of the latest global tag for a given data type. + """ + # Check arguments + if type(DataTypes) is not list: + DataTypes = [DataTypes] + + # Check if the latest tags should be set for simulation or not + if not self.getProp("Simulation"): + partitions = ["DDDB", "LHCBCOND", "DQFLAGS"] + if os.environ['LoadCALIBDB'] is "OFFLINE": + partitions += ["CALIBOFF"] + else: + partitions = ["DDDB", "SIMCOND"] + + # Set the latest tags + from CondDBUI.Admin.TagsFilter import last_gt_lts + rel_notes = None + if self.getProp('Upgrade'): + rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') + + for partition in partitions: + gt, lts = None, [] + for dt in DataTypes: + tags = last_gt_lts(partition, dt, rel_notes) + if not tags: + # Allowing absence of valid tags for DQFLAGS + if partition == 'DQFLAGS': continue + # Allowing absence of valid tags for CALIBOFF before 2015 + elif partition == 'CALIBOFF' and dt.isdigit() and int(dt)<2015: continue + else: + raise RuntimeError("Cannot find tags for partition '%s'," + " data type '%s'" % (partition, dt)) + if not gt: + gt = tags[0] + lts += tags[1] + + if not OnlyLocalTags and gt: # Only for partitions with available global tags + self.Tags[partition] = gt + if not OnlyGlobalTags and lts: + if partition in self.LocalTags: self.LocalTags[partition] += lts + else: self.LocalTags[partition] = lts + + def _useAllLocalTags(self, DataTypes): + """ + Configure the conditions database to use all local tags for a given data type. + """ + + # Check arguments + if type(DataTypes) is not list: + DataTypes = [DataTypes] + + # Check if the latest tags should be set for simulation or not + if not self.getProp("Simulation"): + partitions = ["DDDB", "LHCBCOND"] + if os.environ['LoadCALIBDB'] is "OFFLINE": + partitions += ["CALIBOFF"] + else: + partitions = ["DDDB", "SIMCOND"] + + # Set the latest tags + from CondDBUI.Admin.TagsFilter import all_lts + rel_notes = None + if self.getProp('Upgrade'): + rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') + + for partition in partitions: + local_tags = [] + for dt in DataTypes: + lts = all_lts(partition, dt, rel_notes) + if lts: local_tags += lts + if partition in self.LocalTags: self.LocalTags[partition] += local_tags + else: self.LocalTags[partition] = local_tags + + def __make_sqlite_local_copy__(self, accsvc, local_dir = None, force_copy = None): + if isinstance(accsvc, str): + # convert the string in an actual configurable instance + # This is both for backward compatibility and CondDBTimeSwitchSvc + if "/" in accsvc: + tp, name = accsvc.split("/",1) + else: + tp = name = accsvc + accsvc = getConfigurable(name, tp) + if local_dir is None: + local_dir = self.getProp("SQLiteLocalCopiesDir") + if force_copy is None: + force_copy = self.getProp("OverwriteSQLiteLocalCopy") + # If the directory for the local copies is not specified, we do nothing + if not local_dir: + return accsvc + # Check if we are using Oracle or SQLite +# if self.getProp("UseOracle"): +# log.warning("Conflicting properties in CondDB Configurable: " +# "ignoring SQLiteLocalCopiesDir because UseOracle is set to True") +# return accsvc + # Modify partitions to use local copies of the DBs + newaccsvc = accsvc # fallback return value (no change) + if isinstance(accsvc, CondDBAccessSvc): + # replace the reader with another + m = re.match(r"^sqlite_file:(.*)/([_0-9A-Z]{1,8})$", + accsvc.getProp("ConnectionString")) + if not m: # not SQLite connection string + return accsvc + newaccsvc = CondDBSQLiteCopyAccSvc(accsvc.name() + "_local") + newaccsvc.OriginalFile = m.group(1) + newaccsvc.DestinationFile = os.path.join(local_dir, + os.path.basename(m.group(1))) + newaccsvc.DBName = m.group(2) + newaccsvc.ForceCopy = force_copy + newaccsvc.IgnoreCopyError = not force_copy # ignore copy errors if we do not overwrite (needed for local tags) + if hasattr(accsvc, "CacheHighLevel"): + newaccsvc.CacheHighLevel = accsvc.CacheHighLevel + elif isinstance(accsvc, CondDBDispatcherSvc): + # use the same dispatcher replacing its content + mainAccSvc = accsvc.getProp("MainAccessSvc") + accsvc.MainAccessSvc = self.__make_sqlite_local_copy__(mainAccSvc, local_dir) + alternatives = accsvc.getProp("Alternatives") + for alt in alternatives.keys(): + accsvc.Alternatives[alt] = \ + self.__make_sqlite_local_copy__(alternatives[alt], local_dir) + elif isinstance(accsvc, CondDBLayeringSvc): + # use the same layering service replacing its content + new_layers = [] + for layer in accsvc.getProp("Layers"): + new_layers.append(self.__make_sqlite_local_copy__(layer, local_dir)) + accsvc.Layers = new_layers + elif isinstance(accsvc, CondDBTimeSwitchSvc): + # use the same time switcher replacing its content, + # but we need to parse its options (in format "'%s':(%d,%d)") + readers_list = accsvc.getProp("Readers") + new_readers = [] + for line in readers_list: + # Parse the line for the reader (it looks like "'name':(0,1)") + r, iov = map(eval, line.rsplit(":")) + new_reader = self.__make_sqlite_local_copy__(r, local_dir) + new_readers.append("'%s':(%d,%d)" % + (new_reader.getFullName(), iov[0], iov[1])) + accsvc.Readers = new_readers + elif isinstance(accsvc, CondDBLogger): + # use the same logger replacing its content + logged = accsvc.getProp("LoggedReader") + accsvc.LoggedReader = self.__make_sqlite_local_copy__(logged, local_dir) + elif isinstance(accsvc, CondDBCnvSvc): + # use the same conversion service replacing its content + reader = accsvc.getProp("CondDBReader") + accsvc.CondDBReader = self.__make_sqlite_local_copy__(reader, local_dir) + return newaccsvc + + def _configureDBSnapshot(self): + + baseloc = self.getProp( "DBSnapshotDirectory" ) + self.DisableLFC = True + + # Set alternative connection strings and tags + # if simulation is False, we use DDDB, LHCBCOND and ONLINE + # True DDDB, SIMCOND + # (see Det/DetCond's configurable... ) + dbPartitions = { False : [ "DDDB", "LHCBCOND", "ONLINE" ] + , True : [ "DDDB", "SIMCOND" ] + } + + tag = self.getProp("Tags") + for part in dbPartitions[ self.getProp('Simulation') ] : + if tag[part] is 'default' : raise KeyError('must specify an explicit %s tag'%part) + self.PartitionConnectionString[part] = "sqlite_file:%(dir)s/%(part)s_%(tag)s.db/%(part)s" % {"dir": baseloc, + "part": part, + "tag": tag[part]} + self.Tags[part] = tag[part] + + # Set the location of the Online run-by-run conditions + if self.getProp('EnableRunChangeHandler') : + from Configurables import RunChangeHandlerSvc + rch = RunChangeHandlerSvc() + rch.Conditions = dict( (c,'/'.join([baseloc,f])) for f,cs in self.getProp("RunChangeHandlerConditions").iteritems() for c in cs ) + ApplicationMgr().ExtSvc.append(rch) + + def __apply_configuration__(self): + """ + Converts the high-level information passed as properties into low-level configuration. + """ + # special case for online + if self.getProp('UseDBSnapshot') : self._configureDBSnapshot() + + # In the Online/Upgrade/Simulation environment, LoadCALIBDB should be defaulted to HLT1 + if self.getProp("Online") or self.getProp('Upgrade') or self.getProp('Simulation'): + self._properties["LoadCALIBDB"].setDefault("HLT1") + # Set up environment variables for loading CALIBOFF layers, must be before loading any tags + LoadCALIBDB = self.getProp('LoadCALIBDB') + loadcaliboptions = ["HLT1", "OFFLINE"] + if LoadCALIBDB not in loadcaliboptions: + raise ValueError("'%s' is not a valid LoadCALIBDB value. Allowed: %s" %(LoadCALIBDB, loadcaliboptions)) + if LoadCALIBDB is "OFFLINE" and not exists(join(os.environ["SQLITEDBPATH"], "CALIBOFF.db")): + LoadCALIBDB = "HLT1" # When CALIBOFF.db is not there, reset the option + os.environ['LoadCALIBDB'] = LoadCALIBDB + + # Set the usage of the latest global/local tags + old_latest_Tags_prop = self.getProp("UseLatestTags") # it is deprecated + latest_GTags_prop = self.getProp("LatestGlobalTagByDataTypes") + if not latest_GTags_prop: # if property not set + latest_GTags_prop = self.getProp("LatestGlobalTagByDataType") + latest_LTags_prop = self.getProp("LatestLocalTagsByDataType") + all_LTags_prop = self.getProp("AllLocalTagsByDataType") + + if old_latest_Tags_prop: + if latest_GTags_prop or latest_LTags_prop: + log.warning("The property 'UseLatestTags' is deprecated:" + "'LatestGlobalTagByDataType(s)' and 'LatestLocalTagsByDataType'" + " will be used instead.") + else: + latest_GTags_prop = old_latest_Tags_prop[0] + if type(old_latest_Tags_prop[-1]) != bool or \ + (type(old_latest_Tags_prop[-1]) == bool and not old_latest_Tags_prop[1]): + latest_LTags_prop = old_latest_Tags_prop[0] + + if latest_GTags_prop: + datatype = latest_GTags_prop + if self.getProp("Tags"): + self.Tags = {} + self._useLatestTags(datatype, OnlyGlobalTags = True) + log.warning("Default global tags will be overridden with the latest ones" + " available for '%s' data type: %s"%(datatype, self.getProp("Tags")) ) + + if latest_LTags_prop: + datatypes = latest_LTags_prop + #if self.getProp("LocalTags"): + # self.LocalTags = {} + self._useLatestTags(datatypes, OnlyLocalTags = True) + log.warning("Latest unbound local tags on top of the latest global tags" + " of %s data type(s) are added: %s" + %(datatypes, self.getProp("LocalTags"))) + + if all_LTags_prop: + datatypes = all_LTags_prop + self._useAllLocalTags(datatypes) + log.warning("ALL local tags of %s data type(s) are added: %s" + %(datatypes, self.getProp("LocalTags"))) + + # Import SQLDDDB specific info + if self.getProp("UseOracle"): + CondDBAccessSvc("ONLINE", ConnectionString = "CondDBOnline/ONLINE") + if self.getProp("DisableLFC"): + COOLConfSvc(UseLFCReplicaSvc = False) + elif self.getProp('UseDBSnapshot'): + CondDBAccessSvc("ONLINE") + else: + configureOnlineSnapshots() +# importOptions("$SQLDDDBROOT/options/SQLDDDB.py") + + ######################################################################### + # Access to ConditionsDB + ########################################################################## + conns = self.getProp("PartitionConnectionString") + tags = self.getProp("Tags") + # DB partitions + partition = {} + parttypes = [ ("DDDB", CondDBAccessSvc), + ("LHCBCOND", CondDBAccessSvc), + ("ONLINE", CondDBTimeSwitchSvc), + ("SIMCOND", CondDBAccessSvc), + ("DQFLAGS", CondDBAccessSvc)] + if LoadCALIBDB is "OFFLINE": + # CALIBOFF not needed for the upgrade + parttypes += [("CALIBOFF", CondDBAccessSvc)] + + for (p ,t) in parttypes: + partition[p] = getAnyDBReader(p, t) + # Override connection strings: + if p in conns: + if type(partition[p]) is CondDBAccessSvc: + partition[p].ConnectionString = conns[p] + del conns[p] + + # Override connection strings for Upgrade case + if self.getProp('Simulation') and self.getProp('Upgrade') and type(partition[p]) is CondDBAccessSvc: + partition[p].ConnectionString = os.path.join('sqlite_file:$SQLITEUPGRADEDBPATH', p + '.db', p) + # Override tags + if p in tags and p != "ONLINE": + partition[p].DefaultTAG = tags[p] + del tags[p] + # Set the query granularity + if p != "CALIBOFF": self.propagateProperty("QueryGranularity", partition[p]) + if type(partition[p]) is CondDBTimeSwitchSvc: # also online + for r in partition[p].Readers: + config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] + if isinstance(config, CondDBAccessSvc): + self.propagateProperty("QueryGranularity", config) + # Pass along the configuration for the layered DBs + elif isinstance(config, CondDBLayeringSvc): + for ly in config.Layers: + if isinstance(ly, CondDBAccessSvc): + self.propagateProperty("QueryGranularity", ly) + + if conns: + log.warning("Cannot override the connection strings of the partitions %r", conns.keys()) + if tags and tags.keys()!=['ONLINE']: + log.warning("Cannot set the tag for partitions %r", tags.keys()) + + # In the Online environment, IgnoreHeartBeat should be defaulted to True + if self.getProp("Online"): + self._properties["IgnoreHeartBeat"].setDefault(True) + if not self.getProp("IgnoreHeartBeat"): + if isinstance(partition["ONLINE"], CondDBAccessSvc): + self.propagateProperty("HeartBeatCondition", partition["ONLINE"]) + elif isinstance(partition["ONLINE"], CondDBTimeSwitchSvc): + # Add the heart beat conditions to the latest snapshot only since the + # others are limited but valid by construction. + if partition["ONLINE"].Readers: + latest = partition["ONLINE"].Readers[-1] + config = allConfigurables[eval(latest.split(':')[0]).split("/")[1]] + if isinstance(config, CondDBAccessSvc): + self.propagateProperty("HeartBeatCondition", config) + # Pass along the configuration for the layered DBs + elif isinstance(config, CondDBLayeringSvc): + for ly in config.Layers: + #Only apply HeartBeatCondition for ONLINE + if isinstance(ly, CondDBAccessSvc) and ly.getName().startswith("ONLINE_"): + self.propagateProperty("HeartBeatCondition", ly) + + if not self.getProp("Simulation"): + # Standard configurations + # - Reconstruction / analysis + disp = CondDBDispatcherSvc("MainCondDBReader", + MainAccessSvc = partition["DDDB"], + Alternatives = { + "/Conditions": partition["LHCBCOND"], + "/Conditions/Online": partition["ONLINE"], + "/Conditions/DQ": partition["DQFLAGS"] + }) + else: + # - Simulation + disp = CondDBDispatcherSvc("SimulationCondDBReader", + MainAccessSvc = partition["DDDB"], + Alternatives = { + "/Conditions": partition["SIMCOND"] + }) + CondDBCnvSvc( CondDBReader = disp ) + + if not (self.getProp("Online") or self.getProp("Simulation")): + self._properties["EnableRunStampCheck"].setDefault(True) + if self.getProp("EnableRunStampCheck"): + from Configurables import RunStampCheck + rsc = RunStampCheck() + self.propagateProperty("RunStampCondition", rsc) + ApplicationMgr().ExtSvc.append(rsc) + + # Load the CALIBOFF layer above everything if it exists +# if len([x for x in parttypes if x[0] == 'CALIBOFF']): +# self._addLayer(getAnyDBReader('CALIBOFF')) + + localTags = self.getProp("LocalTags") + not_applied = [] + for p in localTags: + if p in partition: + taglist = list(localTags[p]) + taglist.reverse() # we need to stack the in reverse order to use the first as on top of the others + i = 0 # counter + if p is "CALIBOFF": + if LoadCALIBDB is not "OFFLINE": + raise ValueError("invalid argument LoadCALIBDB set at '%s' instead of 'OFFLINE' for accessing local tags for CALIBOFF.db" % LoadCALIBDB) + pcolayers = [] + for t in taglist: + pcolayers.append(partition[p].clone("CALIBOFF_%d" %i, DefaultTAG = t)) + i += 1 + for r in partition["ONLINE"].Readers: + config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] + if isinstance(config, CondDBLayeringSvc): + config.Layers = pcolayers + config.Layers + elif type(partition[p]) is not CondDBTimeSwitchSvc: + for t in taglist: + self._addLayer(partition[p].clone("%s_%d" % (p, i), + DefaultTAG = t)) + i += 1 + else: + not_applied.append(p) + else: + not_applied.append(p) + if not_applied: + log.warning("Cannot set the local tags for partitions %r", not_applied) + + # Modify partitions to use local copies of the DBs + # before adding user layers and alternatives, which should be already local. + # This is a no-operation if the property is not set + self.__make_sqlite_local_copy__(CondDBCnvSvc()) + + # Add layers and alternatives + call = { self.LAYER : self._addLayer, + self.ALTERNATIVE : self._addAlternative } + for override in self.getProp("Overrides"): + apply(call[override[0]], override[1:]) + + # Add the logger + filename = self.getProp("LogFile") + if filename: + cnvSvc = allConfigurables["CondDBCnvSvc"] + cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader, + LogFile = filename) + + # Suppress pointless warning from COOL_2_5_0 + msgSvc = getConfigurable("MessageSvc") + msgSvc.setError.append("RelationalDatabase") + + # Set up Virtual File System service, can be used by ParticlePropertySvc + from Gaudi.Configuration import VFSSvc + from Configurables import CondDBEntityResolver + VFSSvc().FileAccessTools.append(CondDBEntityResolver()) + + +# Exported symbols +__all__ = [ "addCondDBLayer", "addCondDBAlternative", "useCondDBLogger", + "configureOnlineSnapshots" ] +# Configurables provided by the package +__all__ += [ "CondDBAccessSvc", + "CondDBDispatcherSvc", "CondDBLayeringSvc", "CondDBTimeSwitchSvc", + "CondDBSQLiteCopyAccSvc", "CondDBLogger", + "CondDBCnvSvc", + "CondDB" ] + +# List of known implementations of ICondDBReader (str is used for backward compatibility) +__CondDBReaders__ = [ CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc, + str ] + +def _assertConfig(funcname): + """ + Check if the default configuration has been loaded. + """ + if "CondDBCnvSvc" not in allConfigurables: + raise RuntimeError("You cannot call '%s' before the standard CondDB configuration"%funcname) + +def addCondDBLayer(accessSvc): + """ + Add the given CondDBReader as a layer on top of the existing configuration. + + Example: + addCondDBLayer(myDB) + """ + DetCond().addLayer(accessSvc) + +def addCondDBAlternative(accessSvc, path): + """ + Add the given CondDBReader as an alternative to the existing configuration + for the specified path. + + Example: + addCondDBAlternative(myDB,"/Conditions/MyDetector/Alignment") + """ + DetCond().addAlternative(accessSvc, path) + +def useCondDBLogger(filename = None, logger = None): + """ + Add the CondDBLogger to the chain of CondDBReaders. + + The simplest usage is to call the function without options (use defaults), or + pass a file name. + """ + _assertConfig('useCondDBLogger') + cnvSvc = allConfigurables["CondDBCnvSvc"] + if logger is None: + # use the default configuration + cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader) + elif type(logger) is CondDBLogger: + # use the user-provided configurable + logger.LoggedReader = cnvSvc.CondDBReader + cnvSvc.CondDBReader = logger + else: + raise TypeError("useCondDBLogger does not support '%s'"%logger.__class__.__name__) + # Use the user specified filename, if any + if filename: + cnvSvc.CondDBReader.LogFile = filename + +def _timegm(t): + """Inverse of time.gmtime. Implementation from Gaudi::Time.""" + import time + if t[8] != 0: # ensure that dst is not set + t = tuple(list(t[0:8]) + [0]) + t1 = time.mktime(t) + gt = time.gmtime(t1) + t2 = time.mktime(gt) + return t1 + (t1 - t2) + +def defConnStrFunc(ym_tuple): + return self.connStrOnline(ym_tuple) + +def connStrOnline(ym_tuple): + dbpath = os.environ["SQLITEDBPATH"] + if exists(join(dbpath, "ONLINE-%04d%02d.db" % ym_tuple)): + return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d%02d.db/ONLINE" % ym_tuple + return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d.db/ONLINE" % ym_tuple[0] + +def getAnyDBReader(layer = 'CALIBOFF', svc = CondDBAccessSvc): + CacheHighLevel = 200 + if layer == 'DDDB' : CacheHighLevel = 1700 + # Put the discovered layer on top + cfg = getConfigurable(layer, svc) + if svc is not CondDBAccessSvc: return cfg + try: cfg.ConnectionString + except AttributeError: # Set up connection for the 1st time + connstr = "sqlite_file:$SQLITEDBPATH/%s.db/%s" % (layer, layer) + if layer == 'DQFLAGS' : + cfg = CondDBAccessSvc(layer, ConnectionString = connstr, + CacheLowLevel = 5, CacheHighLevel = 10) + else: + cfg = CondDBAccessSvc(layer, ConnectionString = connstr, + CacheHighLevel = CacheHighLevel) + return cfg + +def getOnlineDBReader(ym_tuple, granularity = 'YEARLY', connStrFunc = None): + cnstr = '' + ymstr = '' + if granularity == 'YEARLY': + ymstr = "%04d" %ym_tuple[0] + cnstr = connStrFunc((ym_tuple[0],13)) + else: + ymstr = "%04d%02d" %ym_tuple + cnstr = connStrFunc(ym_tuple) + + ptnm = "ONLINE_" + ymstr + accSvc = CondDBAccessSvc(ptnm, ConnectionString = cnstr) + dblayers = [ accSvc ] + LoadCALIBDB = os.environ.get('LoadCALIBDB') + if ym_tuple[0] < 2015 or LoadCALIBDB is not "OFFLINE": # For datatype before 2015, no CALIBOFF layer is needed + return accSvc + dbpath = os.environ["SQLITEDBPATH"] + layer = 'CALIBOFF' + if exists(join(dbpath, layer + '.db')): + # Put the discovered layer on top + cfg = getConfigurable(layer, CondDBAccessSvc) + try: cfg.ConnectionString + except AttributeError: # Set up connection for the 1st time + cfg = CondDBAccessSvc("CALIBOFF", ConnectionString = + cnstr.replace('ONLINE-%s.db/ONLINE' %ymstr, "%s.db/%s" % (layer, layer)), CacheHighLevel = 200) + dblayers.insert(0, cfg) + + if (len(dblayers) == 1): return accSvc # In case no CALIBOFF.db is found + return CondDBLayeringSvc("ONLINELAYER_"+ymstr, Layers = dblayers ) + +def configureOnlineSnapshots(start = None, end = None, connStrFunc = None): + if connStrFunc is None: + connStrFunc = connStrOnline + + # prepare the configurable instance + ONLINE = CondDBTimeSwitchSvc("ONLINE") + + # Default snapshots granularity + granularity = 'YEARLY' + + # Set the first available snapshot pair: per-year by default + if start is None: + first_snapshot = (2008, None) + else: + first_snapshot = start + + # Set the last available snapshot pair: current year by default + if end is None: + import time + last_snapshot = (time.gmtime()[0], None) + else: + last_snapshot = end + + # If last snapshot is per-month switch the first one to be also per-month + if last_snapshot[1]: + granularity = 'MONTHLY' + first_snapshot = (2008, 6) + + # reset the list of readers, for safety + ONLINE.Readers = [] + # loop from first to last-1 + i = first_snapshot + until = 0 # this makes the first service used from times starting from 0 + while i < last_snapshot: + accSvc = getOnlineDBReader(i, granularity, connStrFunc) + since = until + # increment + if granularity == 'YEARLY': + i = (i[0]+1, None) + until = int(_timegm(tuple([i[0], 1, 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 + else: + if i[1] == 12: i = (i[0]+1,1) + else: i = (i[0],i[1]+1) + until = int(_timegm(tuple([i[0], i[1], 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 + descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) + ONLINE.Readers.append(descr) + + # append the last database with validity extended to the maximum validity + accSvc = getOnlineDBReader(i, granularity, connStrFunc) + since = until + until = 0x7fffffffffffffffL # Defined in PyCool.cool as ValidityKeyMax + descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) + ONLINE.Readers.append(descr) diff --git a/Det/DetCond/python/DetCond/HistoCond.py b/Det/DetCond/python/DetCond/HistoCond.py new file mode 100644 index 000000000..c89d49911 --- /dev/null +++ b/Det/DetCond/python/DetCond/HistoCond.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# ============================================================================= +## @file DetCond/HistoCond.py +# Decorate the Condition object with functions to extract 1d and 2d-histograms +# @authorVanya BELYAEV Ivan.Belyaev@nikhef.nl +# @date 2009-12-01 +# ============================================================================= +""" +Decorate the Condition object with functions to extract 1d and 2d-histograms, and +define functions to convert 1d and 2d histograms to Condition parameter strings. +""" +# ============================================================================= +__author__ = "Vanya BELYAEV Ivan.Belyaev@nikhef.nl and Dmitry Golubkov" +__version__ = "CVS Tag $Name: not supported by cvs2svn $, verison $Revision: 1.1 $" +# ============================================================================= +# export nothing +__all__ = () ## export nothing +# ============================================================================= + +## import HistoStrings.Histos +from GaudiPython.Bindings import gbl as cpp + +_C = cpp.Condition +# ============================================================================= +## function to convert 1D histogram to an xml param string +def histo1DAsParam ( h1d, name = 'name', comment = 'comment' ) : + """ + Convert 1D histogram to an xml param string + """ + param_head = '\n <param name = "%s" type = "Histo1D" comment="%s">\n' + param_tail = '\n </param>\n' + + return param_head % (name, comment) + h1d.toString() + param_tail +# ============================================================================= +## function to convert 2D histogram to an xml param string +def histo2DAsParam ( h2d, name = 'name', comment = 'comment' ) : + """ + Convert 2D histogram to an xml param string + """ + param_head = '\n <param name = "%s" type = "Histo2D" comment="%s">\n' + param_tail = '\n </param>\n' + + return param_head % (name, comment) + h2d.toString() + param_tail +# ============================================================================= +## decorate the condition object: +if not hasattr ( _C , 'paramAsH1' ) : + + _F1 = cpp.DetDesc.Params.paramAsHisto1D + + # ========================================================================= + ## Extract the 1D-histogram form condition objects + # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + # @date 2009-12-01 + def _paramAsH1_ ( self , name ) : + """ + Extract the 1D-histiogram from condition objects + + >>> cond = ... ## get the condition object + >>> name = ... ## the name + + >>> h1 = cond.paramAsH1 ( name ) + >>> h1 = cond.paramAsHisto1D ( name ) # same as Condition.paramAsH1 + """ + return _F1 ( self , name ) + + _paramAsH1_ . __doc__ += '\n' + _F1 . __doc__ + _C .paramAsH1 = _paramAsH1_ + _C .paramAsHisto1D = _paramAsH1_ + +# ============================================================================= +## decorate the condition object: +if not hasattr ( _C , 'paramAsH2' ) : + + _F2 = cpp.DetDesc.Params.paramAsHisto2D + + # ========================================================================= + ## Extract the 2D-histogram form condition objects + # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + # @date 2009-12-01 + def _paramAsH2_ ( self , name ) : + """ + Extract the 2D-histiogram from condition objects + + >>> cond = ... ## get the condition object + >>> name = ... ## the name + + >>> h2 = cond.paramAsH2 ( name ) + >>> h2 = cond.paramAsHisto2D ( name ) # same as Condition.paramAsH2() + """ + return _F2 ( self , name ) + + _paramAsH2_ . __doc__ += '\n' + _F2 . __doc__ + _C .paramAsH2 = _paramAsH2_ + _C .paramAsHisto2D = _paramAsH2_ + +if '__main__' == __name__ : + + print __doc__ + print __author__ + print __version__ + +# ============================================================================= +# The END +# ============================================================================= diff --git a/Det/DetCond/python/DetCond/__init__.py b/Det/DetCond/python/DetCond/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Det/DetCond/src/Lib/CondDBGenericCnv.cpp b/Det/DetCond/src/Lib/CondDBGenericCnv.cpp new file mode 100755 index 000000000..b83b90922 --- /dev/null +++ b/Det/DetCond/src/Lib/CondDBGenericCnv.cpp @@ -0,0 +1,139 @@ +// Include files +#include "GaudiKernel/IDetDataSvc.h" +#include "GaudiKernel/Time.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/IValidity.h" +#include "GaudiKernel/DataObject.h" + +#include "DetDesc/IDetectorElement.h" +#include "DetDesc/ValidDataObject.h" + +#include "CoolKernel/ValidityKey.h" +#include "CoolKernel/IFolder.h" +#include "CoolKernel/IObject.h" +#include "CoolKernel/IDatabase.h" +#include "CoolKernel/Exception.h" + +// local +#include "DetCond/CondDBGenericCnv.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBGenericCnv +// +// 2004-12-03 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBGenericCnv::CondDBGenericCnv(ISvcLocator* svc,const CLID& clid): + Converter(CONDDB_StorageType,clid,svc) +{} +//============================================================================= +// Destructor +//============================================================================= +CondDBGenericCnv::~CondDBGenericCnv() = default; + +//========================================================================= +// Initialization +//========================================================================= +StatusCode CondDBGenericCnv::initialize() { + // Initializes the grand father + StatusCode sc = Converter::initialize(); + + // Query the IDetDataSvc interface of the detector data service + m_detDataSvc = serviceLocator()->service("DetectorDataSvc"); + if( !sc.isSuccess() ) { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + log << MSG::ERROR << "Can't locate DetectorDataSvc" << endmsg; + return sc; + } else { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Succesfully located DetectorDataSvc" << endmsg; + } + // Get a pointer to the CondDBReader (implemented by the conversion service) + m_condDBReader.reset( conversionSvc().get() ); + if ( !m_condDBReader ) { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + log << MSG::ERROR << "The conversion service does not implement ICondDBReader!" << endmsg; + return StatusCode::FAILURE; + } + + return sc; +} + +//========================================================================= +// Finalization +//========================================================================= +StatusCode CondDBGenericCnv::finalize() { + m_detDataSvc.reset(); + m_condDBReader.reset(); + return Converter::finalize(); +} + +//========================================================================= +// Ask the event time to the DetectorDataSvc +//========================================================================= + +StatusCode CondDBGenericCnv::eventTime(Gaudi::Time &time) const { + if (!m_detDataSvc->validEventTime()){ + return StatusCode::FAILURE; + } + time = m_detDataSvc->eventTime(); + return StatusCode::SUCCESS; +} + +//========================================================================= +// Set the validity of the object +//========================================================================= +void CondDBGenericCnv::setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject){ + // Set validity of created object + IValidity* pValidity = dynamic_cast<IValidity*>(pObject); + + if ( pValidity != NULL ) { // it has a validity + + pValidity->setValidity(since, till); + + } else { + + // I cannot set the validity range + MsgStream log(msgSvc(),"CondDBGenericCnv"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG + << "Created object (CLID = " << pObject->clID() + << ") does not implement IValidity: cannot set validity" + << endmsg; + } +} + +//========================================================================= +// get an object from the conditions database +//========================================================================= +StatusCode CondDBGenericCnv::getObject (const std::string &path, const cool::ChannelId &channel, + ICondDBReader::DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until) { + + Gaudi::Time now; + StatusCode sc = eventTime(now); + if (sc.isFailure()) { + MsgStream log(msgSvc(),"CondDBGenericCnv"); + log << MSG::ERROR << "Cannot create DataObject: event time undefined" << endmsg; + return sc; + } + + return m_condDBReader->getObject(path,now,data,descr,since,until,channel); +} + +//========================================================================= +// get get the list of nodes in a folderset from the conditions database +//========================================================================= +StatusCode CondDBGenericCnv::getChildNodes(const std::string &path,std::vector<std::string> &node_names){ + MsgStream log(msgSvc(),"CondDBGenericCnv"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; + + return m_condDBReader->getChildNodes(path,node_names); +} +//============================================================================= + diff --git a/Det/DetCond/src/component/COOLConfSvc.cpp b/Det/DetCond/src/component/COOLConfSvc.cpp new file mode 100755 index 000000000..384a0b8f0 --- /dev/null +++ b/Det/DetCond/src/component/COOLConfSvc.cpp @@ -0,0 +1,281 @@ +#ifdef __INTEL_COMPILER // Disable ICC remark from CORAL MessageStream and Boost + #pragma warning(disable:2259) +#endif + +// Include files +#include "RelationalAccess/ConnectionService.h" +#include "RelationalAccess/IConnectionServiceConfiguration.h" +#include "RelationalAccess/IReplicaSortingAlgorithm.h" +#include "RelationalAccess/IDatabaseServiceDescription.h" + +#include "CoolKernel/IDatabaseSvc.h" +#include "CoolApplication/Application.h" +#include "CoolApplication/DatabaseSvcFactory.h" + +#include "COOLConfSvc.h" + +#ifdef WIN32 +#define NOMSG +#define NOGDI +#endif + +// For the case insensitive string comparison (boost::algorithm::icontains). +#include "boost/algorithm/string/predicate.hpp" +// For random numbers not affecting simulation. +#include "boost/random/linear_congruential.hpp" +//#include "boost/random/uniform_smallint.hpp" +#include "boost/date_time/posix_time/posix_time_types.hpp" + +namespace +{ + + /** @class ReplicaSortAlg + * + * Small class implementing coral::IReplicaSortingAlgorithm interface to allow dynamic sorting of + * database replicas obtained from LFC. + * + * When retrieving the list of DB replicas, LFCReplicaService obtains a list in an arbitrary order. + * We have to provide to CORAL a class to be used to sort the list of replicas according to our + * needs. First we want the closest DB, identified by the environment variable LHCBPRODSITE, then + * the CERN server (LCG.CERN.ch), while the remaining one can be in any order (this implementation + * uses the natural string ordering). + * + * @author Marco Clemencic + * @date 2007-05-02 + */ + class ReplicaSortAlg: virtual public coral::IReplicaSortingAlgorithm + { + typedef coral::IDatabaseServiceDescription dbDesc_t; + typedef std::vector< const dbDesc_t * > replicaSet_t; + + /** @class ReplicaSortAlg::Comparator + * + * Comparison function defining which replica comes before another. + * + * This class is used via the STL algorithm "sort" to order the list the way we need it. + * + * @author Marco Clemencic + * @date 2007-05-02 + */ + class Comparator: public std::binary_function<const dbDesc_t*,const dbDesc_t*,bool> + { + typedef boost::rand48 RandomGenType; + typedef RandomGenType::result_type WeightType; + typedef std::map<std::string,WeightType> WeightMap; + + /// Site that have to be used before the others + std::string site; + /// Map used to remember the priority of the sites. + /// the local site has weight -1, the other are randomly chosen the first + /// time they are encountered. + mutable WeightMap weights; + /// Random number generator. Using Boost to avoid interactions with the + /// random generator services. + mutable RandomGenType gen; + + WeightType getWeight(const std::string& key) const { + WeightMap::iterator i = weights.find(key); + if ( weights.end() == i ) { // not found + WeightType newWeight = 0; + if (boost::algorithm::icontains(key,site)) { + // it means that this is the site with highest priority + newWeight = gen.max(); + } else { + // all other sites are distributed randomly + newWeight = gen(); + } + weights[key] = newWeight; + return newWeight; + } + return i->second; + } + + public: + + /// Constructor. + /// @param theSite the local LHCb Production Site (<i>SITE</i>.<i>country</i>) + Comparator(std::string theSite): + site(std::move(theSite)), + gen(// this is the rather longish Boost way of getting the current number of + // seconds since the beginning of the day... that I want to use as seed + // for the local random number generator (I do not use "seconds since epoch" + // because the boosted way of getting it is too long). + boost::posix_time::second_clock::universal_time().time_of_day().total_seconds()) + {} + + /// Main function + result_type operator() (first_argument_type a, second_argument_type b) const + { + return getWeight(a->serviceParameter(a->serverNameParam())) + < + getWeight(b->serviceParameter(b->serverNameParam())); + } + + }; + + std::string localSite; + MsgStream log; + + public: + + /// Constructor. + /// @param theSite the local LHCb Production Site (LCG.<i>SITE</i>.<i>country</i>) + ReplicaSortAlg(std::string theSite, IMessageSvc *msgSvc): + localSite(std::move(theSite)), + log(msgSvc,"ReplicaSortAlg") + { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Constructor" << endmsg; + } + + /// Destructor. + virtual ~ReplicaSortAlg() + { + // log << MSG::VERBOSE << "ReplicaSortAlg --> destructor" <<std::endl; + } + + /// Main function + virtual void sort (std::vector< const coral::IDatabaseServiceDescription * > &replicaSet) + { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { + log << MSG::VERBOSE << "Original list" << endmsg; + replicaSet_t::iterator i; + for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { + log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; + } + + log << MSG::VERBOSE << "Sorting..." << endmsg; + } + std::sort(replicaSet.begin(),replicaSet.end(),Comparator(localSite)); + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { + log << MSG::VERBOSE << "Sorted list" << endmsg; + replicaSet_t::iterator i; + for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { + log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; + } + } + } + + }; + +} + +// Factory implementation +DECLARE_SERVICE_FACTORY(COOLConfSvc) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +COOLConfSvc::COOLConfSvc(const std::string& name, ISvcLocator* svcloc): + base_class(name,svcloc) +{ + declareProperty("UseLFCReplicaSvc", m_useLFCReplicaSvc = false ); + declareProperty("LocalSite", m_localSite = "", + "The name of the site we are running on, used to order the " + "list of replicas in LFC."); + declareProperty("EnableCoralConnectionCleanUp", m_coralConnCleanUp = false ); + declareProperty("CoralConnectionRetrialPeriod", m_retrialPeriod = 60, + "Time between two connection trials (in seconds)."); + declareProperty("CoralConnectionRetrialTimeOut", m_retrialTimeOut = 15*60, + "How long to keep retrying before giving up (in seconds)."); +} +//============================================================================= +// Destructor +//============================================================================= +COOLConfSvc::~COOLConfSvc() {} + +//============================================================================= +// Access to COOL DatabaseSvc +//============================================================================= +cool::IDatabaseSvc& COOLConfSvc::databaseSvc() { + return coolApplication()->databaseService(); +} + +//============================================================================= +// Access to SEAL Context +//============================================================================= +coral::IConnectionService& COOLConfSvc::connectionSvc() { + return coolApplication()->connectionSvc(); +} + +//============================================================================= +// initialize +//============================================================================= +StatusCode COOLConfSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if ( ! m_coolApplication.get() ) { + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initializing COOL Application" << endmsg; + m_coolApplication.reset(new cool::Application); + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Getting CORAL Connection Service configurator" << endmsg; + coral::IConnectionServiceConfiguration &connSvcConf = + m_coolApplication->connectionSvc().configuration(); + + if ( m_useLFCReplicaSvc ) { + + log << MSG::INFO << "Using CORAL LFCReplicaService" << endmsg; + connSvcConf.setLookupService( "CORAL/Services/LFCReplicaService" ); + connSvcConf.setAuthenticationService( "CORAL/Services/LFCReplicaService" ); + + if ( m_localSite.empty() ) { + // if we didn't get a site from options, we try the environment var DIRACSITE + m_localSite = System::getEnv("DIRACSITE"); + if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { + // if DIRACSITE is not defined, we try, for backward compatibility, LHCBPRODSITE + m_localSite = System::getEnv("LHCBPRODSITE"); + if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { + // if none of the env. vars is set, let's stick to a "sensible" default + m_localSite = "CERN.ch"; + } + } + } + log << MSG::INFO << "Using '" << m_localSite << "' as preferred site" << endmsg; + + m_replicaSortAlg.reset(new ReplicaSortAlg(m_localSite,msgSvc())); + connSvcConf.setReplicaSortingAlgorithm(*m_replicaSortAlg); + } + + if ( ! m_coralConnCleanUp ) { + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Disabling CORAL connection automatic clean up" << endmsg; + connSvcConf.disablePoolAutomaticCleanUp(); + connSvcConf.setConnectionTimeOut( 0 ); + + } + + connSvcConf.setConnectionRetrialPeriod(m_retrialPeriod); + log << MSG::INFO << "CORAL Connection Retrial Period set to " + << connSvcConf.connectionRetrialPeriod() << "s" << endmsg; + + connSvcConf.setConnectionRetrialTimeOut(m_retrialTimeOut); + log << MSG::INFO << "CORAL Connection Retrial Time-Out set to " + << connSvcConf.connectionRetrialTimeOut() << "s" << endmsg; + + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode COOLConfSvc::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + m_coolApplication.reset(); + m_replicaSortAlg.reset(); + return base_class::finalize(); +} diff --git a/Det/DetCond/src/component/COOLConfSvc.h b/Det/DetCond/src/component/COOLConfSvc.h new file mode 100755 index 000000000..6de60e7cb --- /dev/null +++ b/Det/DetCond/src/component/COOLConfSvc.h @@ -0,0 +1,94 @@ +#ifndef COMPONENT_COOLCONFSVC_H +#define COMPONENT_COOLCONFSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "GaudiKernel/GaudiException.h" +#include "DetCond/ICOOLConfSvc.h" + +// Forward declarations +template <class TYPE> class SvcFactory; + +namespace cool { + class Application; + class RecordSpecification; +} +namespace coral { + class IReplicaSortingAlgorithm; +} + +/** @class COOLConfSvc COOLConfSvc.h + * + * Class used as interface to LCG COOL library API. It should expose as less as + * possible COOL internal details. + * + * @author Marco Clemencic + * @date 2005-01-11 + */ + +class COOLConfSvc: public extends1<Service, ICOOLConfSvc> { +public: + /// Initialize COOL (CondDB) Configuration Service + virtual StatusCode initialize(); + + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICOOLConfSvc implementation + /// Access to the CORAL connection service used by COOL (if needed). + virtual coral::IConnectionService& connectionSvc(); + + /// Get the COOL Database service (used to connect to the databases). + virtual cool::IDatabaseSvc& databaseSvc(); + +protected: + /// Standard constructor + COOLConfSvc(const std::string& name, ISvcLocator* svcloc); + + virtual ~COOLConfSvc( ); ///< Destructor + +private: + + inline cool::Application *coolApplication(){ + if (!m_coolApplication.get()) + throw GaudiException("Attempt to access COOL instance before initialization", + "(COOLConfSvc)" + name() + "::coolApplication", + StatusCode::FAILURE); + return m_coolApplication.get(); + } + + /// Pointer to a shared instance of the COOL Application + std::unique_ptr<cool::Application> m_coolApplication; + + std::unique_ptr<coral::IReplicaSortingAlgorithm> m_replicaSortAlg; + + /// Flag to turn off/on the CORAL LFCReplicaService (option UseLFCReplicaSvc, default = false). + /// Setting this option works only if it is set for the first COOLConfSvc initialized + /// because of a "feature" of CORAL. + bool m_useLFCReplicaSvc; + + /// Name of the grid site the application is running on. It is meaningful only + /// if m_useLFCReplicaSvc (option UseLFCReplicaSvc) is set to true. If not + /// specified the value of the environment variables "DIRACSITE" or + /// "LHCBPRODSITE" is used. If even the environment variables are not set, + /// then it is assumed to be "CERN.ch". (Note: the value is case insensitive) + std::string m_localSite; + + /// Flag to turn off/on the CORAL Automatinc connection clean up + /// (option EnableCoralConnectionCleanUp, default = false). + /// Setting this option works only if it is set for the first COOLConfSvc initialized. + bool m_coralConnCleanUp; + + /// Time between two connection trials (in seconds). + /// Passed to CORAL when loaded. + int m_retrialPeriod; + + /// How long to keep retrying before giving up (in seconds). + /// Passed to CORAL when loaded. + int m_retrialTimeOut; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<COOLConfSvc>; + +}; +#endif // COMPONENT_COOLCONFSVC_H diff --git a/Det/DetCond/src/component/CondDBAccessSvc.cpp b/Det/DetCond/src/component/CondDBAccessSvc.cpp new file mode 100755 index 000000000..d8d75e653 --- /dev/null +++ b/Det/DetCond/src/component/CondDBAccessSvc.cpp @@ -0,0 +1,1492 @@ +// Include files +#include <sstream> +//#include <cstdlib> +//#include <ctime> + + +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +#include "GaudiKernel/IRndmGenSvc.h" +#include "GaudiKernel/IRndmEngine.h" + +#include "CoolKernel/DatabaseId.h" +#include "CoolKernel/IDatabaseSvc.h" +#include "CoolKernel/IFolder.h" +#include "CoolKernel/IFolderSet.h" +#include "CoolKernel/IObject.h" +#include "CoolKernel/IObjectIterator.h" +#include "CoolKernel/Exception.h" +#include "CoolKernel/RecordSpecification.h" +#include "CoolKernel/FolderSpecification.h" +#include "CoolKernel/StorageType.h" +#include "CoolKernel/Record.h" + +#include "CoralBase/AttributeList.h" +#include "CoralBase/Exception.h" +// FIXME: Needed because of COOL bug #38422 +#include "CoralBase/AttributeException.h" + +#include "DetCond/ICOOLConfSvc.h" + +// local +#include "CondDBAccessSvc.h" +#include "CondDBCache.h" + +#include "CondDBCommon.h" +#include "IOVListHelpers.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBAccessSvc) + +// Utility function +namespace { + template <class EXC> + inline void report_exception(MsgStream &log, const std::string &msg, const EXC& e){ + log << MSG::ERROR << msg << endmsg; + log << MSG::ERROR << System::typeinfoName(typeid(e)) << ": " + << e.what() << endmsg; + } +} + +#include "GaudiKernel/Sleep.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBAccessSvc +// +// 2005-01-11 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBAccessSvc::CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc): + base_class(name,svcloc), + m_coolConfSvc(0), + m_cache(0), + m_rndmSvc(0), + m_latestHeartBeat(0) +{ + declareProperty("ConnectionString", m_connectionString = "" ); + declareProperty("DefaultTAG", m_dbTAG = "" ); + declareProperty("NoDB", m_noDB = false ); + declareProperty("UseCache", m_useCache = true ); + declareProperty("CacheLowLevel", m_cacheLL = 10 ); + declareProperty("CacheHighLevel", m_cacheHL = 100 ); + //declareProperty("CachePreload", m_cachePreload=3600*1E9); // ns + declareProperty("CheckTAGTrials", m_checkTagTrials = 1 ); + declareProperty("CheckTAGTimeOut", m_checkTagTimeOut = 60 ); + declareProperty("ReadOnly", m_readonly = true ); + + declareProperty("ConnectionTimeOut", m_connectionTimeOutProp = 120 ); + + declareProperty("LazyConnect", m_lazyConnect = true ); + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); + declareProperty("HeartBeatCondition", m_heartBeatCondition = ""); + + declareProperty("QueryGranularity", m_queryGranularity = 0, + "Granularity of the query in the database (in time units), " + "to allow bulk retrievals."); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBAccessSvc::~CondDBAccessSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBAccessSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if (m_connectionTimeOutProp) { + m_connectionTimeOut = boost::posix_time::seconds(m_connectionTimeOutProp); + } else { + m_connectionTimeOut = boost::posix_time::pos_infin; + } + + if ( m_noDB && !m_useCache ) { + log << MSG::ERROR << "Database access disabled and cache off: I cannot work like that. Ciao!" << endmsg; + return StatusCode::FAILURE; + } + + if ( !m_noDB ) { + if ( connectionString() == "" ) { + // we need a connection string to connect to the DB + log << MSG::ERROR << "Connection to database requested and no connection string provided." << endmsg; + log << MSG::ERROR << "Set the option \"" << name() << ".ConnectionString\"." << endmsg; + return StatusCode::FAILURE; + } + + if ( ! m_lazyConnect ) { + sc = i_initializeConnection(); + if (!sc.isSuccess()) return sc; + } + + } + else { + log << MSG::INFO << "Database not requested: I'm not trying to connect" << endmsg; + } + + // set up cache if needed + if (m_useCache) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize CondDB cache." << endmsg; + m_cache = new CondDBCache(MsgStream(msgSvc(), name() + ".Cache"), + m_cacheHL, m_cacheLL); + if (m_cache == NULL) { + log << MSG::ERROR << "Unable to initialize CondDB cache." << endmsg; + return StatusCode::FAILURE; + } + // when we do bulk retrievals it is normal to have overlaps when inserting objects + // into the cache + m_cache->setSilentConflicts(m_queryGranularity > 0); + + } else { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "CondDB cache not needed" << endmsg; + m_cache = NULL; + } + if ( m_xmlDirectMapping && ! m_useCache ) { + // @todo: make it possible to use the direct mapping without cache + log << MSG::FATAL << "Cannot use direct XML mapping without cache (YET)" << endmsg; + return StatusCode::FAILURE; + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { + if (!m_heartBeatCondition.empty()) { + log << MSG::DEBUG << "Using heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; + } + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBAccessSvc::finalize(){ + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(), name() ); + log << MSG::DEBUG << "Finalize" << endmsg; + } + + // stop TimeOut thread + i_stopTimeoutChecker(); + + // release the database + m_db.reset(); + if (m_useCache) { + // dump the content of the cache + m_cache->dump(); + // dispose of the cache manager + delete m_cache; + } + if ( m_rndmSvc ) m_rndmSvc->release(); + + return base_class::finalize(); +} + +//============================================================================= +// Connect to the database +//============================================================================= +StatusCode CondDBAccessSvc::i_initializeConnection(){ + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(), name() ); + log << MSG::DEBUG << "Connection string = \"" << connectionString() << "\"" << endmsg; + } + + StatusCode sc = i_openConnection(); + if (!sc.isSuccess()) return sc; + + // start TimeOut thread + i_startTimeoutChecker(); + + return i_validateDefaultTag(); +} + +//============================================================================= +// Connect to the database +//============================================================================= +StatusCode CondDBAccessSvc::i_openConnection(){ + MsgStream log(msgSvc(), name() ); + + try { + if (! m_db) { // The database is not yet opened + + if ( !m_coolConfSvc ) { + StatusCode sc = service("COOLConfSvc",m_coolConfSvc,true); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot get COOLConfSvc" << endmsg; + return sc; + } + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Get cool::DatabaseSvc" << endmsg; + cool::IDatabaseSvc &dbSvc = m_coolConfSvc->databaseSvc(); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { + log << MSG::DEBUG << "cool::DatabaseSvc got" << endmsg; + log << MSG::DEBUG << "Opening connection" << endmsg; + } + m_db = dbSvc.openDatabase(connectionString(),m_readonly); + + } + else { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Database connection already established!" << endmsg; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieve the root folderset." << endmsg; + m_rootFolderSet = m_db->getFolderSet("/"); + } + // catch ( cool::DatabaseDoesNotExist &e ) { + catch ( coral::Exception &e ) { + report_exception(log,"Problems opening database",e); + m_db.reset(); + return StatusCode::FAILURE; + } + catch ( cool::Exception &e ) { + report_exception(log,"Problems opening database",e); + m_db.reset(); + return StatusCode::FAILURE; + } + + touchLastAccess(); + log << MSG::INFO << "Connected to database \"" << connectionString() << "\"" << endmsg; + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::i_validateDefaultTag() { + MsgStream log(msgSvc(), name() ); + + // Check the existence of the provided tag. + StatusCode sc = i_checkTag(); + + // Try again if requested + int trials_to_go = m_checkTagTrials - 1; // take into account the trial just done + while (!sc.isSuccess() && (trials_to_go > 0)){ + log << MSG::INFO << "TAG \"" << tag() << "\" not ready, I try again in " << m_checkTagTimeOut << "s. " + << trials_to_go << " trials left." << endmsg; + Gaudi::Sleep(m_checkTagTimeOut); + sc = i_checkTag(); + --trials_to_go; + } + + // Fail if the tag is not found + if (!sc.isSuccess()){ + log << MSG::ERROR << "Bad TAG given: \"" << tag() << "\" not in the database" << endmsg; + return sc; + } + log << MSG::INFO << "Using TAG \"" << tag() << "\"" << endmsg; + return StatusCode::SUCCESS; +} +//============================================================================= +// TAG handling +//============================================================================= +const std::string &CondDBAccessSvc::tag() const { return m_dbTAG; } +StatusCode CondDBAccessSvc::setTag(const std::string &_tag){ + + if (m_dbTAG == _tag) return StatusCode::SUCCESS; // no need to change + + StatusCode sc = i_checkTag(_tag); + if ( sc.isSuccess() ) { + m_dbTAG = _tag; + // the cache must be cleared if the tag is changed + clearCache(); + MsgStream log(msgSvc(), name() ); + log << MSG::WARNING << "TAG changed to \"" << _tag << "\"" << endmsg; + } else { + MsgStream log(msgSvc(), name() ); + log << MSG::WARNING << "Unable to set TAG \"" << _tag + << "\": not in the DB. (Still using \"" << tag() << "\")" << endmsg; + } + return sc; +} +StatusCode CondDBAccessSvc::i_checkTag(const std::string &tag) const { + + MsgStream log(msgSvc(), name() ); + if ( !m_db ) { + log << MSG::ERROR << "Check tag \"" << tag + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Check availability of tag \"" << tag << "\"" << endmsg; + /// @TODO: check all sub-nodes to validate the tag and not only the root + if (m_rootFolderSet) { + // HEAD tags are always good + //if ( (tag.empty()) || (tag == "HEAD") ) return StatusCode::SUCCESS; + if ( cool::IHvsNode::isHeadTag(tag) ) { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "\"" << tag << "\" is a HEAD tag: OK" << endmsg; + return StatusCode::SUCCESS; + } + // try to resolve the tag (it cannot be checked) + try { + try { + m_rootFolderSet->resolveTag(tag); + } catch (cool::NodeRelationNotFound) { + // to be ignored: it means that the tag exists, but somewhere else. + } catch (coral::AttributeException) { // FIXME: COOL bug #38422 + // to be ignored: it means that the tag exists, but somewhere else. + } + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "\"" << tag << "\" found: OK" << endmsg; + return StatusCode::SUCCESS; + } catch (cool::TagNotFound &) { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "\"" << tag << "\" NOT found" << endmsg; + return StatusCode::FAILURE; + } + catch (cool::TagRelationNotFound &e) { + log << MSG::ERROR << "got a cool::TagRelationNotFound : " << e.what() << endmsg; + return StatusCode::FAILURE; + } + catch (std::exception &e) { + report_exception(log,"got exception",e); + return StatusCode::FAILURE; + } + + } + return StatusCode::FAILURE; +} + + +//============================================================================= +// Return the connection string used to connect to the database. +//============================================================================= +const std::string &CondDBAccessSvc::connectionString() const{ + return m_connectionString; +} + +//============================================================================= +// Utilities +//============================================================================= +StatusCode CondDBAccessSvc::createNode(const std::string &path, + const std::string &descr, + StorageType storage, + VersionMode vers) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot create node in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + try { + switch (storage) { + case FOLDERSET: + m_db->createFolderSet(path,descr,true); + break; + case XML: + { + cool::FolderSpecification spec((vers == SINGLE) + ?cool::FolderVersioning::SINGLE_VERSION + :cool::FolderVersioning::MULTI_VERSION, + CondDB::getXMLStorageSpec()); + + // append to the description the storage type + std::ostringstream _descr; + _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + m_db->createFolder(path, + spec, + _descr.str(), + true); + } + break; + default: + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": unknown StorageType" << endmsg; + return StatusCode::FAILURE; + } + } catch(cool::NodeExists &){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the node already exists" << endmsg; + return StatusCode::FAILURE; + } catch(cool::Exception &e){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::createNode(const std::string &path, + const std::string &descr, + const std::set<std::string> &fields, + StorageType storage, + VersionMode vers) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot create node in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + try { + switch (storage) { + case FOLDERSET: + m_db->createFolderSet(path,descr,true); + break; + case XML: + { + cool::RecordSpecification recSpec; + for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ + recSpec.extend(*f, cool::StorageType::String16M); + } + cool::FolderSpecification spec((vers == SINGLE) + ?cool::FolderVersioning::SINGLE_VERSION + :cool::FolderVersioning::MULTI_VERSION, + recSpec); + + // append to the description the storage type + std::ostringstream _descr; + _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + m_db->createFolder(path, + spec, + _descr.str(), + true); + } + break; + default: + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": unknown StorageType" << endmsg; + return StatusCode::FAILURE; + } + } catch(cool::NodeExists &){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\": the node already exists" << endmsg; + return StatusCode::FAILURE; + } catch(cool::Exception &e){ + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to create the folder \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot store in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the object \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + try { + // retrieve folder pointer + cool::IFolderPtr folder = m_db->getFolder(path); + cool::Record payload(folder->payloadSpecification()); + payload["data"].setValue<cool::String16M>(data); + folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); + + } catch (cool::FolderNotFound &) { + + MsgStream log(msgSvc(), name() ); + if (m_db->existsFolderSet(path)) + log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << + path << '\"' << endmsg; + else + log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + + } catch (cool::Exception &e){ + + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the XML string into \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { + if ( m_readonly ) { + MsgStream log(msgSvc(), name() ); + log << "Cannot store in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the object \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + try { + // retrieve folder pointer + cool::IFolderPtr folder = m_db->getFolder(path); + cool::Record payload(folder->payloadSpecification()); + for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ + payload[d->first].setValue<cool::String16M>(d->second); + } + + folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); + + } catch (cool::FolderNotFound &) { + + MsgStream log(msgSvc(), name() ); + if (m_db->existsFolderSet(path)) + log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << + path << '\"' << endmsg; + else + log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + + } catch (cool::Exception &e){ + + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Unable to store the XML string into \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + + } + return StatusCode::SUCCESS; +} + +cool::ValidityKey CondDBAccessSvc::timeToValKey(const Gaudi::Time &time) const { + // ValidityKey is an uInt64 of which only 63 bits used (0 -> 9223372036854775807), + // while time.ns() is a positive signed Int64! (the same thing) + return time.ns(); +} + +Gaudi::Time CondDBAccessSvc::valKeyToTime(const cool::ValidityKey &key) const { + return Gaudi::Time(key); +} + +StatusCode CondDBAccessSvc::tagLeafNode(const std::string &path, const std::string &tagName, + const std::string &description) { + MsgStream log(msgSvc(),name()); + + if ( m_readonly ) { + log << "Cannot tag in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + log << MSG::ERROR << "Unable to tag the leaf node \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + DataBaseOperationLock dbLock(this); + try { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering tagLeafNode: \"" << path << '"' << endmsg; + + cool::IFolderPtr folder = m_db->getFolder(path); + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION){ + log << MSG::WARNING << "Not tagging leaf node \"" << path << "\": single-version" << endmsg; + } else { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Tagging leaf node \"" << path << "\": " << tagName << endmsg; + folder->tagCurrentHead(tagName, description); + } + + } catch (cool::FolderNotFound &) { + + if (m_db->existsFolderSet(path)) + log << MSG::ERROR << "Node \"" << path << "\" is not leaf." << endmsg; + else + log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + + } catch (cool::Exception &e){ + + log << MSG::ERROR << "Unable tag leaf node \"" << path + << "\" (cool::Exception): " << e.what() << endmsg; + return StatusCode::FAILURE; + + } + + return StatusCode::SUCCESS; +} + +std::string CondDBAccessSvc::generateUniqueTagName(const std::string &base, + const std::set<std::string> &reserved) const { + + if ( !m_db->isOpen() ) { + throw GaudiException("Database not open","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); + } + if ( ! m_rndmSvc ) { + IRndmGenSvc *svc; + StatusCode sc = service("RndmGenSvc",svc,true); + const_cast<CondDBAccessSvc*>(this)->m_rndmSvc = svc; + if ( ! sc.isSuccess() ) { + throw GaudiException("Cannot get a pointer to RndmGenSvc","CondDBAccessSvc::generateUniqueTagName",sc); + } + } + + std::string tag = ""; + do { + // start with the signature + tag = "_auto_"; + // add the base, if any + if (!base.empty()) tag += base + "-"; + // append 6 randomly chosen chars in set [0-9A-Za-z] + for ( int i = 0; i<6; ++i ) { + char c=(char) ( 62.0 * m_rndmSvc->engine()->rndm() ); + if ( c > 61 ) GaudiException("Generator failure","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); // c %= 62; + if ( c >= 36 ) tag += c + 61; + else if ( c >= 10 ) tag += c + 55; + else tag += c + 48; + } + // check if the random name already exists or is reserved + } while ( m_db->existsTag(tag) || (reserved.find(tag) != reserved.end()) ); + + return tag; +} + + +StatusCode CondDBAccessSvc::recursiveTag(const std::string &path, const std::string &tagName, + const std::string &description) { + std::set<std::string> reserved; + DataBaseOperationLock dbLock(this); + return i_recursiveTag(path,tagName,description,tagName,reserved); +} + +StatusCode CondDBAccessSvc::i_recursiveTag(const std::string &path, const std::string &base, + const std::string &description, + const std::string &tagName, + std::set<std::string> &reserved) { + MsgStream log(msgSvc(),name()); + + if ( m_readonly ) { + log << MSG::ERROR << "Cannot tag in read-only mode" << endmsg; + return StatusCode::FAILURE; + } + if ( !m_db ) { + log << MSG::ERROR << "Unable to tag the inner node \"" << path + << "\": the database is not opened!" << endmsg; + return StatusCode::FAILURE; + } + + try { + // start reserving the tag name we want to apply to the current folderset + reserved.insert(tagName); + + // get the list of child nodes (both types) + cool::IFolderSetPtr this_folderset = m_db->getFolderSet(path); + std::vector<std::string> folders = this_folderset->listFolders(); + std::vector<std::string> foldersets = this_folderset->listFolderSets(); + + // loop over leaf nodes and apply the tags + std::vector<std::string>::iterator f; + for ( f = folders.begin(); f != folders.end(); ++f ) { + + std::string auto_tag = generateUniqueTagName(base,reserved); + cool::IFolderPtr child_folder = m_db->getFolder(*f); + + if (child_folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION) { + // only multi-version folders can be tagged + child_folder->tagCurrentHead(auto_tag, description); + // associate the child folder tag with the parent one + child_folder->createTagRelation(tagName, auto_tag); + } + + } + + // loop over inner nodes and recurse + for ( f = foldersets.begin(); f != foldersets.end(); ++f ) { + + std::string auto_tag = generateUniqueTagName(base,reserved); + StatusCode sc = i_recursiveTag(*f,base,description,auto_tag,reserved); + if (!sc.isSuccess()) return sc; + + cool::IFolderSetPtr child_folderset = m_db->getFolderSet(*f); + child_folderset->createTagRelation(tagName, auto_tag); + + } + } + catch (cool::FolderSetNotFound &) { + if (m_db->existsFolder(path)) + log << MSG::ERROR << "Node \"" << path << "\" is a leaf." << endmsg; + else + log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; + return StatusCode::FAILURE; + } + catch (cool::Exception &e) { + log << MSG::ERROR << "Problems tagging" << endmsg; + log << MSG::ERROR << e.what() << endmsg; + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + cool::ChannelId channel){ + return i_getObject(path, when, data, descr, since, until, + true, channel, ""); +} + +StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + const std::string &channel){ + return i_getObject(path, when, data, descr, since, until, + false, 0, channel); +} +/* +namespace { + ICondDBReader::IOVList getHoles(const ICondDBReader::IOV& iov, const ICondDBReader::IOVList& data){ + typedef ICondDBReader::IOVList IOVList; + typedef ICondDBReader::IOV IOV; + IOVList result; + + Gaudi::Time last = iov.since; // keep track of the end of coverage + // loop over covering interval + for (IOVList::const_iterator covered = data.begin(); covered != data.end(); ++covered) { + if (covered->since > last) { // hole between the end of coverage and begin of next IOV + result.push_back(IOV(last, covered->since)); + } + last = covered->until; // prepare to look for the next hole + } + if (last < iov.until) { + // we didn't get anything to cover until the end of the requested IOV + result.push_back(IOV(last, iov.until)); + } + + return result; + } +} +*/ + +ICondDBReader::IOVList CondDBAccessSvc::i_getIOVsFromDB(const std::string & path, const IOV &iov, cool::ChannelId channel) { + ICondDBReader::IOVList result; + try { + DataBaseOperationLock dbLock(this); + // we want a folder, so go to the database to get it + cool::IFolderPtr folder = database()->getFolder(path); + cool::IObjectIteratorPtr objects; + + // FIXME: we need to considered the query granularity + // Note: IFolder::browseObject returns the objects valid up to the 'until' + // included, which means that asking for [1,10] will return also the + // object starting at 10, so, to exclude it we need to ask for [1,9]. + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION + || tag().empty() || tag() == "HEAD" ){ + objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel); + } else { + objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel, folder->resolveTag(tag())); + } + + if (!objects->isEmpty()) {// check if we managed to find anything + while (objects->goToNext()) { + // add data to the cache while filling the list of IOVs + const cool::IObject &obj = objects->currentRef(); + m_cache->insert(folder, obj, channel); + result.push_back(ICondDBReader::IOV(Gaudi::Time(obj.since()), Gaudi::Time(obj.until()))); + } + } + } catch(cool::FolderNotFound &/*e*/) { + // ignore + } catch (cool::TagRelationNotFound &/*e*/) { + // ignore + } catch (cool::NodeRelationNotFound &) { + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + } + return result; +} + +ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + typedef ICondDBReader::IOVList IOVList; + IOVList result; + if (m_useCache){ + /// Look for holes in the timeline of the cache + result = m_cache->getIOVs(path, iov, channel); + IOVList holes = IOVListHelpers::find_holes(result, iov); + for(IOVList::iterator hole = holes.begin(); hole != holes.end(); ++hole) { + const IOVList cover = i_getIOVsFromDB(path, *hole, channel); + result.insert(result.end(), cover.begin(), cover.end()); + } + std::sort(result.begin(), result.end()); + } else { + result = i_getIOVsFromDB(path, iov, channel); + } + return result; +} + +ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + cool::ChannelId id; + if (m_useCache){ + // Check if the cache knows about the path + if (m_cache->hasPath(path)) { + // the folder is in the cache + if (m_cache->getChannelId(path, channel, id)) { + return getIOVs(path, iov, id); // we know about the folder and the channel + } else { + return ICondDBReader::IOVList(); // we know about the folder, but not about the channel + } + } + } + + // the folder is not in the cache or we do not use the cache, so we have to + // get the channel id from the DB + try { + DataBaseOperationLock dbLock(this); + cool::IFolderPtr folder = database()->getFolder(path); + id = folder->channelId(channel); + } catch(cool::FolderNotFound &/*e*/) { + return ICondDBReader::IOVList(); // unknown folder + } catch(cool::InvalidChannelName &/*e*/) { + return ICondDBReader::IOVList(); // unknown channel + } + return getIOVs(path, iov, id); +} + +StatusCode CondDBAccessSvc::i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, + DataPtr &data, + std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, + bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ + try { + + bool existsFolderSet = false; + { + DataBaseOperationLock dbLock(this); + existsFolderSet = database()->existsFolderSet(path); + } + // Check if the user asked for a folderset + if (existsFolderSet) { + if ( !m_xmlDirectMapping ) { + // with FolderSets, I put an empty entry and clear the shared_ptr + if (m_useCache) m_cache->addFolderSet(path,""); + data.reset(); + } else { + // Using XML direct mapping, foldersets are replaced in the cache + // with the XML equivalent (a catalog). + i_generateXMLCatalogFromFolderset(path); + // now get the data from the cache + m_cache->get(path,when,channel,since,until,descr,data); + } + + return StatusCode::SUCCESS; + } + else { + // Special retrieval procedure if we use "query granularity" (make sense + // only when using the cache). + if (m_useCache && m_queryGranularity > 0){ + // modify the range rounding it to the requested granularity (if needed) + // Range used for the query + cool::ValidityKey sinceWhen = when, untilWhen = when; + + sinceWhen -= when % m_queryGranularity; + untilWhen = sinceWhen + m_queryGranularity; + + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(),name()); + log << MSG::DEBUG << "Retrieving conditions in range " + << sinceWhen << " - " << untilWhen << endmsg; + } + + DataBaseOperationLock dbLock(this); + // we want a folder, so go to the database to get it + cool::IFolderPtr folder = database()->getFolder(path); + cool::IObjectIteratorPtr objects; + if ( !use_numeric_chid ) { // we need to convert from name to id + channel = folder->channelId(channelstr); + } + + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION + || tag().empty() || tag() == "HEAD" ){ + objects = folder->browseObjects(sinceWhen, untilWhen, channel); + } else { + objects = folder->browseObjects(sinceWhen, untilWhen, channel, folder->resolveTag(tag())); + } + + if (objects->isEmpty()) // check if we managed to find anything + return StatusCode::FAILURE; + + while (objects->goToNext()) { + m_cache->insert(folder, objects->currentRef(), channel); + } + // now get the data from the cache + m_cache->get(path, when, channel, since, until, descr, data); + + } else { // no-cache or no granularity are quite similar + + DataBaseOperationLock dbLock(this); + // we want a folder, so go to the database to get it + cool::IFolderPtr folder = database()->getFolder(path); + cool::IObjectPtr object; + if ( !use_numeric_chid ) { // we need to convert from name to id + channel = folder->channelId(channelstr); + } + + if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION + || tag().empty() || tag() == "HEAD" ){ + object = folder->findObject(when, channel); + } else { + object = folder->findObject(when, channel, folder->resolveTag(tag())); + } + + if (m_useCache) { + // add the object to the cache + m_cache->insert(folder, *object, channel); + // and get the data back + m_cache->get(path, when, channel, since, until, descr, data); + } else { + data = DataPtr(new cool::Record(object->payload())); + descr = folder->description(); + since = object->since(); + until = object->until(); + } + } + } + } catch ( cool::FolderNotFound &/*e*/) { + //log << MSG::ERROR << e << endmsg; + return StatusCode::FAILURE; + } catch (cool::TagRelationNotFound &/*e*/) { + return StatusCode::FAILURE; + } catch (cool::ObjectNotFound &/*e*/) { + //log << MSG::ERROR << "Object not found in \"" << path << + // "\" for tag \"" << (*accSvc)->tag() << "\" ("<< now << ')' << endmsg; + //log << MSG::DEBUG << e << endmsg; + return StatusCode::FAILURE; + } catch (cool::NodeRelationNotFound &) { + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + return StatusCode::FAILURE; + } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 + // to be ignored: it means that the tag exists, but it is not in the + // node '/'. + return StatusCode::FAILURE; + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + return StatusCode::SUCCESS; +} + +StatusCode CondDBAccessSvc::i_getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ + + cool::ValidityKey vk_when = timeToValKey(when); + cool::ValidityKey vk_since = 0, vk_until = 0; + + // This is not in i_getObjectFromDB because I need to ensure that m_latestHeartBeat + // is correctly set even when using the cache. + if (vk_when >= i_latestHeartBeat()) { + MsgStream log(msgSvc(), name()); + const Gaudi::Time hb = valKeyToTime(i_latestHeartBeat()); + log << MSG::ERROR << "Database not up-to-date. Latest known update is at " + << hb.format(false, "%Y-%m-%d %H:%M:%S") << "." << hb.nanoformat() + << " UTC, event time is " + << when.format(false, "%Y-%m-%d %H:%M:%S") << "." << when.nanoformat() + << " UTC" << endmsg; + return StatusCode::FAILURE; + } + + if (m_useCache) { + + // Check if the cache knows about the path + if ( m_cache->hasPath(path) ) { + + // the folder is in the cache + if ( !use_numeric_chid ) { // we need to convert from name to id + if (!m_cache->getChannelId(path,channelstr,channel)) { + // the channel name cannot be found in the cached folder + return StatusCode::FAILURE; + } + } + + if ( m_cache->get(path,vk_when,channel,vk_since,vk_until,descr,data) ) { + since = valKeyToTime(vk_since); + /// Artificially cutting the end of validity of the retrieved object to + /// the latest know heart beat guarantees that we will have to go back + /// to the database when the event time exceeds it. + /// Note that we are not calling i_latestHeartBeat() on purpose: + /// it returns +inf if called during initialize, but it sets + /// correctly the variable m_latestHeartBeat. + until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); + return StatusCode::SUCCESS; + } + } + + } + // If we get here, either we do not know about the folder, we didn't + // find the object, or we are not using the cache, so let's try the DB + if (m_noDB) { + // oops... we are not using the db: no way of getting the object from it + return StatusCode::FAILURE; + } + + StatusCode sc = i_getObjectFromDB(path,vk_when,data,descr,vk_since,vk_until,use_numeric_chid,channel,channelstr); + since = valKeyToTime(vk_since); + /// Artificially cutting the end of validity of the retrieved object to + /// the latest know heart beat guarantees that we will have to go back + /// to the database when the event time exceeds it. + /// Note that we are not calling i_latestHeartBeat() on purpose: + /// it returns +inf if called during initialize, but it sets + /// correctly the variable m_latestHeartBeat. + until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); + return sc; +} + +namespace { + // Small helper function to reduce duplications + inline void cannotGetHeartBeatError(CondDBAccessSvc *self, const std::string&path) { + MsgStream log(self->msgSvc(), self->name()); + log << MSG::ERROR << "Cannot get latest heart beat (" << path + << ") in the database" << endmsg; + } +} +const cool::ValidityKey& CondDBAccessSvc::i_latestHeartBeat() +{ + if (m_latestHeartBeat == 0) { + if (m_heartBeatCondition.empty() || + m_noDB) { // it doesn't make sense to ask for a heart beat if we do not use the DB + // no heart beat condition: the database is always valid + m_latestHeartBeat = cool::ValidityKeyMax; + } else { + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(),name()); + log << MSG::DEBUG << "Retrieving heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; + } + // we do not use the normal functions to retrieve the object because + // we want to by-pass the cache + try { + DataBaseOperationLock dbLock(this); + cool::IFolderPtr folder = database()->getFolder(m_heartBeatCondition); + cool::IObjectPtr obj = folder->findObject(cool::ValidityKeyMax-1, 0); + m_latestHeartBeat = obj->since(); + } + catch (cool::Exception &) { + cannotGetHeartBeatError(this, m_heartBeatCondition); + m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database + } + catch (coral::Exception &) { + cannotGetHeartBeatError(this, m_heartBeatCondition); + m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database + } + if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(),name()); + log << MSG::DEBUG << "Latest heart beat at " << m_latestHeartBeat << endmsg; + } + } + } + if (FSMState() != Gaudi::StateMachine::RUNNING) { + // Temporarily consider the database valid if not running + // (e.g. during initialize). + // Note that the retrieve is done (and must be done) anyway, + // because it is needed by i_getObject(). + return cool::ValidityKeyMax; + } + return m_latestHeartBeat; +} + + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) { + MsgStream log(msgSvc(),name()); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; + + folders.clear(); + foldersets.clear(); + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + if (database()->existsFolderSet(path)) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "FolderSet \"" << path << "\" exists" << endmsg; + + cool::IFolderSetPtr folderSet = database()->getFolderSet(path); + + std::vector<std::string> fldr_names = folderSet->listFolders(); + std::vector<std::string> fldrset_names = folderSet->listFolderSets(); + + for ( std::vector<std::string>::iterator f = fldr_names.begin(); f != fldr_names.end(); ++f ) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << *f << endmsg; + // Check if folder is tagged with a tag set to load db with. + cool::IFolderPtr folder = database()->getFolder(*f); + if (folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION){ + try{ + folder->resolveTag(tag()); + folders.push_back(f->substr(f->rfind('/')+1)); + } catch (cool::TagRelationNotFound &) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Tag '" << tag() + << "' relation was not found for ': "<< *f << "' folder" << endmsg; + } catch (cool::ReservedHeadTag &) { + //to be ignored: 'HEAD' tag is in every node + folders.push_back(f->substr(f->rfind('/')+1)); + } catch (cool::NodeRelationNotFound &) { + //to be ignored: it means that the tag exists, but it is not in the node '/'. + } catch (coral::AttributeException &) { // FIXME: COOL bug #38422. To be ignored: + //it means that the tag exists, but it is not in the node '/'. + } catch (coral::Exception &e) { + report_exception(log,"got CORAL exception",e); + folders.push_back(f->substr(f->rfind('/')+1)); + } + } else { //add folder if it is single version without tag verification + folders.push_back(f->substr(f->rfind('/')+1)); + } + } + + for ( std::vector<std::string>::iterator f = fldrset_names.begin(); f != fldrset_names.end(); ++f ) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << *f << endmsg; + foldersets.push_back(f->substr(f->rfind('/')+1)); + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { + log << MSG::DEBUG << "got " << folders.size() << " sub folders" << endmsg; + log << MSG::DEBUG << "got " << foldersets.size() << " sub foldersets" << endmsg; + } + + } else { + // cannot get the sub-nodes of a folder! + return StatusCode::FAILURE; + } + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + m_cache->getSubNodes(path,folders,foldersets); + } else { + // no cache and no db + return StatusCode::FAILURE; + } + } catch ( cool::FolderNotFound &/*e*/) { + //log << MSG::ERROR << e << endmsg; + return StatusCode::FAILURE; + } catch (coral::Exception &e) { + report_exception(log,"got CORAL exception",e); + } + return StatusCode::SUCCESS; + + +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { + + std::vector<std::string> temp; + StatusCode sc = getChildNodes(path, node_names, temp); + if (sc.isSuccess()) + node_names.insert(node_names.end(), temp.begin(), temp.end()); + return sc; + +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBAccessSvc::exists(const std::string &path) { + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + return database()->existsFolderSet(path) || database()->existsFolder(path); + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + return m_cache->hasPath(path); + } + + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + // if we do not have neither DB nor cache, or we got an exception + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBAccessSvc::isFolder(const std::string &path) { + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + return database()->existsFolder(path); + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + return m_cache->isFolder(path); + } + + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + // if we do not have neither DB nor cache, or we got an exception + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBAccessSvc::isFolderSet(const std::string &path) { + + try { + + if (!m_noDB) { // If I have the DB I always use it! + DataBaseOperationLock dbLock(this); + return database()->existsFolderSet(path); + } else if (m_useCache) { + // if no db, but cache, let's assume we know everything is in there + return m_cache->isFolderSet(path); + } + + } catch (coral::Exception &e) { + MsgStream log(msgSvc(),name()); + report_exception(log,"got CORAL exception",e); + } + // if we do not have neither DB nor cache, or we got an exception + return false; +} + +//========================================================================= +// Disconnect from the database. +//========================================================================= +void CondDBAccessSvc::disconnect() { + boost::mutex::scoped_lock busy_lock(m_busy); + if ( database() && database()->isOpen() ) { + if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { + debug() << "Forced disconnect from database (will reconnect automatically)" << endmsg; + } + database()->closeDatabase(); + } else if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { + debug() << "Database already disconnected" << endmsg; + } + i_stopTimeoutChecker(); +} + +//========================================================================= +// Add database name and TAG to the passed vector. +//========================================================================= +void CondDBAccessSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + /// @todo This should be something like + /// <quote> + /// tags.push_back(LHCb::CondDBNameTagPair(database()->dbName(),tag())); + /// </quote> + /// but COOL API does not provide that function yet. (Available since 2.2.0) + + std::string dbName; + // Parsing of COOL connection string to find database name + // - first type: <tech>://<server>;schema=<schema>;dbname=<dbname> + std::string::size_type pos = connectionString().find("dbname="); + if ( std::string::npos != pos ) { + pos += 7; + std::string::size_type pos2 = connectionString().find(';',pos); + if ( std::string::npos != pos2 ) + dbName = connectionString().substr(pos,pos2-pos); + else + dbName = connectionString().substr(pos); + } else { + // - second type: <alias>/<dbname> + pos = connectionString().find_last_of('/'); + if ( std::string::npos != pos ) { + dbName = connectionString().substr(pos+1); + } else { + throw GaudiException("Cannot understand COOL connection string", + "CondDBAccessSvc::defaultTags",StatusCode::FAILURE); + } + } + // If the tag is a "HEAD" tag, I want to show "HEAD" + std::string tagName = tag(); + if (cool::IHvsNode::isHeadTag(tagName)) { + tagName = "HEAD"; + } + + tags.push_back(LHCb::CondDBNameTagPair(dbName,tagName)); + +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec) { + if (!m_useCache) { + MsgStream log(msgSvc(),name()); + log << MSG::ERROR << "Cache not in use: I cannot add a folder to it." << endmsg; + return StatusCode::FAILURE; + } + return m_cache->addFolder(path,descr,spec) ? StatusCode::SUCCESS : StatusCode::FAILURE; +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddFolderSet(const std::string &path, const std::string &descr) { + if (!m_useCache) { + MsgStream log(msgSvc(),name()); + log << MSG::ERROR << "Cache not in use: I cannot add a folder-set to it." << endmsg; + return StatusCode::FAILURE; + } + return m_cache->addFolderSet(path,descr) ? StatusCode::SUCCESS : StatusCode::FAILURE; +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path) { + std::ostringstream _descr; + _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + return cacheAddFolder(path,_descr.str(),CondDB::getXMLStorageSpec()); +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) { + std::ostringstream _descr; + _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; + cool::RecordSpecification spec; + for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ + spec.extend(*f, cool::StorageType::String16M); + } + return cacheAddFolder(path,_descr.str(),spec); +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const cool::IRecord& payload, cool::ChannelId channel) { + if (!m_useCache) { + MsgStream log(msgSvc(),name()); + log << MSG::ERROR << "Cache not in use: I cannot add an object to it." << endmsg; + return StatusCode::FAILURE; + } + return m_cache->addObject(path,timeToValKey(since),timeToValKey(until),payload,channel) + ? StatusCode::SUCCESS + : StatusCode::FAILURE; +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string &data, cool::ChannelId channel) { + /// @todo this is affected by the evolution in COOL API + cool::Record payload(CondDB::getXMLStorageSpec()); + payload["data"].setValue<cool::String16M>(data); + return cacheAddObject(path,since,until,payload,channel); +} + +//========================================================================= +// +//========================================================================= +StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::map<std::string,std::string> &data, cool::ChannelId channel) { + cool::RecordSpecification spec; + for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ + spec.extend(d->first,cool::StorageType::String16M); + } + + cool::Record payload(spec); + + for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ + payload[d->first].setValue<cool::String16M>(d->second); + } + return cacheAddObject(path,since,until,payload,channel); +} + +//========================================================================= +// +//========================================================================= +void CondDBAccessSvc::clearCache() +{ + if (m_useCache) { + m_cache->clear(); + } +} + +//========================================================================= +// +//========================================================================= +void CondDBAccessSvc::dumpCache() const { + if (m_useCache) m_cache->dump(); +} + +//========================================================================= +// +//========================================================================= +void CondDBAccessSvc::i_generateXMLCatalogFromFolderset(const std::string &path){ + // Use the name of the folderset as catalog name. + std::string::size_type pos = path.rfind('/'); + if ( std::string::npos == pos ) { + pos = 0; // if we cannot find '/' let's take the whole string + } else { + ++pos; + } + std::string folderset_name = path.substr(pos); + + // Get the names of sub-folders and sub-foldersets + std::vector<std::string> fldr_names, fldrset_names; + getChildNodes(path, fldr_names, fldrset_names).ignore(); + + std::string xml; + CondDB::generateXMLCatalog(folderset_name,fldr_names,fldrset_names,xml); + + // Put the data in the cache + if ( ! m_cache->hasPath(path) ) + cacheAddXMLFolder(path); + + // This is needed because we cannot add objects valid for the current event + // to the cache using the ICondDBAccessSvc API. + bool check_enabled = m_cache->setIOVCheck(false); + cacheAddXMLData(path,Gaudi::Time::epoch(),Gaudi::Time::max(),xml,0).ignore(); + m_cache->setIOVCheck(check_enabled); + +} diff --git a/Det/DetCond/src/component/CondDBAccessSvc.h b/Det/DetCond/src/component/CondDBAccessSvc.h new file mode 100755 index 000000000..34e578470 --- /dev/null +++ b/Det/DetCond/src/component/CondDBAccessSvc.h @@ -0,0 +1,506 @@ +#ifndef COMPONENT_CONDDBACCESSSVC_H +#define COMPONENT_CONDDBACCESSSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "GaudiKernel/GaudiException.h" +#include "Kernel/ICondDBInfo.h" +#include "DetCond/ICondDBAccessSvc.h" +#include "DetCond/ICondDBReader.h" +#include "DetCond/ICondDBEditor.h" +#include <set> + +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition.hpp> +#include <boost/thread/thread_time.hpp> + +#include "CoolKernel/IDatabase.h" + +// Forward declarations +template <class TYPE> class SvcFactory; + +class CondDBCache; +class IRndmGenSvc; +class ICOOLConfSvc; + +namespace cool { + class Application; + class RecordSpecification; +} + +/** @class CondDBAccessSvc CondDBAccessSvc.h + * + * Class used as interface to LCG COOL library API. It should expose as less as + * possible COOL internal details. + * + * @author Marco Clemencic + * @date 2005-01-11 + */ + +class CondDBAccessSvc: public extends3<Service, + ICondDBAccessSvc, + ICondDBReader, + ICondDBEditor> { +public: + + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + /// (Version with alphanumeric channel id) + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags ) const; + + // --------- ICondDBEditor implementation + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + StorageType storage = XML, + VersionMode vers = MULTI) const; + + /// Create a CondDB node in the hierarchy (Folder or FolderSet). + virtual StatusCode createNode(const std::string &path, + const std::string &descr, + const std::set<std::string> &fields, + StorageType storage = XML, + VersionMode vers = MULTI) const; + + /// Utility function that simplifies the storage of an XML string. + virtual StatusCode storeXMLData(const std::string &path, const std::string &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; + + /// Utility function that simplifies the storage of a set of XML strings. + virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, + const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; + + /// Tag the given leaf node with the given tag-name. + virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, + const std::string &description = ""); + + /// Tag the given inner node with the given tag-name, recursively tagging the head + /// of child nodes with automatically generated tag-names. + virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, + const std::string &description = ""); + + // --------- ICondDBAccessSvc implementation + + /// Used to obtain direct access to the database. + virtual cool::IDatabasePtr& database() { return m_db; } + + /// Convert from Gaudi::Time class to cool::ValidityKey. + virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const; + + /// Convert from cool::ValidityKey to Gaudi::Time class. + virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const; + + /// Return the currently set TAG to use. + virtual const std::string &tag() const; + + /// Set the TAG to use. + virtual StatusCode setTag(const std::string &_tag); + + /// Return the connection string used to connect to the database. + virtual const std::string &connectionString() const; + + /// Add a folder to the cache (bypass the DB) + virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec); + + /// Add a folder-set to the cache (bypass the DB) + virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr); + + /// Add a folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path); + + /// Add an XML folder to the cache (bypass the DB) + virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields); + + ///Add an object to the cache (bypass the DB) + virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const cool::IRecord& payload, cool::ChannelId channel = 0); + + ///Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::string& data, cool::ChannelId channel = 0); + + /// Add an XML object to the cache (bypass the DB) + virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, + const std::map<std::string,std::string> &data, cool::ChannelId channel = 0); + + /// Clear the cache + virtual void clearCache(); + + /// Dump the cache (debug) + virtual void dumpCache() const; + +protected: + /// Standard constructor + CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc); + + virtual ~CondDBAccessSvc( ); ///< Destructor + +protected: + // Properties + + /// Property CondDBAccessSvc.ConnectionString: full connection string to open database access. + /// Format is: "<BackEnd>://<HostName>;schema=<Schema>;dbname=<Database>;[user=<User>;][password=<Password>;]" + /// or "<HostAlias>/<Database>". + std::string m_connectionString; + +private: + /// Property CondDBAccessSvc.DefaultTAG: which tag to use if none is specified + std::string m_dbTAG; + + /** Property CondDBAccessSvc.UseCache: store the retrieved informations into a cache for faster + later access. */ + bool m_useCache; + + /// Property CondDBAccessSvc.CacheLowLevel: minimum fill of the cache. + size_t m_cacheLL; + + /// Property CondDBAccessSvc.CacheHighLevel: maximum fill of the cache. + size_t m_cacheHL; + + /// Property CondDBAccessSvc.NoDB: do not use the database (cache must be on). + bool m_noDB; + + /// Property CondDBAccessSvc.ReadOnly: open the database as read-only (default: true). + bool m_readonly; + + /// Property CondDBAccessSvc.CheckTAGTrials: Number of times to retry the check on the tag (default = 1). + int m_checkTagTrials; + + /// Property CondDBAccessSvc.CheckTAGTimeOut: Seconds to sleep between one trial and the following (default = 60). + int m_checkTagTimeOut; + + /// Pointer to the service initializing COOL/CORAL. + ICOOLConfSvc *m_coolConfSvc; + + /// Shared pointer to the COOL database instance + cool::IDatabasePtr m_db; + + /// Shared pointer to the COOL database instance + cool::IFolderSetPtr m_rootFolderSet; + + /// Pointer to the cache manager + CondDBCache *m_cache; + + /// Pointer to the random generator service + IRndmGenSvc *m_rndmSvc; + + /// Lazy connection flag. + /// If true (the default), the connection to (lazy = connect only when needed). + bool m_lazyConnect; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Path in the condition database (not in the transient store) to be used as + /// heart-beat marker. + /// The latest update of the condition specified give information about when + /// the replica was last updated: We cannot guarantee that the database is more + /// "up to date" then the "since" field of the latest object in the heart-beat + /// condition. + std::string m_heartBeatCondition; + + /// Latest know update of the database ("since" field of the latest heart-beat condition). + /// Initialized to 0, if no heart-beat condition is requested, it is set to + /// cool::ValidityKeyMax, otherwise, during the first access to the DB, the + /// object valid until ValidityKeyMax is retrieved and its "since" field is + /// recorded in this variable. + /// When disconnected from the database, it is reset to 0 to force a re-check. + cool::ValidityKey m_latestHeartBeat; + + // ---------------------------------------------- + // ---------- Private Member Functions ---------- + // ---------------------------------------------- + + /// Connect to the COOL database. It sets 'm_db'. + StatusCode i_initializeConnection(); + + /// Connect to the COOL database. It sets 'm_db'. + StatusCode i_openConnection(); + + /// Internal method to retrieve an object. + StatusCode i_getObject(const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, + bool use_numeric_chid, + cool::ChannelId channel, const std::string &channelstr); + + /// Internal method to retrieve an object from the database. + /// If the cache is activated, the result is copied there. + StatusCode i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, + DataPtr &data, + std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, + bool use_numeric_chid, + cool::ChannelId channel, const std::string &channelstr); + + /// Internal method to get the list of IOVs in a range. + /// @see ICondDBReader::getIOVs + IOVList i_getIOVsFromDB(const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + + void i_generateXMLCatalogFromFolderset(const std::string &path); + + /// Connect to the COOL database. It sets 'm_db'. + StatusCode i_validateDefaultTag(); + + /// Check if the TAG set exists in the DB. + inline StatusCode i_checkTag() const { return i_checkTag(tag()); } + + /// Check if the given TAG exists in the DB. + StatusCode i_checkTag(const std::string &tag) const; + + /// Generate a tag name that do not create conflicts in the DB. + /// Tagnames generated by this method will start with "_auto_". + /// If base value is passed to the method, the result will have + /// a "_auto_`base`-" prefix. + std::string generateUniqueTagName(const std::string &base, + const std::set<std::string> &reserved) const; + + /// Function used by recursiveTag to do the real work. + StatusCode i_recursiveTag(const std::string &path, + const std::string &base, + const std::string &description, + const std::string &tagName, + std::set<std::string> &reserved); + + + /// Return the value of m_latestHeartBeat. + /// The value is retrieved from the database when requested the first time + /// in the RUNNING state. + const cool::ValidityKey &i_latestHeartBeat(); + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBAccessSvc>; + + /// AttributeListSpecification used to sore XML strings + static std::unique_ptr<cool::RecordSpecification> s_XMLstorageSpec; + + /// Parameter controlling the granularity of the queries to the conditions database (in time units). + /// + /// When different from 0, instead of retrieving the only condition valid for the requested event time, + /// we will retrieve all the conditions valid for a range around the event time, rounded by the + /// granularity. + /// + /// For example, with granularity set to 1h and the event time 16:18:08, all the conditions valid for the + /// range 16:00:00 to 17:00:00 will be retrieved. + /// + /// \b Note: if the cache is not enabled the parameter has no effect. + cool::ValidityKey m_queryGranularity; + + // ------------------------------------- + // ---------- Time Out Thread ---------- + // ------------------------------------- + + /// Property CondDBAccessSvc.ConnectionTimeOut: How many seconds to keep the connection to the DB open after the + /// last access (default = 120, 0 means never). The connection will be started again if a new operation is performed. + int m_connectionTimeOutProp; + boost::posix_time::time_duration m_connectionTimeOut; + + /// Mutex to avoid conflicts between the main thread and the thread trying to close the connection. + boost::mutex m_busy; + + /// The time of last access. + boost::system_time m_lastAccess; + + /// Mutex to protect the last access time. + boost::mutex m_lastAccessMutex; + + /// Pointer to the second thread. + std::unique_ptr<boost::thread> m_timeOutCheckerThread; + + /// Function to set the last access time to "now". + inline void touchLastAccess() + { + boost::mutex::scoped_lock myLock(m_lastAccessMutex); + m_lastAccess = boost::get_system_time(); + } + + /// Get the last access time. + inline const boost::system_time &lastAccess() const + { + return m_lastAccess; + } + + /// Start the timeout checker thread, if requested. + inline void i_startTimeoutChecker() { + if ( UNLIKELY( (!m_timeOutCheckerThread) + && (!m_connectionTimeOut.is_pos_infinity()) ) ) { + m_timeOutCheckerThread.reset( new boost::thread(TimeOutChecker{this}) ); + } + } + + /// Stop the timeout checker thread if running. + inline void i_stopTimeoutChecker() { + if ( LIKELY( NULL != m_timeOutCheckerThread.get() ) ) { + m_timeOutCheckerThread->interrupt(); // tell the thread to stop + m_timeOutCheckerThread->join(); // wait for it + m_timeOutCheckerThread.reset(); // delete it + } + } + + /// Class executed in a separate thread to disconnect from the database if + /// a time-out is reached. + class TimeOutChecker + { + /// Pointer to the CondDBAccessSvc, used to acquire operation locks and + /// access parameters. + CondDBAccessSvc *m_owner; + /// Cached MsgStream to report messages. + MsgStream log; + + public: + TimeOutChecker(CondDBAccessSvc *owner): + m_owner(owner), + log(m_owner->msgSvc(),m_owner->name()+".TimeOutChecker") + { + } + + void operator () () + { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Starting" << endmsg; + + boost::system_time last_access = m_owner->lastAccess(); + + // set initial check time + boost::system_time next_check = last_access + m_owner->m_connectionTimeOut; + + try { + // enter infinite loop + while (true) { + // Wait until the next check point time is reached. + // An early exit must be triggered by a call to this->interrupt(), which + // will produce an exception during the sleep. + boost::thread::sleep(next_check); + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Time-out reached (" << next_check << ")" << endmsg; + + boost::mutex::scoped_lock busy_lock(m_owner->m_busy); + + if ( last_access == m_owner->lastAccess() ) { // no further accesses + + if ( m_owner->database()->isOpen() ) { // close the database + log << MSG::INFO << "Disconnect from database after being idle for " + << m_owner->m_connectionTimeOut.total_seconds() + << "s (will reconnect if needed)"<< endmsg; + m_owner->database()->closeDatabase(); + // reset the latest heart beat because it may be different the next time + // we connect to the DB + if (!m_owner->m_heartBeatCondition.empty()) m_owner->m_latestHeartBeat = 0; + } + + // schedule the next check for now + dt (seems a good estimate) + next_check = boost::get_system_time() + m_owner->m_connectionTimeOut; + + } else { + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Wait more" << endmsg; + + // schedule the next check for last_access + dt + next_check = last_access = m_owner->lastAccess(); + next_check += m_owner->m_connectionTimeOut; + } + } + } + // Ignore the exception since it is used only to exit from the loop. + catch (boost::thread_interrupted&) {} + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Stopping" << endmsg; + } + }; + + class DataBaseOperationLock + { + CondDBAccessSvc *m_owner; + MsgStream log; + boost::mutex::scoped_lock busy_lock; + public: + DataBaseOperationLock(const CondDBAccessSvc *owner): + m_owner(const_cast<CondDBAccessSvc*>(owner)), + log(m_owner->msgSvc(),m_owner->name()+".DataBaseOperationLock"), + busy_lock(m_owner->m_busy) // lock the access to the db + { + // If the database has not been instantiated yet, we may be using + // lazy connection and we have to connect now. + if (!m_owner->m_db) { + // we have to release the lock because i_initializeConnection + // needs to lock the DB + busy_lock.unlock(); + StatusCode sc = m_owner->i_initializeConnection(); + busy_lock.lock(); + if (! sc.isSuccess()) + throw GaudiException("Cannot initialize connection", + "DataBaseOperationLock::DataBaseOperationLock", + sc); + } + if (!m_owner->m_db->isOpen()){ + log << MSG::INFO << "Connecting to database" << endmsg; + m_owner->m_db->openDatabase(); // ensure that the db is open + m_owner->i_startTimeoutChecker(); // ensure that the timeout checker is running + } + } + + ~DataBaseOperationLock() + { + m_owner->touchLastAccess(); // update last access time + } + }; + + friend class TimeOutChecker; + friend class DataBaseOperationLock; + +}; +#endif // COMPONENT_CONDDBACCESSSVC_H diff --git a/Det/DetCond/src/component/CondDBCache.cpp b/Det/DetCond/src/component/CondDBCache.cpp new file mode 100755 index 000000000..2e6e94cc4 --- /dev/null +++ b/Det/DetCond/src/component/CondDBCache.cpp @@ -0,0 +1,444 @@ +// Include files +#include "CondDBCache.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBCache +// +// 2005-06-13 : Marco Clemencic +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBCache::CondDBCache(const MsgStream& log, size_t highLvl, size_t lowLvl): + m_highLvl(highLvl), m_lowLvl(lowLvl), + m_level(0), + m_log(log), + m_lastRequestedTime(0), m_checkLastReqTime(true), + m_silentConflicts(false) +{ + if ( highLvl == 0 ) { + m_log << MSG::WARNING << "High level == 0 : forced to 100" << endmsg; + m_highLvl = 100; + } + if ( highLvl <= lowLvl ) { + m_log << MSG::WARNING << "High level <= low level : low level forced to 0" << endmsg; + m_lowLvl = 0; + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Cache initialized with high/low levels = " << + m_highLvl << '/' << m_lowLvl << endmsg; +} +//============================================================================= +// Destructor +//============================================================================= +CondDBCache::~CondDBCache() { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Cache deleted. Level was = " << m_level << endmsg; +} + +//========================================================================= +// Add a new item to the cache +//========================================================================= +bool CondDBCache::insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel) { + // increment object count and check the limit + if ( m_level >= highLevel() ){ + // needs clean up + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Level above max threshold" << endmsg; + clean_up(); + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Insert Folder '" << folder->fullPath() + << "', IOV : " << obj.since() << " - " << obj.until() + << ", channel : " << channel << endmsg; + + FolderIdType id(folder->fullPath()); + StorageType::iterator f = m_cache.find(id); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(id, CondFolder(folder))).first; + // Fill the map of channel names. + std::map<cool::ChannelId,std::string>::const_iterator p; + std::map<cool::ChannelId,std::string> ch_names = folder->listChannelsWithNames(); + for (p = ch_names.begin(); p != ch_names.end(); ++p) { + f->second.channelNames[p->second] = p->first; + } + } else { + if (f->second.items[channel].end() != f->second.conflict(obj.since(), obj.until(), channel)) { + const MSG::Level lvl = (m_silentConflicts ? MSG::DEBUG : MSG::WARNING); + m_log << lvl << "Conflict found: item not inserted" << endmsg; + ItemListType::iterator i = f->second.conflict(obj.since(), obj.until(), channel); + m_log << lvl << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; + return false; + } + } + // for vectors + // f->second.items.push_back(CondItem(&f->second,obj)); + // for lists + ItemListType &items = f->second.items[channel]; + ItemListType::iterator pos = items.begin(); + while (pos != items.end() && pos->iov.first < obj.since()) { + ++pos; + } + items.insert(pos, CondItem(&f->second, obj)); + + ++m_level; + return true; +} + +//========================================================================= +// Add a new folder using the given specification and description. (Bypass the real DB) +//========================================================================= +bool CondDBCache::addFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec) { + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; + } + return true; +} +bool CondDBCache::addFolder(const std::string &path, const std::string &descr, + const cool::IRecordSpecification& spec, + const std::map<cool::ChannelId,std::string>& ch_names) { + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; + // Fill the map of channel names. + std::map<cool::ChannelId,std::string>::const_iterator p; + for (p = ch_names.begin(); p != ch_names.end(); ++p) { + f->second.channelNames[p->second] = p->first; + } + } + return true; +} + +//========================================================================= +// Add a new folder using the given specification and description. (Bypass the real DB) +//========================================================================= +bool CondDBCache::addFolderSet(const std::string &path, const std::string &descr) { + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + f = m_cache.insert(StorageType::value_type(path,CondFolder(descr))).first; + } + return true; +} + +//========================================================================= +// Add a new object to a given folder +//========================================================================= +bool CondDBCache::addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before) { + // new objects cannot be already valid. check it! + if ( IOVCheck() && (m_lastRequestedTime != 0) + && ( since <= m_lastRequestedTime && m_lastRequestedTime < until ) ) { + m_log << (m_silentConflicts ? MSG::DEBUG : MSG::WARNING) + << "New item IOV is compatible with last requested time:" + << " not allowed to avoid inconsistencies" << endmsg; + return false; + } + // increment object count and check the limit + if ( m_level >= highLevel() ){ + // needs clean up + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Level above max threshold" << endmsg; + clean_up(); + } + StorageType::iterator f = m_cache.find(path); + if (f == m_cache.end()){ + m_log << MSG::WARNING << "Could not find the folder: object not added" << endmsg; + return false; + } + if (!f->second.spec) { // no specification means FolderSet + m_log << MSG::WARNING << '"' << path << '"' << " is a FolderSet: object not added" << endmsg; + return false; + } + + // when bypassing the DB, the conflicts must be solved + /* + if (f->second.conflict(since,until) != f->second.items.end()) { + m_log << MSG::WARNING << "Conflict found: item not inserted" << endmsg; + return false; + } + */ + // **** COOL single version style --> [x;+inf] + [y(>x);z] = [x;y], [y;z] + // scan for conflicting items (from the end) + ItemListType::iterator i = f->second.conflict(since,until,channel); + if ( i != f->second.items[channel].end() ) { // conflict found + if ( i->iov.second == cool::ValidityKeyMax && i->iov.first < since ) { + // solvable conflict + if (iov_before) *iov_before = i->iov; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Solvable conflict found: old until = " << i->iov.second << endmsg; + i->iov.second = since; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " new until = " << i->iov.second << endmsg; + } else { + // conflict not solvable + m_log << MSG::WARNING << "Unsolvable conflict found: item not inserted" << endmsg; + return false; + } + } + // for vectors + // f->second.items.push_back(CondItem(&f->second,since,until,rec)); + // for lists + f->second.items[channel].push_front(CondItem(&f->second,since,until,rec)); + ++m_level; + return true; +} + +//========================================================================= +// Get data from given path and valid at given time +//========================================================================= +bool CondDBCache::get(const std::string &path, const cool::ValidityKey &when, + const cool::ChannelId &channel, + cool::ValidityKey &since, cool::ValidityKey &until, + std::string &descr, ICondDBReader::DataPtr &payload ) { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Request Folder '" << path + << "' @ " << when << " channel " << channel; + m_lastRequestedTime = when; + StorageType::iterator folder = m_cache.find(path); + if (folder != m_cache.end()) { + if ( ! folder->second.spec ) { + // It's a FolderSet! no objects inside + since = cool::ValidityKeyMin; + until = cool::ValidityKeyMax; + descr = folder->second.description; + payload.reset(); + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << " FOUND (FolderSet)" << endmsg; + return true; + } + ItemListType::iterator i = folder->second.find(when,channel); + if ( i != folder->second.items[channel].end() ) { + since = i->iov.first; + until = i->iov.second; + descr = folder->second.description; + payload = i->data; + //i->score += 1.0; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << " FOUND" << endmsg; + return true; + } + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << " MISSING" << endmsg; + return false; +} +//========================================================================= +// +//========================================================================= +bool CondDBCache::getChannelId(const std::string &path,const std::string &name, + cool::ChannelId &channel) const { + StorageType::const_iterator f = m_cache.find(path); + if ( m_cache.end() != f ) { + CondFolder::ChannelNamesMapType::const_iterator id = f->second.channelNames.find(name); + if ( f->second.channelNames.end() != id ) { + channel = id->second; + return true; + } + } + channel = 0; + return false; +} +//========================================================================= +// +//========================================================================= +void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets) { + + folders.clear(); + foldersets.clear(); + + StorageType::iterator f; + for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { + const std::string &p = f->first; + if ( p.find(path) == 0 // the string must start with path + && ( p.size() > path.size() ) // it must contain something more than the path + && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name + if ( f->second.spec.get() ) { + // this is a folder + folders.push_back(p.substr(path.size())); + } else { + // this is a folderset + foldersets.push_back(p.substr(path.size())); + } + } + } +} +//========================================================================= +// +//========================================================================= +void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &node_names) { + // @todo: could be implemented as getSubNodes(path,node_names,node_names); + + node_names.clear(); + + StorageType::iterator f; + for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { + const std::string &p = f->first; + if ( p.find(path) == 0 // the string must start with path + && ( p.size() > path.size() ) // it must contain something more than the path + && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name + node_names.push_back(p.substr(path.size())); + } + } +} +//========================================================================= +// Remove unused entries from the cache +//========================================================================= + +void CondDBCache::clean_up(){ + typedef std::vector<std::pair<float,std::pair<CondDBCache::CondFolder*,std::pair<cool::ValidityKey,cool::ChannelId> > > > + _vec_t; + _vec_t all_items; + float score = 0; + size_t old_level = level(); + + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) { + m_log << MSG::DEBUG << "Start cleaning up (level = " << level() << ")" << endmsg; + m_log << MSG::DEBUG << " Last requested time = " << m_lastRequestedTime << endmsg; + } + // collect all items info in order + StorageType::iterator folder; + for ( folder = m_cache.begin() ; folder != m_cache.end() ; ++folder ) { + + if ( ! folder->second.spec ) continue; // It's a FolderSet! no objects inside: skip it + + CondFolder::StorageType::iterator ch; + ItemListType::iterator i; + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Folder " << folder->first << endmsg; + for ( ch = folder->second.items.begin(); ch != folder->second.items.end() ; ++ch ){ + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " channel : " << ch->first << endmsg; + for ( i = ch->second.begin(); i != ch->second.end() ; ++i ){ + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; + if ( ! (i->iov.first <= m_lastRequestedTime && i->iov.second > m_lastRequestedTime) ) { + if ( m_lastRequestedTime < i->iov.first ) { + score = (float)m_lastRequestedTime - i->iov.first; + } else { + score = (float)i->iov.second - m_lastRequestedTime; + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " score = " << score << endmsg; + all_items.push_back( + std::make_pair(score, + std::make_pair(&folder->second, + std::make_pair(i->iov.first,ch->first)))); + // i->score = 0; + } + } + } + } + std::sort(all_items.begin(),all_items.end()); + + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Remove items" << endmsg; + // remove items + _vec_t::iterator it = all_items.begin(); + while ( m_level > m_lowLvl && it != all_items.end()) { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Remove item since " << it->second.second.first << + " channel " << it->second.second.second << + // " from '" << it->second.first->path << "'" << + " (score =" << it->first << ")" << endmsg; + // folder when + it->second.first->erase(it->second.second.first,it->second.second.second); + --m_level; + ++it; + } + + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Remove empty folders:" << endmsg; + // remove empty folders + std::vector<FolderIdType> to_remove; + for ( StorageType::iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { + if (!i->second.sticky && i->second.empty()) { // delete folders which are empty but not sticky + to_remove.push_back(i->first); + } + } + for ( std::vector<FolderIdType>::iterator i = to_remove.begin(); i != to_remove.end(); ++i ) { + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << " " << *i << endmsg; + m_cache.erase(m_cache.find(*i)); + } + if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) + m_log << MSG::DEBUG << "Clean up finished (level = " << level() << ")" << endmsg; + if ( UNLIKELY(old_level == level()) ) { + m_log << MSG::WARNING << "No item removed: I increase high threshold" << endmsg; + setHighLevel(highLevel()+(highLevel()-lowLevel())/10+1); + m_log << MSG::WARNING << "New threshold = " << highLevel() << endmsg; + } +} + +//========================================================================= +// Check if an entry for the give path+time is in the cache +//========================================================================= +bool CondDBCache::hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel) const { + StorageType::const_iterator folder = m_cache.find(path); + if (folder != m_cache.end()) { + + if ( !folder->second.spec ) return true; // It's a FolderSet! They ignore time + + ItemListType::const_iterator i = folder->second.find(when,channel); + const ItemListType &lst = (*const_cast<CondFolder::StorageType *>(&folder->second.items))[channel]; + return i != lst.end(); + } + return false; +} + +ICondDBReader::IOVList CondDBCache::getIOVs(const std::string & path, const ICondDBReader::IOV & iov, cool::ChannelId channel) +{ + ICondDBReader::IOVList result; + StorageType::const_iterator folder = m_cache.find(path); + if (folder != m_cache.end()) { + if (folder->second.spec) { + // find the first recorded interval which overlaps with requested IOV + ItemListType::const_iterator i = folder->second.conflict(iov.since.ns(), iov.until.ns(), channel); + // marker for the end of IOVs in the cache for the channel + const ItemListType::const_iterator end = folder->second.end(channel); + // we add all the IOVs in the cache starting from the one found until + // we are in the list and the IOV is in the requested range. + for(; i != end && (i->iov.first < static_cast<cool::ValidityKey>(iov.until.ns())); ++i) { + result.push_back(ICondDBReader::IOV(i->iov.first, i->iov.second)); + } + } else { + // it's a FolderSet: IOV is infinite + result.push_back(ICondDBReader::IOV(Gaudi::Time::epoch(), Gaudi::Time::max())); + } + } + return result; +} + +//========================================================================= +// Dump the content of the cache to the message service. +//========================================================================= +void CondDBCache::dump() { + if (m_log.level() > MSG::DEBUG) return; // do not dump outside for non debug + m_log << MSG::DEBUG << "Cache content dump --------------------- BEGIN" << endmsg; + m_log << MSG::DEBUG << " Thresholds (high/low) -> " << m_highLvl << '/' << m_lowLvl << endmsg; + m_log << MSG::DEBUG << " Level = " << level() << endmsg; + for(StorageType::const_iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { + if ( !i->second.spec ) { // It's a FolderSet! They ignore time + m_log << MSG::DEBUG << "FolderSet '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; + continue; + } else { + m_log << MSG::DEBUG << "Folder '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; + } + + for(CondFolder::StorageType::const_iterator ch = i->second.items.begin(); ch != i->second.items.end(); ++ch) { + m_log << MSG::DEBUG << " Channel " << ch->first << endmsg; + size_t cnt = 0; + for(ItemListType::const_iterator j = ch->second.begin(); j != ch->second.end(); ++j) { + m_log << MSG::DEBUG << " Object " << cnt++ << endmsg; + m_log << MSG::DEBUG << " Score: " << j->score << endmsg; + m_log << MSG::DEBUG << " Validity: " << j->iov.first << " - " << j->iov.second << endmsg; + m_log << MSG::DEBUG << " Data: " << *(j->data)<< endmsg; + } + } + } + m_log << MSG::DEBUG << "Cache content dump --------------------- END" << endmsg; +} +//============================================================================= + diff --git a/Det/DetCond/src/component/CondDBCache.h b/Det/DetCond/src/component/CondDBCache.h new file mode 100755 index 000000000..0f8ab7994 --- /dev/null +++ b/Det/DetCond/src/component/CondDBCache.h @@ -0,0 +1,279 @@ +#ifndef COMPONENT_CONDDBCACHE_H +#define COMPONENT_CONDDBCACHE_H 1 + +// Include files +#include <string> +#include <vector> +#include <list> + +#include "GaudiKernel/MsgStream.h" + +#include "GaudiKernel/HashMap.h" + +#include "CoolKernel/types.h" +#include "CoolKernel/pointers.h" +#include "CoolKernel/ValidityKey.h" +#include "CoolKernel/IObject.h" +#include "CoolKernel/IFolder.h" +#include "CoolKernel/IRecord.h" +#include "CoolKernel/Record.h" +#include "CoolKernel/IRecordSpecification.h" +#include "CoolKernel/RecordSpecification.h" + +#include "DetCond/ICondDBReader.h" + +#include <boost/shared_ptr.hpp> + +/** @class CondDBCache CondDBCache.h component/CondDBCache.h + * + * Class used to manage in memory conditions. + * + * @author Marco Clemencic + * @date 2005-06-13 + */ +class CondDBCache { + +public: + + typedef std::pair<cool::ValidityKey,cool::ValidityKey> IOVType; + + //-------------------------------------------------------------------------------- + /// Standard constructor + CondDBCache(const MsgStream& log, size_t highLevel = 100, size_t lowLevel = 10); + + virtual ~CondDBCache( ); ///< Destructor + + /// Add a new data object to the cache. + /// \warning {no check performed} + bool insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel = 0); + + /// Shortcut for the regular implementations (for backward compatibility). + inline bool insert(const cool::IFolderPtr &folder,const cool::IObjectPtr &obj, const cool::ChannelId &channel = 0) { + return insert(folder, *obj.get(), channel); + } + + bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec); + bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec, + const std::map<cool::ChannelId,std::string>& ch_names); + bool addFolderSet(const std::string &path, const std::string &descr); + bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before = NULL); + /// (version kept for backward compatibility) + inline bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord& rec, IOVType *iov_before = NULL) + { + return addObject(path,since,until,rec,0,iov_before); + } + + + /// Search an entry in the cache and returns the data string or an empty string if no object is found. + bool get(const std::string &path, const cool::ValidityKey &when, + const cool::ChannelId &channel, + cool::ValidityKey &since, cool::ValidityKey &until, + std::string &descr, ICondDBReader::DataPtr &payload); + + /// Search an entry in the cache and returns the data string or an empty string if no object is found. + /// (version kept for backward compatibility) + inline bool get(const std::string &path, const cool::ValidityKey &when, + cool::ValidityKey &since, cool::ValidityKey &until, + std::string &descr, ICondDBReader::DataPtr &payload) { + return get(path,when,0,since,until,descr,payload); + } + + /// Find the value of the channel id for the given channel name in a folder + /// (if present in the cache). + /// Returns true if the channel name in the folder was found + bool getChannelId(const std::string &path,const std::string &name, + cool::ChannelId &channel) const; + + void getSubNodes(const std::string &path, std::vector<std::string> &node_names); + + void getSubNodes(const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets); + + /// Remove all entries from the cache; + inline void clear() {m_cache.clear();} + + /// Get the number of items cached. + inline size_t size() const; + + inline void setHighLevel(size_t lvl) { m_highLvl = lvl; } + inline void setLowLevel(size_t lvl) { m_lowLvl = lvl; } + inline size_t highLevel() const { return m_highLvl; } + inline size_t lowLevel() const { return m_lowLvl; } + + inline size_t level() const { return m_level; } + + void clean_up(); + + /// Check if the given path is present in the cache. + inline bool hasPath(const std::string &path) const { return m_cache.count(path) != 0; } + + /// Check if the path is a folderset. + inline bool isFolderSet(const std::string &path) const { + return hasPath(path) && (m_cache.find(path)->second.spec.get() == 0); + } + + /// Check if the path is a folderset. + inline bool isFolder(const std::string &path) const { + return hasPath(path) && (m_cache.find(path)->second.spec.get() != 0); + } + + /// Check if the given path,time pair is present in the cache. + bool hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const; + + /// Return the list of IOVs known for the given path, IOV, channel. + /// @see ICondDBReader::getIOVs + ICondDBReader::IOVList getIOVs(const std::string &path, const ICondDBReader::IOV &iov, cool::ChannelId channel = 0); + + void dump(); + + /// Set the flag to enable the check that the inserted IOVs are not compatible with the latest + /// requested time (needed to avoid that the cache is modified for the current event). + /// @return previous value + bool setIOVCheck(bool enable) + { + bool old = m_checkLastReqTime; + m_checkLastReqTime = enable; + return old; + } + + /// Tell if the check on inserted IOVs is enabled. + bool IOVCheck() { return m_checkLastReqTime; } + + /// Getter for the data member m_silentConflicts. + bool silentConflicts() const { return m_silentConflicts; } + + /// Getter for the data member m_silentConflicts. + void setSilentConflicts(bool value) { m_silentConflicts = value; } + +protected: + +private: + + struct CondFolder; + struct CondItem; + + typedef std::string FolderIdType; + //typedef std::vector<CondItem> ItemListType; + typedef std::list<CondItem> ItemListType; + // typedef std::map<FolderIdType,CondFolder> FolderListType; + typedef GaudiUtils::HashMap<FolderIdType,CondFolder> StorageType; + + /// Internal class used to record IOV+data pairs + struct CondItem { + /// Constructor. + CondItem(CondFolder *myFolder, const cool::IObject &obj): + folder(myFolder),iov(obj.since(),obj.until()), + data(new cool::Record(obj.payload())),score(1.0) {} + CondItem(CondFolder *myFolder, const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::IRecord &rec): + folder(myFolder),iov(since,until), data(new cool::Record(rec)),score(1.0) {} + CondFolder *folder; + IOVType iov; + ICondDBReader::DataPtr data; + float score; + /// Check if the CondItem is valid at the given time. + inline bool valid(const cool::ValidityKey &when) const { + return iov.first <= when && when < iov.second; + } + }; + + /// Internal class used to keep the items common to a given path. + struct CondFolder { + + typedef GaudiUtils::Map<cool::ChannelId,ItemListType> StorageType; + typedef GaudiUtils::HashMap<std::string,cool::ChannelId> ChannelNamesMapType; + + CondFolder(const cool::IFolderPtr &fld): + description(fld->description()), + spec(new cool::RecordSpecification(fld->payloadSpecification())), + sticky(false) {} + CondFolder(const std::string &descr, const cool::IRecordSpecification& new_spec): + description(descr),spec(new cool::RecordSpecification(new_spec)),sticky(true) {} + // for a folderset (FolderSets are identified by missing spec) + CondFolder(const std::string &descr): + description(descr),sticky(true) {} + std::string description; + boost::shared_ptr<cool::IRecordSpecification> spec; + StorageType items; + ChannelNamesMapType channelNames; + bool sticky; + /// Search for the first item in the storage valid at the given time. + inline ItemListType::iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { + ItemListType &lst = items[channel]; + ItemListType::iterator i; + for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} + return i; + } + /// Const version of the search method. + inline ItemListType::const_iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const { + const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; + ItemListType::const_iterator i; + for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} + return i; + } + inline ItemListType::iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::ChannelId &channel = 0) { + ItemListType &lst = items[channel]; + ItemListType::iterator i; + for ( i = lst.begin(); i != lst.end() ; ++i ){ + // Given two IOVs a and b, they conflict if the intersection is not empty: + // max(a.s,b.s) < min(a.u,b.u) + if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; + } + return i; + } + inline ItemListType::const_iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, + const cool::ChannelId &channel = 0) const { + const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; + ItemListType::const_iterator i; + for ( i = lst.begin(); i != lst.end() ; ++i ){ + if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; + } + return i; + } + inline ItemListType::iterator end(const cool::ChannelId &channel = 0) { + return items[channel].end(); + } + inline ItemListType::const_iterator end(const cool::ChannelId &channel = 0) const { + return (*const_cast<StorageType *>(&items))[channel].end(); + } + inline void erase (const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { + items[channel].erase(find(when,channel)); + } + inline bool empty() const { + for (StorageType::const_iterator ch = items.begin(); ch != items.end(); ++ch ) { + if (! ch->second.empty()) return false; + } + return true; + } + + }; + + /// Actual storage + StorageType m_cache; + + size_t m_highLvl; + size_t m_lowLvl; + size_t m_level; + + MsgStream m_log; + + cool::ValidityKey m_lastRequestedTime; + bool m_checkLastReqTime; + + // Do not print warning messages in case of conflicts during the insertion + bool m_silentConflicts; +}; + +inline size_t CondDBCache::size() const { + size_t count = 0; + StorageType::const_iterator folder; + for (folder = m_cache.begin(); folder != m_cache.end(); ++folder) { + for (CondFolder::StorageType::const_iterator ch = folder->second.items.begin(); ch != folder->second.items.end(); ++ch) + count += ch->second.size(); + } + return count; +} + +#endif // COMPONENT_CONDDBCACHE_H diff --git a/Det/DetCond/src/component/CondDBCnvSvc.cpp b/Det/DetCond/src/component/CondDBCnvSvc.cpp new file mode 100755 index 000000000..a192987ee --- /dev/null +++ b/Det/DetCond/src/component/CondDBCnvSvc.cpp @@ -0,0 +1,197 @@ +#include <string> + +#include "CondDBCnvSvc.h" +#include "DetCond/ICondDBReader.h" + +#include "GaudiKernel/GenericAddress.h" +#include "GaudiKernel/IDetDataSvc.h" +#include "GaudiKernel/IDataProviderSvc.h" +#include "GaudiKernel/MsgStream.h" + +/// Instantiation of a static factory to create instances of this service +DECLARE_SERVICE_FACTORY(CondDBCnvSvc) + +//---------------------------------------------------------------------------- + +/// Constructor +CondDBCnvSvc::CondDBCnvSvc( const std::string& name, ISvcLocator* svc) + : base_class ( name, svc, CONDDB_StorageType ), + m_dbReader(0) +{ + declareProperty( "CondDBReader", m_dbReaderName = "CondDBAccessSvc" ); +} + +//---------------------------------------------------------------------------- + +/// Destructor +CondDBCnvSvc::~CondDBCnvSvc() {} + +//---------------------------------------------------------------------------- + +/// Initialize the service. +StatusCode CondDBCnvSvc::initialize() +{ + + // Before anything else, we need to initialise the base class + StatusCode sc = base_class::initialize(); + if ( !sc.isSuccess() ) return sc; + + // Now we can get a handle to the MessageSvc + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Specific initialization starting" << endmsg; + + // Locate the Database Access Service + sc = service(m_dbReaderName,m_dbReader,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << m_dbReaderName << endmsg; + return sc; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved " << m_dbReaderName << endmsg; + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Specific initialization completed" << endmsg; + return sc; +} + +//---------------------------------------------------------------------------- + +/// Finalize the service. +StatusCode CondDBCnvSvc::finalize() +{ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalizing" << endmsg; + if (m_dbReader) m_dbReader->release(); + return base_class::finalize(); +} + +//---------------------------------------------------------------------------- + +/// Create an address using explicit arguments to identify a single object. +/// Par[0] is folder name in the CondDB. +/// Par[1] is entry name in the string (which may contain many conditions, +/// for instance in the case of XML files with more than one element). +StatusCode CondDBCnvSvc::createAddress( long svc_type, + const CLID& clid, + const std::string* par, + const unsigned long* ipar, + IOpaqueAddress*& refpAddress ) { + + // First check that requested address is of type CONDDB_StorageType + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering createAddress" << endmsg; + if ( svc_type!= CONDDB_StorageType ) { + log << MSG::ERROR + << "Cannot create addresses of type " << (int)svc_type + << " which is different from " << (int)CONDDB_StorageType + << endmsg; + return StatusCode::FAILURE; + } + + // Par[0] is folder name in the CondDB. + std::string folderName = par[0]; + + // Par[1] is entry name in the string (which may contain many conditions, + // for instance in the case of XML files with more than one element). + std::string entryName = par[1]; + + // iPar[0] is the cool::ChannelId + unsigned long channelId = ipar[0]; + + // Now create the address + refpAddress = new GenericAddress( CONDDB_StorageType, + clid, + folderName, + entryName, + channelId ); + return StatusCode::SUCCESS; + +} + +//---------------------------------------------------------------------------- + +/// Retrieve converter from list +IConverter* CondDBCnvSvc::converter(const CLID& clid) { + IConverter* cnv = 0; + cnv = ConversionSvc::converter(clid); + if ( cnv ) { + return cnv; + } + else { + return ConversionSvc::converter(CLID_Any); + } +} + +//---------------------------------------------------------------------------- +// Implementation of ICondDBReader +StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) +{ + return m_dbReader->getObject(path,when,data,descr,since,until,channel); +} + +StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) +{ + return m_dbReader->getObject(path,when,data,descr,since,until,channel); +} + +StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) +{ + return m_dbReader->getChildNodes(path,node_names); +} + +StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) +{ + return m_dbReader->getChildNodes(path,folders,foldersets); +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBCnvSvc::exists(const std::string &path) { + return m_dbReader->exists(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBCnvSvc::isFolder(const std::string &path) { + return m_dbReader->isFolder(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBCnvSvc::isFolderSet(const std::string &path) { + return m_dbReader->isFolder(path); +} + +void CondDBCnvSvc::disconnect() { + if(m_dbReader) + m_dbReader->disconnect(); +} + +ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return m_dbReader->getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return m_dbReader->getIOVs(path, iov, channel); +} + +void CondDBCnvSvc::defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const +{ + tags.clear(); + m_dbReader->defaultTags(tags); +} + diff --git a/Det/DetCond/src/component/CondDBCnvSvc.h b/Det/DetCond/src/component/CondDBCnvSvc.h new file mode 100755 index 000000000..88430fd0a --- /dev/null +++ b/Det/DetCond/src/component/CondDBCnvSvc.h @@ -0,0 +1,123 @@ +#ifndef DETCOND_CONDDBCNVSVC_H +#define DETCOND_CONDDBCNVSVC_H 1 + +/// Include files +#include "GaudiKernel/ConversionSvc.h" + +#include "DetCond/ICondDBReader.h" + +/// Forward and external declarations +template <class TYPE> class SvcFactory; +class IDetDataSvc; +class IOpaqueAddress; + +///--------------------------------------------------------------------------- +/** @class CondDBCnvSvc CondDBCnvSvc.h + + A conversion service for CERN-IT COOL (ex. CondDB) persistency. + Allows to create and update condition data objects (i.e. DataObjects + implementing IValidity). + + @author Marco Clemencic + @date November 2004 +*///-------------------------------------------------------------------------- + +class CondDBCnvSvc : public extends1<ConversionSvc, ICondDBReader> { + + /// Only factories can access protected constructors + friend class SvcFactory<CondDBCnvSvc>; + +protected: + + /// Constructor + CondDBCnvSvc( const std::string& name, ISvcLocator* svc ); + + /// Destructor + virtual ~CondDBCnvSvc(); + +public: + + // Overloaded from ConversionSvc + + /// Initialize the service + virtual StatusCode initialize(); + + /// Finalize the service + virtual StatusCode finalize(); + + using ConversionSvc::createAddress; + /// Create an address using explicit arguments to identify a single object. + virtual StatusCode createAddress (long svc_type, + const CLID& clid, + const std::string* par, + const unsigned long* ip, + IOpaqueAddress*& refpAddress ); + +public: + + /// Retrieve converter from list + virtual IConverter* converter(const CLID& clid); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + +private: + + /// List of all the names of the known databases. It is filled via the option + /// CondDBCnvSvc.CondDBReader. If none is given, "CondDBAccessSvc" is used. + std::string m_dbReaderName; + + /// Handles to the database Access services + ICondDBReader* m_dbReader; + +protected: + +}; + +#endif // DETCOND_CONDITIONSDBCNVSVC_H + + diff --git a/Det/DetCond/src/component/CondDBCommon.cpp b/Det/DetCond/src/component/CondDBCommon.cpp new file mode 100755 index 000000000..c0fbf40bb --- /dev/null +++ b/Det/DetCond/src/component/CondDBCommon.cpp @@ -0,0 +1,90 @@ +#include "CondDBCommon.h" + +#include <sstream> + +#include "CoolKernel/RecordSpecification.h" +#include "CoolKernel/Record.h" +#include "CoolKernel/StorageType.h" + +static std::unique_ptr<cool::RecordSpecification> s_XMLStorageSpec{}; + +namespace CondDB { + +const cool::RecordSpecification& getXMLStorageSpec() { + if ( s_XMLStorageSpec.get() == NULL){ + // attribute list spec template + s_XMLStorageSpec = std::unique_ptr<cool::RecordSpecification>(new cool::RecordSpecification()); + s_XMLStorageSpec->extend("data", cool::StorageType::String16M); + } + return *s_XMLStorageSpec; +} + +namespace { + inline bool ends_with(const std::string& s, const std::string &suff) { + const auto count = suff.size(); + const auto size = s.size(); + return (size >= count) && + (s.compare(size - count, count, suff) == 0); + } +} + +void generateXMLCatalog(const std::string &name, + const std::vector<std::string> &fldrs, + const std::vector<std::string> &fldrsets, + std::string &data) { + std::ostringstream xml; // buffer for the XML + + // XML header, root element and catalog initial tag + xml << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + << "<!DOCTYPE DDDB SYSTEM \"conddb:/DTD/structure.dtd\">" + << "<DDDB><catalog name=\"" << name << "\">"; + + // sub-folders are considered as container of conditions + std::vector<std::string>::const_iterator f; + for (const auto& f: fldrs) { + // Ignore folders with the .xml extension. + // We never used .xml for Online conditions and after the Hlt1/Hlt2 split + // we need to avoid automatic mapping for the .xml files. + if (!ends_with(f, ".xml")) { + xml << "<conditionref href=\"" << name << '/' << f << "\"/>"; + } + } + // sub-foldersets are considered as catalogs + for (const auto& f: fldrsets) { + xml << "<catalogref href=\"" << name << '/' << f << "\"/>"; + } + // catalog and root element final tag + xml << "</catalog></DDDB>"; + + data = xml.str(); +} + +StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, + ICondDBReader::DataPtr &payload){ + // get the list of subnodes + std::vector<std::string> folders, foldersets; + StatusCode sc = reader->getChildNodes(path,folders,foldersets); + if (sc.isFailure()) return sc; + + // extract the name of the folderset + std::string::size_type pos = path.rfind('/'); + std::string name; + if ( std::string::npos != pos ) { + name = path.substr(pos+1); + } else { + name = path; + } + + // generate the XML catalog + std::string xml; + generateXMLCatalog(name,folders,foldersets,xml); + + // prepare new payload + cool::Record *rec = new cool::Record(getXMLStorageSpec()); + (*rec)["data"].setValue<cool::String16M>(xml); + payload.reset(rec); + + return sc; +} + +} diff --git a/Det/DetCond/src/component/CondDBCommon.h b/Det/DetCond/src/component/CondDBCommon.h new file mode 100755 index 000000000..476f26811 --- /dev/null +++ b/Det/DetCond/src/component/CondDBCommon.h @@ -0,0 +1,29 @@ +#ifndef CONDDBCOMMON_H_ +#define CONDDBCOMMON_H_ + +#include <string> +#include <vector> +#include "DetCond/ICondDBReader.h" + +// forward declaration +namespace cool{ + class RecordSpecification; +} + +/** @file Utility functions shared among DetCond components. + * + * @author Marco Clemencic + */ +namespace CondDB { + void generateXMLCatalog(const std::string &name, + const std::vector<std::string> &fldrs, + const std::vector<std::string> &fldrsets, + std::string &data); + + StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, + ICondDBReader::DataPtr &data); + + const cool::RecordSpecification& getXMLStorageSpec(); +} + +#endif /*CONDDBCOMMON_H_*/ diff --git a/Det/DetCond/src/component/CondDBDQScanner.cpp b/Det/DetCond/src/component/CondDBDQScanner.cpp new file mode 100644 index 000000000..48cdd8556 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDQScanner.cpp @@ -0,0 +1,147 @@ +// Include files + +// From Gaudi +#include "GaudiKernel/IConverter.h" +#include "GaudiKernel/IAddressCreator.h" +#include "GaudiKernel/IOpaqueAddress.h" + +#include "CoolKernel/IRecord.h" +#include "CoolKernel/RecordException.h" + +// From LHCb +#include "DetCond/ICondDBReader.h" +#include "DetDesc/Condition.h" + +// local +#include "CondDBDQScanner.h" +#include "RelyConverter.h" + +// ---------------------------------------------------------------------------- +// Implementation file for class: CondDBDQScanner +// +// 04/11/2011: Marco Clemencic +// ---------------------------------------------------------------------------- +DECLARE_TOOL_FACTORY(CondDBDQScanner) + +// ============================================================================ +// Standard constructor, initializes variables +// ============================================================================ +CondDBDQScanner::CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent) + : base_class(type, name, parent) +{ + + declareProperty("ConditionPath", + m_condPath = "/Conditions/DQ/Flags", + "Path in the Conditions Database where to find the Data " + "Quality condition."); + + declareProperty("CondDBReader", + m_condDBReaderName = "CondDBCnvSvc", + "Service implementing the ICondDBReader interface to be used " + "to access the CondDB."); + + declareProperty("Converter", + m_converterName = "DetectorPersistencySvc", + "Service implementing the IConverter interface."); +} + +CondDBDQScanner::~CondDBDQScanner() {} + +IDQFilter::FlagsType CondDBDQScanner::scan(const Gaudi::Time & since, const Gaudi::Time & until) const +{ + typedef ICondDBReader::IOVList IOVList; + typedef ICondDBReader::IOV IOV; + IDQFilter::FlagsType flags; + + ICondDBReader::DataPtr data; + Gaudi::Time dataSince, dataUntil; + std::string desc; + + // Loop over the list of conditions in the folder + IOVList iovs = m_condDB->getIOVs(m_condPath, IOV(since, until)); + for(IOVList::iterator iov = iovs.begin(); iov != iovs.end(); ++iov) { + // get the condition data (XML) + StatusCode sc = m_condDB->getObject(m_condPath, iov->since, data, desc, dataSince, dataUntil); + if (sc.isFailure()){ + Exception("Problems retrieving data from the database"); + return flags; // never reached, but helps Coverity + } + + try { + // prepare the IOpaqueAddress to be given to the PersistencySvc + const long storageType = RelyConverter::getStorageType(m_condPath, desc); + const std::string xml_data = (*data.get())["data"].data<std::string>(); + IOpaqueAddress *addr = RelyConverter::createTmpAddress("conddb:" + m_condPath, + storageType, + "Flags", + Condition::classID(), + xml_data, + info(), + m_converter->addressCreator()); + if (!addr){ + Exception("Failed to create temporary IOpaqueAddress"); + return flags; // never reached, but helps Coverity + } + + // Retrieve the condition data + DataObject *obj = 0; + Condition *cond = 0; + if (m_converter->createObj(addr, obj).isFailure() + || m_converter->fillObjRefs(addr, obj).isFailure() + || (cond = dynamic_cast<Condition*>(obj)) == 0) { //assignment intended + delete addr; + if (obj) delete obj; + Exception("Conversion of Condition failed"); + return flags; // never reached, but helps Coverity + } + delete addr; + + // Merge the condition map with the collected one. + const IDQFilter::FlagsType &condFlags = cond->param<IDQFilter::FlagsType>("map"); + flags.insert(condFlags.begin(), condFlags.end()); + + delete obj; + + } catch (cool::RecordSpecificationUnknownField &e) { + Exception(std::string("I cannot find the data inside COOL object: ") + e.what()); + } + } + + return flags; +} + + + + +StatusCode CondDBDQScanner::initialize() +{ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + m_condDB = service(m_condDBReaderName); + if (UNLIKELY(!m_condDB.isValid())) { + error() << "Cannot get the ICondDBReader implementation " << m_condDBReaderName << endmsg; + return StatusCode::FAILURE; + } + + m_converter = service(m_converterName); + if (UNLIKELY(!m_converter.isValid())) { + error() << "Cannot get the IConverter implementation " << m_converterName << endmsg; + return StatusCode::FAILURE; + } + + return sc; +} + + + +StatusCode CondDBDQScanner::finalize() +{ + m_condDB.reset(); // release the ICondDBReader service + + return base_class::finalize(); +} + + + +// ============================================================================ diff --git a/Det/DetCond/src/component/CondDBDQScanner.h b/Det/DetCond/src/component/CondDBDQScanner.h new file mode 100644 index 000000000..c686a8fd4 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDQScanner.h @@ -0,0 +1,56 @@ +#ifndef SRC_CONDDBDQSCANNER_H +#define SRC_CONDDBDQSCANNER_H 1 +// Include files +// from Gaudi +#include "GaudiAlg/GaudiTool.h" +#include "GaudiKernel/SmartIF.h" + +// Implemented interfaces +#include "Kernel/IDQScanner.h" // IDQScanner + +class ICondDBReader; +class IConverter; + +/** Basic implementation of an IDQScanner based on the Conditions Database. + * + * @author Marco Clemencic + * @date 04/11/2011 + */ +class CondDBDQScanner: public extends1<GaudiTool, IDQScanner> { +public: + /// Standard constructor + CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent); + virtual ~CondDBDQScanner(); ///< Destructor + + /// Scan all the Data Quality flags in the give time range in the CondDB. + /// @return merged list of DQ flags + virtual IDQFilter::FlagsType scan(const Gaudi::Time& since, const Gaudi::Time& until) const; + + virtual StatusCode initialize(); ///< Initialize the instance. + virtual StatusCode finalize(); ///< Finalize the instance. + +protected: +private: + + /// Path to the condition object containing the Data Quality flags. + /// (property ConditionPath) + std::string m_condPath; + + /// ICondDBReader implementation to use to access the Conditions Database. + /// (property CondDBReader) + std::string m_condDBReaderName; + + /// IConverter implementation (e.g. the persistency service) to use to convert + /// the data to a Condition. + /// (property Converter) + std::string m_converterName; + + /// ICondDBReader instance. + SmartIF<ICondDBReader> m_condDB; + + /// ICondDBReader instance. + SmartIF<IConverter> m_converter; + +}; + +#endif // SRC_CONDDBDQSCANNER_H diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.cpp b/Det/DetCond/src/component/CondDBDispatcherSvc.cpp new file mode 100755 index 000000000..624638275 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDispatcherSvc.cpp @@ -0,0 +1,294 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +// local +#include "CondDBDispatcherSvc.h" +#include "CondDBCommon.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBDispatcherSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBDispatcherSvc +// +// 2006-07-10 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBDispatcherSvc::CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc), + m_mainDB(0), + m_alternatives() +{ + declareProperty("MainAccessSvc", m_mainAccessSvcName = "CondDBAccessSvc" ); + declareProperty("Alternatives", m_alternativesDeclarationMap ); + + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBDispatcherSvc::~CondDBDispatcherSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBDispatcherSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + // locate the main access service + sc = service(m_mainAccessSvcName,m_mainDB,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << m_mainAccessSvcName << endmsg; + return sc; + } + + // locate all the alternative AccessSvcs + std::map<std::string,std::string>::iterator decl; + for ( decl = m_alternativesDeclarationMap.begin(); decl != m_alternativesDeclarationMap.end(); ++decl ) { + const std::string &altPath = decl->first; + const std::string &svcName = decl->second; + + if ( m_alternatives.find(altPath) != m_alternatives.end() ) { + log << MSG::ERROR << "More than one alternative for path " << altPath << endmsg; + return StatusCode::FAILURE; + } + + ICondDBReader *svcPtr; + sc = service(svcName,svcPtr,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << svcName << endmsg; + return sc; + } + + m_alternatives[altPath] = svcPtr; + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved '" << svcName << "' (for path '" << altPath << "')" << endmsg; + + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBDispatcherSvc::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + + if (m_mainDB) { + m_mainDB->release(); + m_mainDB = 0; + } + + std::map<std::string,ICondDBReader*>::iterator alt; + for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { + if (alt->second) alt->second->release(); + } + m_alternatives.clear(); + + return base_class::finalize(); +} + +ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return alternativeFor(path)->getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return alternativeFor(path)->getIOVs(path, iov, channel); +} + +//========================================================================= +// find the appropriate alternative +//========================================================================= +ICondDBReader *CondDBDispatcherSvc::alternativeFor(const std::string &path) const { + MsgStream log(msgSvc(), name() ); + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Get alternative DB for '" << path << "'" << endmsg; + if ( path.empty() || (path == "/") ) { + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Root node: using '" << m_mainAccessSvcName << "'" << endmsg; + return m_mainDB; + } + + // loop over alternatives + std::map<std::string,ICondDBReader*>::const_reverse_iterator alt; + for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { + if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { + log << MSG::VERBOSE << "Comparing with " << alt->first << endmsg; + } + // FIXME: (MCl) wrong logic + // path=/Conditions/Velo/AlignmentCatalog.xml + // alt.=/Conditions/Velo/Alignment + // Should not match + if ( ( path.size() >= alt->first.size() ) && + ( path.substr(0,alt->first.size()) == alt->first ) ){ + if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { + IService *svc = dynamic_cast<IService*>(alt->second); + log << MSG::VERBOSE << "Using '" ; + if (svc) log << svc->name(); + else log << "unknown"; + log << "'" << endmsg; + } + + return alt->second; + } + } + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Not found: using '" << m_mainAccessSvcName << "'" << endmsg; + return m_mainDB; +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) { + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); + } + return sc; +} +StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) { + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); + } + return sc; +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { + return getChildNodes(path,node_names,node_names); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) { + // clear the destination vectors + folders.clear(); + foldersets.clear(); + + // Get the folders and foldersets from the dedicated alternative + std::vector<std::string> tmpv1,tmpv2; + StatusCode sc = alternativeFor(path)->getChildNodes(path,tmpv1,tmpv2); + if (sc.isFailure()) return sc; + + // Find alternatives for subfolders of the path. + std::map<std::string,ICondDBReader*>::reverse_iterator alt; + std::string::size_type path_size = path.size(); + for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { + // check if the path for the alternative is a subfolder of the required path + // i.e. alt->first should be = path + '/' + extra + if ( ( alt->first.size() > (path_size+1) ) && // it must be long enough + ( alt->first[path_size] == '/' ) && + ( alt->first.substr(0,path_size) == path ) ){ + // take the name of the child folder[set] implied by the alternative + // i.e. substring from after (path+'/') to the next '/' + std::string sub = alt->first.substr(path_size+1, + alt->first.find('/',path_size+1)-(path_size+1)); + if (std::find(tmpv1.begin(),tmpv1.end(),sub) == tmpv1.end() && + std::find(tmpv2.begin(),tmpv2.end(),sub) == tmpv2.end()){ + // this subnode is an addition due to the alternative + // let's check the type + if (alt->second->isFolder(path+'/'+sub)) + tmpv1.push_back(sub); // folder + else + tmpv2.push_back(sub); // folderset + } + } + } + + // copy the temporary vectors to the output ones + folders = tmpv1; + foldersets = tmpv2; + return sc; +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBDispatcherSvc::exists(const std::string &path) { + return alternativeFor(path)->exists(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBDispatcherSvc::isFolder(const std::string &path) { + return alternativeFor(path)->isFolder(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBDispatcherSvc::isFolderSet(const std::string &path) { + return alternativeFor(path)->isFolderSet(path); +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBDispatcherSvc::disconnect() { + // loop over alternatives + std::map<std::string,ICondDBReader*>::const_iterator alt; + for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { + alt->second->disconnect(); + } + if (m_mainDB) + m_mainDB->disconnect(); +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBDispatcherSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + // first add the main db + m_mainDB->defaultTags(tags); + + // loop over alternatives + std::map<std::string,ICondDBReader*>::const_iterator alt; + for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { + alt->second->defaultTags(tags); + } +} + + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.h b/Det/DetCond/src/component/CondDBDispatcherSvc.h new file mode 100755 index 000000000..2e3819280 --- /dev/null +++ b/Det/DetCond/src/component/CondDBDispatcherSvc.h @@ -0,0 +1,109 @@ +#ifndef COMPONENT_CONDDBDISPATCHERSVC_H +#define COMPONENT_CONDDBDISPATCHERSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "DetCond/ICondDBReader.h" +#include <vector> +#include <map> + +template <class TYPE> class SvcFactory; + +/** @class CondDBDispatcherSvc CondDBDispatcherSvc.h component/CondDBDispatcherSvc.h + * + * + * + * @author Marco Clemencic + * @date 2006-07-10 + */ +class CondDBDispatcherSvc: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + + +protected: + /// Standard constructor + CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBDispatcherSvc( ); ///< Destructor + + +private: + + ICondDBReader *alternativeFor(const std::string &path) const; + + // -------------------- Data Members + + /// Property CondDBDispatcherSvc.MainAccessSvc: the AccessSvc instance to use to retrieve all the + /// objects for which an alternative is not specified (default to "CondDBAccessSvc"). + std::string m_mainAccessSvcName; + + /// Property CondDBDispatcherSvc.Alternatives: list of alternative Access Services in the form of + /// "/path/for/alternative":"ServiceType/ServiceName". + std::map<std::string,std::string> m_alternativesDeclarationMap; + + /// Pointer to the main access service. + ICondDBReader* m_mainDB; + + /// Container fo the alternatives. + std::map<std::string,ICondDBReader*> m_alternatives; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBDispatcherSvc>; + +}; +#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.cpp b/Det/DetCond/src/component/CondDBLayeringSvc.cpp new file mode 100755 index 000000000..d78161e24 --- /dev/null +++ b/Det/DetCond/src/component/CondDBLayeringSvc.cpp @@ -0,0 +1,288 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +// local +#include "CondDBLayeringSvc.h" +#include "CondDBCommon.h" +#include "IOVListHelpers.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBLayeringSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBLayeringSvc +// +// 2006-07-14 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +// This is needed otherwise the implementation of std::map does +// not find operator<(Gaudi::Time,Gaudi::Time). +namespace Gaudi { using ::operator<; } + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBLayeringSvc::CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc) { + + declareProperty("Layers", m_layersNames ); + + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); + +} +//============================================================================= +// Destructor +//============================================================================= +CondDBLayeringSvc::~CondDBLayeringSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBLayeringSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + // locate all the AccessSvcs layers + std::vector<std::string>::iterator lname; + for ( lname = m_layersNames.begin(); lname != m_layersNames.end(); ++lname ) { + + ICondDBReader *svcPtr; + sc = service(*lname,svcPtr,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << *lname << endmsg; + return sc; + } + + m_layers.push_back(svcPtr); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved '" << *lname << "'" << endmsg; + + } + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBLayeringSvc::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + + std::vector<ICondDBReader*>::iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ( *layer ) (*layer)->release(); + } + m_layers.clear(); + + return base_class::finalize(); +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) +{ + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + std::vector<ICondDBReader*>::iterator layer; + sc = StatusCode::FAILURE; + for ( layer = m_layers.begin(); + layer != m_layers.end() && sc.isFailure(); + ++layer ) { + sc = (*layer)->getObject(path,when,data,descr,since,until,channel); + } + } + return sc; +} +StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) +{ + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + std::vector<ICondDBReader*>::iterator layer; + sc = StatusCode::FAILURE; + for ( layer = m_layers.begin(); + layer != m_layers.end() && sc.isFailure(); + ++layer ) { + sc = (*layer)->getObject(path,when,data,descr,since,until,channel); + } + } + return sc; +} + +template <typename Channel> +ICondDBReader::IOVList CondDBLayeringSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) +{ + IOVList iovs; + + IOVList missing; // IOVs not found + missing.push_back(iov); + + std::vector<ICondDBReader*>::iterator layer; + // for each layer + for ( layer = m_layers.begin(); + layer != m_layers.end() && !missing.empty(); + ++layer ) { + + IOVList layer_iovs; + + // look for the missing IOVs in this layer + for ( IOVList::iterator m = missing.begin(); + m != missing.end(); + ++m ) { + IOVList missing_iovs = (*layer)->getIOVs(path, *m, channel); + // if we found something merge with the others in the layer + if (!missing_iovs.empty()) { + // ensure that the found IOVs do not overlap with the already available ones + missing_iovs.front().since = std::max(missing_iovs.front().since, m->since); + missing_iovs.back().until = std::min(missing_iovs.back().until, m->until); + layer_iovs.insert(layer_iovs.end(), missing_iovs.begin(), missing_iovs.end()); + } + else continue; + } + + // if we got IOVs in this layer, we add them to the results list + if (!layer_iovs.empty()) { + iovs.insert(iovs.end(), layer_iovs.begin(), layer_iovs.end()); + std::sort(iovs.begin(), iovs.end()); + // regenerate the list of holes + missing = IOVListHelpers::find_holes(iovs, iov); + } + } + + return iovs; +} + +ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return i_getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return i_getIOVs(path, iov, channel); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) +{ + return getChildNodes(path,node_names,node_names); +} + +namespace { + // helper function + template <class Input, class Output> + void merge(const Input &i, Output &o){ + typename Input::const_iterator it; + for (it = i.begin(); it != i.end(); ++it){ + if (std::find(o.begin(),o.end(),*it)==o.end()) { + o.push_back(*it); + } + } + } +} +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) +{ + // clear the destination vectors + folders.clear(); + foldersets.clear(); + + // Get the folders and foldersets from the dedicated alternative + std::vector<std::string> tmpv1,tmpv2; + StatusCode sc = StatusCode::FAILURE; + std::vector<ICondDBReader*>::iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->getChildNodes(path,tmpv1,tmpv2).isSuccess()){ + // we consider it a success if it worked at least for one of the layers + sc = StatusCode::SUCCESS; + merge(tmpv1,folders); + merge(tmpv2,foldersets); + } + } + return sc; +} +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBLayeringSvc::exists(const std::string &path) { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->exists(path)) return true; + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBLayeringSvc::isFolder(const std::string &path) { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->exists(path)) return (*layer)->isFolder(path); + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBLayeringSvc::isFolderSet(const std::string &path) { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + if ((*layer)->exists(path)) return (*layer)->isFolderSet(path); + } + return false; +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBLayeringSvc::disconnect() { + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + (*layer)->disconnect(); + } +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBLayeringSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + // loop over layers + std::vector<ICondDBReader*>::const_iterator layer; + for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { + (*layer)->defaultTags(tags); + } +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.h b/Det/DetCond/src/component/CondDBLayeringSvc.h new file mode 100755 index 000000000..c821688ef --- /dev/null +++ b/Det/DetCond/src/component/CondDBLayeringSvc.h @@ -0,0 +1,103 @@ +#ifndef COMPONENT_CONDDBLAYERINGSVC_H +#define COMPONENT_CONDDBLAYERINGSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "DetCond/ICondDBReader.h" +#include <vector> + +template <class TYPE> class SvcFactory; + +/** @class CondDBLayeringSvc CondDBLayeringSvc.h component/CondDBLayeringSvc.h + * + * + * @author Marco CLEMENCIC + * @date 2006-07-14 + */ +class CondDBLayeringSvc: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + +protected: + + /// Standard constructor + CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBLayeringSvc( ); ///< Destructor + +protected: + +private: + + // -------------------- Data Members + + /// Property CondDBLayeringSvc.Layers: list of Access Service layers. + /// They will be searched from the first to the last. + std::vector<std::string> m_layersNames; + + /// Container fo the alternatives. + std::vector<ICondDBReader*> m_layers; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBLayeringSvc>; + + /// Internal implementation helper to generalize the channel type. + template <typename Channel> + IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); + +}; +#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBLogger.cpp b/Det/DetCond/src/component/CondDBLogger.cpp new file mode 100755 index 000000000..9ec6bc57f --- /dev/null +++ b/Det/DetCond/src/component/CondDBLogger.cpp @@ -0,0 +1,250 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" + +#include <fstream> + +// local +#include "CondDBLogger.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBLogger) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBLogger +// +// 2008-01-24 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBLogger::CondDBLogger( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc), m_loggedReader(nullptr) { + + declareProperty("LoggedReader", m_loggedReaderName = "", + "Fully qualified name of the ICondDBReader to which the calls" + " have to be forwarded."); + declareProperty("LogFile", m_logFileName = "", + "Path to the log file (it is overwritten if it exists). " + "If not specified or set to empty, the file name is set from " + "the name of the instance plus '.log'." ); + +} +//============================================================================= +// Destructor +//============================================================================= +CondDBLogger::~CondDBLogger() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBLogger::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if ( m_loggedReaderName.empty() ){ + log << MSG::ERROR << "Property LoggedReader is not set." << endmsg; + return StatusCode::FAILURE; + } + + // locate the CondDBReader + sc = service(m_loggedReaderName,m_loggedReader,true); + if ( !sc.isSuccess() ) { + log << MSG::ERROR << "Could not locate " << m_loggedReaderName << endmsg; + return sc; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved '" << m_loggedReaderName << "'" << endmsg; + + // Set the default value of the file name if not specified. + if ( m_logFileName.empty() ){ + m_logFileName = name() + ".log"; + log << MSG::INFO << "Property LogFile not specified, using '" + << m_logFileName << "'" << endmsg; + } + + // Open the output file and start writing. + m_logFile = std::unique_ptr<std::ostream>(new std::ofstream(m_logFileName.c_str())); + if ( ! m_logFile->good() ) { + log << MSG::ERROR << "Problems opening " << m_logFileName << endmsg; + return StatusCode::FAILURE; + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "File '" << m_logFileName << "' opened for writing." << endmsg; + + (*m_logFile) << "INI: " << Gaudi::Time::current().ns() << " " << name() << " logging " << m_loggedReaderName << std::endl; + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBLogger::finalize(){ + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Finalize" << endmsg; + + if ( m_loggedReader ) { + m_loggedReader->release(); + m_loggedReader = 0; + } + + if (m_logFile.get()) { + (*m_logFile) << "FIN: " << Gaudi::Time::current().ns() << " " << name() << std::endl; + m_logFile.reset(0); + } + + return base_class::finalize(); +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GET: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << when.ns() << " " << std::flush; + StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} +StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GCN: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << when.ns() << " " << std::flush; + StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} + +ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "IOV: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << iov.since.ns() << " " << iov.until.ns() << std::endl; + return m_loggedReader->getIOVs(path, iov, channel); + } + return ICondDBReader::IOVList(); +} + +ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + if ( m_loggedReader ) { + (*m_logFile) << "ICN: " << Gaudi::Time::current().ns() << " " + << path << " " << channel << " " + << iov.since.ns() << " " << iov.until.ns() << std::endl; + return m_loggedReader->getIOVs(path, iov, channel); + } + return ICondDBReader::IOVList(); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLogger::getChildNodes (const std::string &path, std::vector<std::string> &node_names) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + StatusCode sc = m_loggedReader->getChildNodes(path,node_names); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBLogger::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) +{ + if ( m_loggedReader ) { + (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + StatusCode sc = m_loggedReader->getChildNodes(path,folders,foldersets); + (*m_logFile) << sc << std::endl; + return sc; + } + return StatusCode::FAILURE; +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBLogger::exists(const std::string &path) { + if ( m_loggedReader ) { + (*m_logFile) << "XST: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + bool out = m_loggedReader->exists(path); + (*m_logFile) << out << std::endl; + return out; + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBLogger::isFolder(const std::string &path) { + if ( m_loggedReader ) { + (*m_logFile) << "IFL: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + bool out = m_loggedReader->isFolder(path); + (*m_logFile) << out << std::endl; + return out; + } + return false; +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBLogger::isFolderSet(const std::string &path) { + if ( m_loggedReader ) { + (*m_logFile) << "IFS: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; + bool out = m_loggedReader->isFolderSet(path); + (*m_logFile) << out << std::endl; + return out; + } + return false; +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBLogger::disconnect() { + if ( m_loggedReader ) { + (*m_logFile) << "DIS: " << Gaudi::Time::current().ns() << std::endl; + m_loggedReader->disconnect(); + } +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBLogger::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + if ( m_loggedReader ) { + (*m_logFile) << "TAG: " << Gaudi::Time::current().ns() << std::endl; + m_loggedReader->defaultTags(tags); + } +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLogger.h b/Det/DetCond/src/component/CondDBLogger.h new file mode 100755 index 000000000..d05fc8fd1 --- /dev/null +++ b/Det/DetCond/src/component/CondDBLogger.h @@ -0,0 +1,147 @@ +#ifndef COMPONENT_CONDDBLOGGER_H +#define COMPONENT_CONDDBLOGGER_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "DetCond/ICondDBReader.h" + +template <class TYPE> class SvcFactory; + +/** @class CondDBLogger CondDBLogger.h component/CondDBLogger.h + * + * Logger of acesses to CondDB. + * + * CondDBLogger is a simple class that allow to store in a file all the + * requests made to a ICondDBReader instance. It has to be used as a front-end + * to the instance we want to monitor. + * + * Given the following option snippet + * @code + * MyCondDBUser.Reader = "ACondDBReader"; + * @endcode + * the CondDBLogger can be enabled with + * @code + * CondDBLogger.LoggedReader = "ACondDBReader"; + * MyCondDBUser.Reader = "CondDBLogger"; + * @endcode + * or in python options + * @code + * user = MyCondDBUser() + * user.Reader = CondDBLogger(LoggedReader = user.Reader) + * @endcode + * + * The format of the log file is very simple. Each line starts with an + * operation code then the time of the operation in ns (as returned by + * Gaudi::Time::ns()). The rest of the line depend on the operation: + * - "INI:" + * - Initialization of the logger + * - "TAG:" + * - Request of the used tag + * - "GCH:" + * - Retrieve the child nodes of a folderset. + * - "GET:" + * - Request of an object from the database, the format is<br> + * <path> <channel id> <path> <evt.time> <status> + * - "GCN:" + * - Request of an object from the database using the channel name, the format is<br> + * <path> <channel name> <path> <evt.time> <status> + * - "FIN:" + * - Finalization of the logger + * - "IOV:" + * - Request list of IOVs (using numeric channel) + * - "ICN:" + * - Request list of IOVs (using channel name) + * + * @param LoggedReader + * Fully qualified name of the ICondDBReader to which the calls have to + * be forwarded. + * @param LogFile + * Path to the log file (it is overwritten if it exists). If not + * specified or set to empty, the file name is set from the name of the + * instance plus '.log'. + * + * @author Marco CLEMENCIC + * @date 2008-01-24 + */ +class CondDBLogger: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + +protected: + + /// Standard constructor + CondDBLogger( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBLogger( ); ///< Destructor + +private: + + // -------------------- Data Members + + /// Pointer to the CondDBReader whose activity has to be logged. + ICondDBReader *m_loggedReader; + + /// Name of the CondDBReader whose activity has to be logged. + std::string m_loggedReaderName; + + /// Path to the file that will contain the log. + std::unique_ptr<std::ostream> m_logFile; + + /// Path to the file that will contain the log. + std::string m_logFileName; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBLogger>; + +}; +#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBReplayAlg.cpp b/Det/DetCond/src/component/CondDBReplayAlg.cpp new file mode 100755 index 000000000..101826444 --- /dev/null +++ b/Det/DetCond/src/component/CondDBReplayAlg.cpp @@ -0,0 +1,162 @@ +// Include files + +// from Gaudi +// needed to sleep between two operations +#include "GaudiKernel/Sleep.h" + +#include "DetCond/ICondDBReader.h" +#include <fstream> + +// local +#include "CondDBReplayAlg.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBReplayAlg +// +// Jan 25, 2008 : Marco Clemencic +//----------------------------------------------------------------------------- + +// Declaration of the Algorithm Factory +DECLARE_ALGORITHM_FACTORY( CondDBReplayAlg ) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBReplayAlg::CondDBReplayAlg( const std::string& name, + ISvcLocator* pSvcLocator) + : GaudiAlgorithm ( name , pSvcLocator ) + , m_reader(NULL) +{ + declareProperty("Reader", m_readerName = "CondDBCnvSvc", + "Name of the reader to use to replay the requests."); + declareProperty("LogFile", m_logFileName = "", + "Path to the log file to re-play. " + "If not specified or set to empty, the file name is set from " + "the name of the instance plus '.log'." ); +} +//============================================================================= +// Destructor +//============================================================================= +CondDBReplayAlg::~CondDBReplayAlg() {} + +//============================================================================= +// Initialization +//============================================================================= +StatusCode CondDBReplayAlg::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Initialize" << endmsg; + + const bool create = true; + m_reader = svc<ICondDBReader>(m_readerName,create); + + // Open the input file. + std::unique_ptr<std::istream> logFile(new std::ifstream(m_logFileName.c_str())); + if ( ! logFile->good() ) { + error() << "Problems opening " << m_logFileName << endmsg; + return StatusCode::FAILURE; + } + info() << "File '" << m_logFileName << "' opened for reading." << endmsg; + + // Parse the input file + std::string opcode, tmp; + operation_t operation; + Gaudi::Time last_time; + Gaudi::Time::ValueType tmptime; + while ( ! logFile->eof() ) { + + (*logFile) >> opcode; + if ("GET:" == opcode || "GCN:" == opcode) { // we use this operation... + + operation.use_numeric_channel = ("GET:" == opcode); + + (*logFile) >> tmptime; operation.time = Gaudi::Time(tmptime); + (*logFile) >> operation.node; + (*logFile) >> tmptime; operation.evttime = Gaudi::Time(tmptime); + + if (operation.use_numeric_channel) { + (*logFile) >> operation.channel; + } + else { + (*logFile) >> operation.chn_name; + } + + if ( last_time > operation.time ) { + error() << "Error in the log file: the operation time is not strictly increasing"; + return StatusCode::FAILURE; + } + + //info() << operation.time.ns() << " " << operation.node << " " << operation.evttime.ns() << " " << operation.channel << endmsg; + last_time = operation.time; + m_operations.push_back(operation); + } + // skip the rest of the line + std::getline(*logFile,tmp); + } + info() << "Found " << m_operations.size() << " operations to replay." << endmsg; + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode CondDBReplayAlg::execute() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Execute" << endmsg; + + info() << "Replaying database operations ..." << endmsg; + ICondDBReader::DataPtr data; + std::string descr; + Gaudi::Time since, until; + // replay the operations + Gaudi::Time last_optime, last_time; + bool first = true; + for(list_t::iterator op = m_operations.begin(); op != m_operations.end(); ++op) { + + if ( first ) { + // we do not have to wait for the first operation + first = false; + } else { + // calculate how much we have to sleep + Gaudi::Time::ValueType ns_to_sleep = (op->time.ns() - last_optime.ns()) // time between operations + - (Gaudi::Time::current().ns() - last_time.ns()); // time wasted + + if ( ns_to_sleep > 0 ) Gaudi::NanoSleep(ns_to_sleep); + } + + last_optime = op->time; + + // I have to store the current time before the operation otherwise + // we to not count the time that the operation takes as already elapsed. + last_time = Gaudi::Time::current(); + + // Get the object + if (op->use_numeric_channel) { + m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->channel).ignore(); + } + else { + m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->chn_name).ignore(); + } + + } + info() << "Replay completed." << endmsg; + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode CondDBReplayAlg::finalize() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Finalize" << endmsg; + + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBReplayAlg.h b/Det/DetCond/src/component/CondDBReplayAlg.h new file mode 100755 index 000000000..9eff90934 --- /dev/null +++ b/Det/DetCond/src/component/CondDBReplayAlg.h @@ -0,0 +1,60 @@ +#ifndef CONDDBREPLAYALG_H_ +#define CONDDBREPLAYALG_H_ + +// Include files +// from Gaudi +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/Time.h" +#include <list> + +class ICondDBReader; + +/** @class CondDBReplayAlg CondDBReplayAlg.h + * + * Simple algorithm that reads a file in the format produced by CondDBLogger + * and re-play the request to the database with the same timing written in the + * log file. + * + * @author Marco Clemencic <marco.clemencic@cern.ch> + * @date 2008-01-25 + */ +class CondDBReplayAlg : public GaudiAlgorithm { +public: + /// Standard constructor + CondDBReplayAlg( const std::string& name, ISvcLocator* pSvcLocator ); + + virtual ~CondDBReplayAlg( ); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization + +protected: + +private: + + /// Path to the file containing the log. + std::string m_logFileName; + + /// Name of the reader to use to replay the requests. + std::string m_readerName; + + /// Pointer to the ICondDBReader service. + ICondDBReader *m_reader; + + struct operation_t { + Gaudi::Time time; + std::string node; + Gaudi::Time evttime; + bool use_numeric_channel; + cool::ChannelId channel; + std::string chn_name; + }; + typedef std::list<operation_t> list_t; + + /// List of operations to perform + list_t m_operations; + +}; + +#endif /*CONDDBREPLAYALG_H_*/ diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp new file mode 100755 index 000000000..f4701c43f --- /dev/null +++ b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp @@ -0,0 +1,135 @@ +// Include files +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/Property.h" +#include "GaudiKernel/IJobOptionsSvc.h" +#include "GaudiKernel/ThreadGaudi.h" + +#include "boost/filesystem/path.hpp" +#include "boost/filesystem/operations.hpp" +#include "boost/filesystem/exception.hpp" + +// local +#include "CondDBSQLiteCopyAccSvc.h" + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBSQLiteCopyAccSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBSQLiteCopyAccSvc +// +// 2007-03-22 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBSQLiteCopyAccSvc::CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ): + CondDBAccessSvc(name,svcloc) +{ + declareProperty("OriginalFile", m_source_path = "" ); + declareProperty("DestinationFile", m_dest_path = "" ); + declareProperty("DBName", m_dbname = "" ); + declareProperty("ForceCopy", m_force_copy = false ); + declareProperty("IgnoreCopyError", m_ignore_copy_error = false ); +} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBSQLiteCopyAccSvc::initialize(){ + //before initializing the parent, I have to copy the file + StatusCode sc = setProperties(); + if ( ! sc.isSuccess() ) { + MsgStream log(msgSvc(), name() ); + log << MSG::ERROR << "Failed to set properties" << endmsg; + return sc; + } + + // this should be done after getting the properties + MsgStream log(msgSvc(), name() ); + + // preliminary checks on the options + if ( m_source_path.empty() ) { + log << MSG::ERROR << "You must provide the source file path via the option '" + << name() << ".OriginalFile'" << endmsg; + return StatusCode::FAILURE; + } + if ( m_dest_path.empty() ) { + log << MSG::ERROR << "You must provide the destination file path via the option '" + << name() << ".DestinationFile'" << endmsg; + return StatusCode::FAILURE; + } + if ( m_dbname.empty() ) { + log << MSG::ERROR << "You must provide the database name via the option '" + << name() << ".DBName'" << endmsg; + return StatusCode::FAILURE; + } + + try { + + // if "force" mode is selected: remove the destination file if it exists + if ( m_force_copy ) { + bool file_existed = boost::filesystem::remove( m_dest_path ); + if ( file_existed ) { + log << MSG::WARNING << "Removed file '" << m_dest_path << "' to replace it" << endmsg; + } + } + + // copy the source file + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Copying " + << m_source_path << " -> " + << m_dest_path << endmsg; + boost::filesystem::copy_file(m_source_path,m_dest_path); + + } + catch (boost::filesystem::filesystem_error &e){ + + MSG::Level lvl = MSG::ERROR; + if ( m_ignore_copy_error ) lvl = MSG::WARNING; + + log << lvl << "Problems occurred copying the file" << endmsg; + log << lvl << e.what() << endmsg; + if ( ! m_ignore_copy_error ) + return StatusCode::FAILURE; + } + + /* + // I need to override the connection string property + IJobOptionsSvc* jos; + const bool CREATEIF(true); + sc = serviceLocator()->service( "JobOptionsSvc", jos, CREATEIF ); + if( sc.isFailure() ) { + log << MSG::ERROR << "Service JobOptionsSvc not found" << endmsg; + } + + sc = jos->addPropertyToCatalogue( getGaudiThreadGenericName(name()), + StringProperty( "ConnectionString", + "sqlite_file:" + m_dest_path + "/" + m_dbname) ); + jos->release(); + if ( ! sc.isSuccess() ) { + log << MSG::ERROR << "Failed to override the property '" << name() << ".ConnectionString'"<< endmsg; + return sc; + } + */ + + // Set the connection string to be used (the one from the base class will be ignored). + m_sqlite_connstring = "sqlite_file:" + m_dest_path + "/" + m_dbname; + + // Initialize the base class. + return CondDBAccessSvc::initialize(); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBSQLiteCopyAccSvc::~CondDBSQLiteCopyAccSvc() {} + +//============================================================================= +// Return the connection string used to connect to the database. +//============================================================================= +const std::string &CondDBSQLiteCopyAccSvc::connectionString() const { + return m_sqlite_connstring; +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h new file mode 100755 index 000000000..1daecf30c --- /dev/null +++ b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h @@ -0,0 +1,55 @@ +#ifndef COMPONENT_CONDDBSQLITECOPYACCSVC_H +#define COMPONENT_CONDDBSQLITECOPYACCSVC_H 1 + +// Include files +#include "CondDBAccessSvc.h" + +/** @class CondDBSQLiteCopyAccSvc CondDBSQLiteCopyAccSvc.h component/CondDBSQLiteCopyAccSvc.h + * + * Extension to CondDBAccessSvc SQLite specific. The original SQLite file is copied to + * a different direcory before being used. This is particularily helpful when the original + * file is accessible only via NFS (see http://www.sqlite.org/faq.html#q7 for details). + * + * @author Marco Clemencic + * @date 2007-03-22 + */ +class CondDBSQLiteCopyAccSvc: public CondDBAccessSvc { + +public: + + /// Initilize the service + virtual StatusCode initialize(); + + /// Return the connection string used to connect to the database. + virtual const std::string &connectionString() const; + + +protected: + /// Standard constructor + CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBSQLiteCopyAccSvc( ); ///< Destructor + +private: + + /// Path to the original file + std::string m_source_path; + /// Path to destination file + std::string m_dest_path; + /// COOL database name + std::string m_dbname; + + /// Whether to overwrite the destination file. + bool m_force_copy; + /// Whether ingore copy error (e.g. if the destination file exists, try to use it) + bool m_ignore_copy_error; + + /// Needed to avoid interference with the connection string set by CondDBAccessSvc + /// standard options (we need to overwrite it). + std::string m_sqlite_connstring; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBSQLiteCopyAccSvc>; + +}; +#endif // COMPONENT_CONDDBSQLITECOPYACCSVC_H diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp b/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp new file mode 100755 index 000000000..7df80596a --- /dev/null +++ b/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp @@ -0,0 +1,363 @@ +// Include files +#ifdef WIN32 // Hacks to compile on Windows... +#define NOMSG +#define NOGDI +#define max max +#endif + +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/Time.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "GaudiKernel/IDetDataSvc.h" + +// local +#include "CondDBTimeSwitchSvc.h" +#include "CondDBCommon.h" + + +// Factory implementation +DECLARE_SERVICE_FACTORY(CondDBTimeSwitchSvc) + +//----------------------------------------------------------------------------- +// Implementation file for class : CondDBTimeSwitchSvc +// +// 2006-07-10 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +// This is needed otherwise the implementation of std::map does +// not find operator<(Gaudi::Time,Gaudi::Time). +namespace Gaudi { using ::operator<; } +//============================================================================= +// Code copied from GaudiKernel Parsers, to have a parser for +// pair<long long,long long>. +// ============================================================================ +// GaudiKernel +// ============================================================================ +// 2011-08-26 : alexander.mazurov@gmail.com +#include "GaudiKernel/ParsersFactory.h" +namespace { + StatusCode parse(std::pair<long long,long long>& result, + const std::string& input){ + return Gaudi::Parsers::parse_(result, input); + } +} +//============================================================================= + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +CondDBTimeSwitchSvc::CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ): + base_class(name,svcloc), + m_readersDeclatations(), + m_readers(), + m_latestReaderRequested(0), + m_dds(0) +{ + + // "'CondDBReader':(since, until)", with since and until doubles + declareProperty("Readers", m_readersDeclatations); + + declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, + "Allow direct mapping from CondDB structure to" + " transient store."); +} + +//============================================================================= +// Destructor +//============================================================================= +CondDBTimeSwitchSvc::~CondDBTimeSwitchSvc() {} + +//============================================================================= +// initialize +//============================================================================= +StatusCode CondDBTimeSwitchSvc::initialize(){ + StatusCode sc = base_class::initialize(); + if (sc.isFailure()) return sc; + + MsgStream log(msgSvc(), name() ); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Initialize" << endmsg; + + if (m_readersDeclatations.empty()) { + log << MSG::ERROR << "No CondDBReader has been specified" + " (property 'Readers')." << endmsg; + return StatusCode::FAILURE; + } + + // decoding the property "Readers" + std::string reader_name, reader_siov; + std::pair<long long,long long> reader_iov; + for (ReadersDeclatationsType::iterator rd = m_readersDeclatations.begin(); + rd != m_readersDeclatations.end(); ++rd){ + // first step of parsing (split "'name':value" -> "name","value") + sc = Gaudi::Parsers::parse(reader_name,reader_siov,*rd); + if (sc.isSuccess()) { + // second step (only if first passed) + sc = ::parse(reader_iov,reader_siov); + } + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot decode string '" << *rd << "'" << endmsg; + return sc; + } + // Check for overlaps + const bool quiet = true; + ReaderInfo *old = readerFor(reader_iov.first,quiet); + if (!old) old = readerFor(reader_iov.second,quiet); + if (old) { + log << MSG::ERROR << "Conflicting IOVs between '" << old->name << "':(" + << old->since.ns() << "," << old->until.ns() << ") and " + << *rd << endmsg; + return StatusCode::FAILURE; + } + // use "until" as key to be able to search with "upper_bound" + ReaderInfo ri(reader_name, reader_iov.first, reader_iov.second); + m_readers.insert(std::make_pair(ri.until,ri)); + } + if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { + log << MSG::DEBUG << "Configured CondDBReaders:" << endmsg; + ReadersType::iterator r; + for (r = m_readers.begin(); r != m_readers.end(); ++r) { + log << MSG::DEBUG << " " << r->second.since << " - " << r->second.until + << ": " << r->second.name << endmsg; + } + } + // we need to reset it because it got corrupted during the + // check for overlaps + m_latestReaderRequested = 0; + + return sc; +} + +//============================================================================= +// finalize +//============================================================================= +StatusCode CondDBTimeSwitchSvc::finalize(){ + if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { + MsgStream log(msgSvc(), name()); + log << MSG::DEBUG << "Finalize" << endmsg; + } + + // release all the loaded CondDBReader services + m_readers.clear(); + if(m_dds) { + m_dds->release(); + m_dds = 0; + } + m_readersDeclatations.clear(); + m_latestReaderRequested = 0; + + return base_class::finalize(); +} + +//========================================================================= +// find the appropriate reader +//========================================================================= +CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::readerFor(const Gaudi::Time &when, bool quiet) { + MsgStream log(msgSvc(), name()); + + if (!quiet) log << MSG::VERBOSE << "Get CondDBReader for event time " << when << endmsg; + + // TODO: (MCl) if we change service, we may clear the cache of the one + // that is not needed. + if ((!m_latestReaderRequested) || !m_latestReaderRequested->isValidAt(when)){ + // service not valid: search for the correct one + + // Find the element with key ("until") greater that the requested one + ReadersType::iterator reader = m_readers.upper_bound(when); + if (reader != m_readers.end() && reader->second.isValidAt(when)){ + m_latestReaderRequested = &(reader->second); + } else { + m_latestReaderRequested = 0; // reader not found + if (!quiet) log << MSG::WARNING << "No reader configured for requested event time" << endmsg; + } + } + + return m_latestReaderRequested; +} + +//========================================================================= +// get the current time +//========================================================================= +Gaudi::Time CondDBTimeSwitchSvc::getTime() { + if (!m_dds) { + StatusCode sc = service("DetectorDataSvc",m_dds,false); + if (sc.isFailure()) { + MsgStream log(msgSvc(), name()); + log << MSG::WARNING << "Cannot find the DetectorDataSvc," + " using a default event time (0)" << endmsg; + return Gaudi::Time(); + } + } + return m_dds->eventTime(); +} + +//========================================================================= +// get the current reader +//========================================================================= +CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::currentReader() { + if (!m_latestReaderRequested) { + // Let's stay on the safe side if we don't find a reader + if (readerFor(getTime()) == 0) { + throw GaudiException("No reader configured for current event time", + "CondDBTimeSwitchSvc::currentReader",StatusCode::FAILURE); + } + } + return m_latestReaderRequested; +} + +//========================================================================= +// retrieve an object +//========================================================================= +StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, + const Gaudi::Time &when, + DataPtr &data, + std::string &descr, + Gaudi::Time &since, + Gaudi::Time &until, + cool::ChannelId channel) { + // get the reader for the requested time + ReaderInfo *ri = readerFor(when); + if (!ri) return StatusCode::FAILURE; + + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); + if (sc.isSuccess()) ri->cutIOV(since,until); + } + return sc; +} +StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, + const Gaudi::Time &when, + DataPtr &data, + std::string &descr, + Gaudi::Time &since, + Gaudi::Time &until, + const std::string &channel) { + // get the reader for the requested time + ReaderInfo *ri = readerFor(when); + if (!ri) return StatusCode::FAILURE; + + StatusCode sc; + if (m_xmlDirectMapping && isFolderSet(path)) { + descr = "Catalog generated automatically by " + name(); + since = Gaudi::Time::epoch(); + until = Gaudi::Time::max(); + sc = CondDB::generateXMLCatalog(this,path,data); + } else { + sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); + if (sc.isSuccess()) ri->cutIOV(since,until); + } + return sc; + +} + +template <typename Channel> +ICondDBReader::IOVList CondDBTimeSwitchSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) +{ + IOVList iovs; + + IOV tmp; + + // get the list of readers valid in the given time IOV + ReadersType::iterator r; + for(r = m_readers.begin(); r != m_readers.end(); ++r) { + if (r->second.until <= iov.since) continue; // ignore readers before... + if (r->second.since >= iov.until) break; // ...and after the request + + tmp.since = std::max(iov.since, r->second.since); + tmp.until = std::min(iov.until, r->second.until); + + IOVList new_iovs = r->second.reader(serviceLocator())->getIOVs(path, tmp, channel); + if (!new_iovs.empty()) { + // trim the IOVs found + new_iovs.front().since = std::max(tmp.since, new_iovs.front().since); + new_iovs.back().until = std::min(tmp.until, new_iovs.back().until); + + iovs.insert(iovs.end(), new_iovs.begin(), new_iovs.end()); + } + } + return iovs; +} + +ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) +{ + return i_getIOVs(path, iov, channel); +} + +ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) +{ + return i_getIOVs(path, iov, channel); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { + return getChildNodes(path,node_names,node_names); +} + +//========================================================================= +// get the list of child nodes of a folderset +//========================================================================= +StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets) { + // clear the destination vectors + folders.clear(); + foldersets.clear(); + + // delegate to the current Reader (hoping that is good enough) + return currentReader()->reader(serviceLocator())->getChildNodes(path,folders,foldersets); +} + +//========================================================================= +// Tells if the path is available in the database. +//========================================================================= +bool CondDBTimeSwitchSvc::exists(const std::string &path) { + return currentReader()->reader(serviceLocator())->exists(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folder. +//========================================================================= +bool CondDBTimeSwitchSvc::isFolder(const std::string &path) { + return currentReader()->reader(serviceLocator())->isFolder(path); +} + +//========================================================================= +// Tells if the path (if it exists) is a folderset. +//========================================================================= +bool CondDBTimeSwitchSvc::isFolderSet(const std::string &path) { + return currentReader()->reader(serviceLocator())->isFolderSet(path); +} + +//========================================================================= +// Force disconnection from database. +//========================================================================= +void CondDBTimeSwitchSvc::disconnect() { + // loop over all readers + ReadersType::const_iterator reader; + for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { + if (reader->second.loaded()) + reader->second.reader(serviceLocator())->disconnect(); + } +} + +//========================================================================= +// Collect the list of used tags and databases +//========================================================================= +void CondDBTimeSwitchSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { + // loop over all readers + ReadersType::const_iterator reader; + for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { + reader->second.reader(serviceLocator())->defaultTags(tags); + } +} + +//============================================================================= diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.h b/Det/DetCond/src/component/CondDBTimeSwitchSvc.h new file mode 100755 index 000000000..c1eecb386 --- /dev/null +++ b/Det/DetCond/src/component/CondDBTimeSwitchSvc.h @@ -0,0 +1,198 @@ +#ifndef COMPONENT_CONDDBTIMESWITCHSVC_H +#define COMPONENT_CONDDBTIMESWITCHSVC_H 1 + +// Include files +#include "GaudiKernel/Service.h" +#include "GaudiKernel/Map.h" +#include "DetCond/ICondDBReader.h" +#include <vector> +#include <map> + +template <class TYPE> class SvcFactory; +class IDetDataSvc; + +/** @class CondDBTimeSwitchSvc CondDBTimeSwitchSvc.h component/CondDBTimeSwitchSvc.h + * + * + * + * @author Marco Clemencic + * @date 2006-07-10 + */ +class CondDBTimeSwitchSvc: public extends1<Service, ICondDBReader> { +public: + /// Initialize COOL (CondDB) Access Layer Service + virtual StatusCode initialize(); + /// Finalize Service + virtual StatusCode finalize(); + + // --------- ICondDBReader implementation + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); + + /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, + /// channel and when are ignored and data is set ot NULL. + virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, + DataPtr &data, + std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); + + /// @{ + /// @see ICondDBReader::getIOVs + virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); + virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); + /// @} + + /// Retrieve the names of the children nodes of a FolderSet. + virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); + + /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. + virtual StatusCode getChildNodes (const std::string &path, + std::vector<std::string> &folders, + std::vector<std::string> &foldersets); + + /// Tells if the path is available in the database. + virtual bool exists(const std::string &path); + + /// Tells if the path (if it exists) is a folder. + virtual bool isFolder(const std::string &path); + + /// Tells if the path (if it exists) is a folderset. + virtual bool isFolderSet(const std::string &path); + + /// Disconnect from the database. + virtual void disconnect(); + + // --------- ICondDBInfo implementation + + /** Get the current default database tags + * @param tags vector of DB name, tag pairs. Empty if DB not available + */ + virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; + + +protected: + /// Standard constructor + CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ); + + virtual ~CondDBTimeSwitchSvc( ); ///< Destructor + + +private: + + /// Internal class to record the readers + struct ReaderInfo { + /// CondDBReader instance name ("type/name") + std::string name; + /// Boundaries of the Interval Of Validity + Gaudi::Time since, until; + /// Default Constructor + ReaderInfo(const std::string &_n, + Gaudi::Time _s = Gaudi::Time::epoch(), + Gaudi::Time _u = Gaudi::Time::max()): + name(_n), + since(_s), + until(_u), + m_reader(0) + {} + /// Default Constructor + ReaderInfo(const std::string &_n, Gaudi::Time::ValueType _s, Gaudi::Time::ValueType _u): + name(_n), + since(_s), + until(_u), + m_reader(0) + {} + /// Copy constructor (for a correct reference counting). + ReaderInfo(const ReaderInfo &_ri): + name(_ri.name), + since(_ri.since), + until(_ri.until), + m_reader(_ri.m_reader) + { + if (m_reader) m_reader->addRef(); + } + /// Destructor (releases the CondDBReader service). + ~ReaderInfo(){ + if (m_reader) m_reader->release(); + } + /// Shortcut to check the validity of the reader + bool isValidAt(const Gaudi::Time &when) const { + return since <= when && until > when; + } + /// Shortcut to retrieve the pointer to the reader service. + ICondDBReader *reader(ISvcLocator *svcloc) const { + if (!m_reader) { + if (!svcloc) + throw GaudiException("ServiceLocator pointer is NULL", + "CondDBTimeSwitchSvc::ReaderInfo::get",StatusCode::FAILURE); + StatusCode sc = svcloc->service(name,m_reader,true); + if (sc.isFailure()) + throw GaudiException("Cannot get ICondDBReader '"+name+"'", + "CondDBTimeSwitchSvc::ReaderInfo::get",sc); + } + return m_reader; + } + /// Shortcut to restrict and IOV to the boundaries defined for the reader + void cutIOV(Gaudi::Time &_since, Gaudi::Time &_until) const { + if ( since > _since ) _since = since; + if ( until < _until ) _until = until; + } + /// convert to a string + std::string toString() const; + /// tell if the reader has already been instantiated + bool loaded() const { + return m_reader; + } + private: + /// Pointer to the CondDBReader instance + mutable ICondDBReader *m_reader; + }; + + /// Get the the CondDBReader valid for a given point in time. + /// Returns 0 if no service is available. + /// The boolean flag is used to avoid messages (during initialization). + ReaderInfo *readerFor(const Gaudi::Time &when, bool quiet = false); + + /// Get the the CondDBReader valid for a given point in time. + /// Returns 0 if no service is available + ReaderInfo *currentReader(); + + /// Get current event time from the detector data svc. + Gaudi::Time getTime(); + + // -------------------- Data Members + typedef std::vector<std::string> ReadersDeclatationsType; + typedef GaudiUtils::Map<Gaudi::Time,ReaderInfo> ReadersType; + + /// Property CondDBTimeSwitchSvc.Readers: list of ICondDBReaders to be used + /// for given intervals of validity. The format is "'Reader': (since, until)", + /// where since and until are doubles defining the time in standard units. + ReadersDeclatationsType m_readersDeclatations; + + /// Container for the alternatives. The ReaderInfo objects are indexed by + /// "until" to allow efficient search with map::upper_bound. + ReadersType m_readers; + + /// Pointer used to cache the latest requested reader. + /// It allows to avoid the search. + ReaderInfo *m_latestReaderRequested; + + /// Pointer to the detector data service, used to get the event time in + /// the methods that do not require it as argument. + /// It used only if there was not a previous request with the time. + IDetDataSvc *m_dds; + + /// Enable/disable direct mapping from the database structure to the transient + /// store using XML persistency format (enabled by default). + bool m_xmlDirectMapping; + + /// Allow SvcFactory to instantiate the service. + friend class SvcFactory<CondDBTimeSwitchSvc>; + + /// Internal implementation helper to generalize the channel type. + template <typename Channel> + IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); +}; +#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/IOVListHelpers.cpp b/Det/DetCond/src/component/IOVListHelpers.cpp new file mode 100644 index 000000000..62ede6d93 --- /dev/null +++ b/Det/DetCond/src/component/IOVListHelpers.cpp @@ -0,0 +1,23 @@ +#include "IOVListHelpers.h" + +namespace IOVListHelpers { + ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov) { + + ICondDBReader::IOVList result; + + Gaudi::Time last = iov.since; // keep track of the end of coverage + // loop over covering interval + for (const auto& covered : data ) { + if (covered.since > last) { // hole between the end of coverage and begin of next IOV + result.emplace_back(last, covered.since); + } + last = covered.until; // prepare to look for the next hole + } + if (last < iov.until) { + // we didn't get anything to cover until the end of the requested IOV + result.emplace_back(last, iov.until); + } + + return result; + } +} diff --git a/Det/DetCond/src/component/IOVListHelpers.h b/Det/DetCond/src/component/IOVListHelpers.h new file mode 100644 index 000000000..d660cf962 --- /dev/null +++ b/Det/DetCond/src/component/IOVListHelpers.h @@ -0,0 +1,10 @@ +#ifndef IOVLISTHELPERS_H +#define IOVLISTHELPERS_H +#include "DetCond/ICondDBReader.h" + +namespace IOVListHelpers { + /// Find the intervals in passed interval that are not covered by the provided. + ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov); +} + +#endif diff --git a/Det/DetCond/src/component/LoadDDDB.cpp b/Det/DetCond/src/component/LoadDDDB.cpp new file mode 100755 index 000000000..08beaac28 --- /dev/null +++ b/Det/DetCond/src/component/LoadDDDB.cpp @@ -0,0 +1,101 @@ +// Include files + +// from Gaudi +#include "GaudiKernel/DataStoreItem.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/GaudiException.h" + +// from LHCb +#include "Kernel/ICondDBInfo.h" + +// local +#include "LoadDDDB.h" + +//----------------------------------------------------------------------------- +// Implementation file for class : LoadDDDB +// +// 2005-10-14 : Marco Clemencic +//----------------------------------------------------------------------------- + +// Declaration of the Algorithm Factory +DECLARE_ALGORITHM_FACTORY( LoadDDDB ) + + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +LoadDDDB::LoadDDDB( const std::string& name, + ISvcLocator* pSvcLocator) + : GaudiAlgorithm ( name , pSvcLocator ) +{ + declareProperty("Node", m_treeToLoad = "/dd*"); +} +//============================================================================= +// Destructor +//============================================================================= +LoadDDDB::~LoadDDDB() {} + +//============================================================================= +// Initialization +//============================================================================= +StatusCode LoadDDDB::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) + debug() << "==> Initialize" << endmsg; + + std::vector<LHCb::CondDBNameTagPair> tmp; + svc<ICondDBInfo>("CondDBCnvSvc",true)->defaultTags(tmp); + + std::vector<LHCb::CondDBNameTagPair>::iterator db; + for ( db = tmp.begin(); db != tmp.end(); ++db ) { + info() << "Database " << db->first << " tag " << db->second << endmsg; + } + + updMgrSvc(); // trigger the initialization of the Condition Update sub-system + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode LoadDDDB::execute() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Execute" << endmsg; + + info() << "Loading the DDDB" << endmsg; + + try { + detSvc()->addPreLoadItem(m_treeToLoad); + detSvc()->preLoad(); + } catch (GaudiException &x) { + fatal() << "Gaught GaudiException" << endmsg; + int i = 0; + for ( GaudiException *ex = &x; 0 != ex; ex = ex->previous() ) { + fatal() << std::string(i++,' ') << " ==> " << ex->what() << endmsg; + } + return StatusCode::FAILURE; + } catch (std::exception &x) { + fatal() << "Gaught exception '" << System::typeinfoName(typeid(x)) << "'" + << endmsg; + fatal() << " ==> " << x.what() << endmsg; + return StatusCode::FAILURE; + } catch (...) { + fatal() << "Gaught unknown exception!!" << endmsg; + return StatusCode::FAILURE; + } + info() << "done." << endmsg; + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode LoadDDDB::finalize() { + + if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Finalize" << endmsg; + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +//============================================================================= diff --git a/Det/DetCond/src/component/LoadDDDB.h b/Det/DetCond/src/component/LoadDDDB.h new file mode 100755 index 000000000..584e4f0ac --- /dev/null +++ b/Det/DetCond/src/component/LoadDDDB.h @@ -0,0 +1,35 @@ +#ifndef LOADDDDB_H +#define LOADDDDB_H 1 + +// Include files +// from Gaudi +#include "GaudiAlg/GaudiAlgorithm.h" + + +/** @class LoadDDDB LoadDDDB.h + * + * Load entries in the detector transient store using IDataSvc::preLoad(). + * The node to be loaded is set with the option LoadDDDB.Node. + * + * @author Marco Clemencic + * @date 2005-10-14 + */ +class LoadDDDB : public GaudiAlgorithm { +public: + /// Standard constructor + LoadDDDB( const std::string& name, ISvcLocator* pSvcLocator ); + + virtual ~LoadDDDB( ); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization + +protected: + +private: + + std::string m_treeToLoad; + +}; +#endif // LOADDDDB_H diff --git a/Det/DetCond/src/component/RelyConverter.cpp b/Det/DetCond/src/component/RelyConverter.cpp new file mode 100755 index 000000000..f9b5b8a11 --- /dev/null +++ b/Det/DetCond/src/component/RelyConverter.cpp @@ -0,0 +1,479 @@ +// Include files +#include "RelyConverter.h" + +#include "GaudiKernel/IConversionSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/IOpaqueAddress.h" +#include "GaudiKernel/IRegistry.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/DataObject.h" +#include "GaudiKernel/Time.h" +#include "GaudiKernel/IDataManagerSvc.h" + +#include "DetDesc/ValidDataObject.h" + +#include "CoolKernel/IObject.h" +#include "CoolKernel/IRecord.h" +#include "CoolKernel/RecordException.h" + +#include <string> +#include <sstream> + +// local + +//----------------------------------------------------------------------------- +// Implementation file for class : RelyConverter +// +// 2004-12-03 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------- +// Instantiation of a static factory class used by clients to create +// instances of this service +// ----------------------------------------------------------------------- +DECLARE_CONVERTER_FACTORY(RelyConverter) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +RelyConverter::RelyConverter(ISvcLocator* svc): + CondDBGenericCnv(svc,RelyConverter::classID()), + m_detPersSvc(NULL) +{} +//============================================================================= +// Destructor +//============================================================================= +RelyConverter::~RelyConverter() {} + +//========================================================================= +// Initialization +//========================================================================= +StatusCode RelyConverter::initialize() { + // Initializes the grand father + StatusCode sc = CondDBGenericCnv::initialize(); + + sc = serviceLocator()->service("DetectorPersistencySvc", m_detPersSvc, true); + if ( !sc.isSuccess() ) { + MsgStream log(msgSvc(),"RelyConverter"); + log << MSG::ERROR << "Cannot locate IConversionSvc interface of DetectorPersistencySvc" << endmsg; + return sc; + } else { + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Retrieved IConversionSvc interface of DetectorPersistencySvc" << endmsg; + } + return sc; +} + +//========================================================================= +// Finalization +//========================================================================= +StatusCode RelyConverter::finalize() { + m_detPersSvc->release(); + return CondDBGenericCnv::finalize(); +} + +//========================================================================= +// Create the transient representation +//========================================================================= +StatusCode RelyConverter::createObj (IOpaqueAddress* pAddress, DataObject *&pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering createObj" << endmsg; + + StatusCode sc = i_delegatedCreation(pAddress,pObject,CreateObject); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot create the object " << pAddress->registry()->identifier() << endmsg; + return sc; + } + + return StatusCode::SUCCESS; +} + +//========================================================================= +// Fill references of the transient representation +//========================================================================= +StatusCode RelyConverter::fillObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering fillObjRefs" << endmsg; + + StatusCode sc = i_delegatedCreation(pAddress,pObject,FillObjectRefs); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot fill object's refs" << endmsg; + return sc; + } + + return StatusCode::SUCCESS; +} + +//========================================================================= +// Update transient representation from persistent one +//========================================================================= +StatusCode RelyConverter::updateObj (IOpaqueAddress* pAddress, DataObject* pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Method updateObj starting" << endmsg; + + DataObject* pNewObject; // create a new object and copy it to the old version + StatusCode sc = i_delegatedCreation(pAddress,pNewObject,CreateObject); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot create the new object" << endmsg; + return sc; + } + + // do the real update + // + // Since DataObject::operator= operator is not virtual, dynamic cast first! + // Overloaded virtual method Condition::update() must be properly defined! + // The memory pointed to by the old pointer must contain the new object + // Andrea Valassi + + ValidDataObject* pVDO = dynamic_cast<ValidDataObject*>(pObject); + ValidDataObject* pNewVDO = dynamic_cast<ValidDataObject*>(pNewObject); + if ( 0 == pVDO || 0 == pNewVDO ) { + log << MSG::ERROR + << "Cannot update objects other than ValidDataObject: " + << "update() must be defined!" + << endmsg; + return StatusCode::FAILURE; + } + // Deep copy the new Condition into the old DataObject + pVDO->update( *pNewVDO ); + + // Delete the useless Condition + delete pNewVDO; + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Object successfully updated" << endmsg; + return StatusCode::SUCCESS; +} + +//========================================================================= +// Update references of the transient representation +//========================================================================= +StatusCode RelyConverter::updateObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) +{ + MsgStream log(msgSvc(),"RelyConverter"); + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "entering updateObjRefs" << endmsg; + + StatusCode sc = i_delegatedCreation(pAddress,pObject,UpdateObjectRefs); + if (sc.isFailure()){ + log << MSG::ERROR << "Cannot update object's refs" << endmsg; + return sc; + } + + return StatusCode::SUCCESS; +} + +//========================================================================= +// Create the persistent representation +//========================================================================= +StatusCode RelyConverter::createRep (DataObject* /*pObject*/, IOpaqueAddress*& /*pAddress*/) +{ + MsgStream log(msgSvc(),"RelyConverter"); + log << MSG::WARNING << "createRep() not implemented" << endmsg; + return StatusCode::SUCCESS; +} + +//========================================================================= +// Update the persistent representation +//========================================================================= +StatusCode RelyConverter::updateRep (IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) +{ + MsgStream log(msgSvc(),"RelyConverter"); + log << MSG::WARNING << "updateRep() not implemented" << endmsg; + return StatusCode::SUCCESS; +} + +//========================================================================= +// Create an object by delegation +//========================================================================= +StatusCode RelyConverter::i_delegatedCreation(IOpaqueAddress* pAddress, DataObject *&pObject, Operation op){ + StatusCode sc; + + MsgStream log(msgSvc(),"RelyConverter"); + + ICondDBReader::DataPtr data; + std::string description; + Gaudi::Time since,until; + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Entering \"i_delegatedCreation\"" << endmsg; + + std::string path = pAddress->par()[0]; + std::string data_field_name = "data"; + + // Extract the COOL field name from the condition path + std::string::size_type at_pos = path.find('@'); + if ( at_pos != path.npos ) { + std::string::size_type slash_pos = path.rfind('/',at_pos); + if ( slash_pos+1 < at_pos ) { // item name is not null + data_field_name = path.substr(slash_pos+1,at_pos - (slash_pos +1)); + } // if I have "/@", I should use the default ("data") + // always remove '@' from the path + path = path.substr(0,slash_pos+1) + path.substr(at_pos+1); + } + + sc = getObject(path, pAddress->ipar()[0], data, description, since, until); + if ( !sc.isSuccess() ) return sc; + + if ( !data ) { + switch (op) { + case CreateObject: + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Path points to a FolderSet: create a directory" << endmsg; + + // I hit a FolderSet!!! I handle it here (at least for the moment, since it's the only CondDB real converter) + pObject = new DataObject(); + + break; + + case FillObjectRefs: + { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Create addresses for sub-folders" << endmsg; + + // find subnodes + std::vector<std::string> children; + + sc = getChildNodes(path,children); + if ( !sc.isSuccess() ) return sc; + + // add registries for the sub folders + for ( std::vector<std::string>::iterator c = children.begin(); c != children.end(); ++c ) { + + IOpaqueAddress *childAddress; + std::string par[2]; + // in current implementation, the child folders have a '/' in front. + // So I need to treat in a different way the case of a parent COOL root folderset + // to avoid thing like "//folder" + if ( path == "/" ) { + par[0] = *c; + } else { + par[0] = path + *c; + } + par[1] = *c; + unsigned long ipar[2] = { 0,0 }; + + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Create address for " << par[0] << endmsg; + sc = conversionSvc()->addressCreator()->createAddress(CONDDB_StorageType, + CLID_Catalog, + par, + ipar, + childAddress); + if ( !sc.isSuccess() ) return sc; + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Address created" << endmsg; + + sc = dataManager()->registerAddress(pAddress->registry(), *c, childAddress); + if ( !sc.isSuccess() ) return sc; + if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) + log << MSG::VERBOSE << "Address registered" << endmsg; + } + } + break; + + case UpdateObjectRefs: + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Update references not supported for FolderSet" << endmsg; + break; + } + + return StatusCode::SUCCESS; + } + + long storage_type = getStorageType(path,description); + if (storage_type <= 0) { + log << MSG::ERROR << + "Folder description does not contain a valid storage type: " << endmsg; + log << MSG::ERROR << "desc = \"" << description << "\"" << endmsg; + return StatusCode::FAILURE; + } + + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "delegate to DetectorPersistencySvc" << endmsg; + + std::string xml_data; + try { + xml_data = (*data.get())[data_field_name].data<std::string>(); + } catch (cool::RecordSpecificationUnknownField &e) { + log << MSG::ERROR << "I cannot find the data inside COOL object: " << e.what() << endmsg; + return StatusCode::FAILURE; + } + + // for XML string temporary address, I need a way to know which is the originating href + std::ostringstream src_href; + src_href << "conddb:" << pAddress->par()[0] << ":" << pAddress->ipar()[0]; + + // Create temporary address for the relevant type and classID + IOpaqueAddress *tmpAddress = createTmpAddress(src_href.str(), + storage_type, + pAddress->par()[1], + pAddress->clID(), + xml_data, + log, + conversionSvc()->addressCreator()); + if (!tmpAddress) return StatusCode::FAILURE; + + tmpAddress->addRef(); + if ( pAddress->registry() ){ + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "register tmpAddress to registry " << pAddress->registry()->identifier() + << endmsg; + } else { + log << MSG::WARNING << "the address does not have a registry" << endmsg; + } + tmpAddress->setRegistry(pAddress->registry()); + if (tmpAddress->registry()) { + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "tmpAddress registered to registry " << tmpAddress->registry()->identifier() + << endmsg; + } else { + log << MSG::WARNING << "tmpAddress not registered!" << endmsg; + } + + switch (op) { + case CreateObject: + sc = m_detPersSvc->createObj ( tmpAddress, pObject ); + break; + case FillObjectRefs: + sc = m_detPersSvc->fillObjRefs ( tmpAddress, pObject ); + break; + case UpdateObjectRefs: + sc = m_detPersSvc->updateObjRefs ( tmpAddress, pObject ); + break; + } + + tmpAddress->release(); + if ( sc.isFailure() ) { + log << MSG::ERROR + << "Persistency service could not create a new object" << endmsg; + return sc; + } + + if (op == CreateObject){ + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "Setting object validity" << endmsg; + setObjValidity(since,until,pObject); + + } + if( UNLIKELY( log.level() <= MSG::DEBUG ) ) + log << MSG::DEBUG << "New object successfully created" << endmsg; + + return StatusCode::SUCCESS; +} + +//============================================================================= + +long RelyConverter::getStorageType(const std::string &path, const std::string &desc){ + // the description string should contain a substring of the form (regexp) + // "< *storage_type *= *[0-9]+ *>" + + if ( path.rfind(".xml") != path.npos ) return XML_StorageType; + + const char delimiter_begin = '<'; + const char delimiter_end = '>'; + const char delimiter_sep = '='; + const std::string delimiter_keyword = "storage_type"; + + std::string::size_type pos_start; + std::string::size_type pos_end; + std::string::size_type pos_max; + + pos_start = pos_end = pos_max = desc.size(); + + std::string::size_type tmp_pos = 0; + + while ( pos_start == pos_max || pos_end <= pos_start ){ + // find the next occurrence of '<' + tmp_pos = desc.find(delimiter_begin,tmp_pos); + if (tmp_pos >= pos_max) break; // not found + + // skip spaces + ++tmp_pos; + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // check for the keyword + if (desc.compare(tmp_pos, delimiter_keyword.size(), delimiter_keyword) != 0) continue; + + // skip spaces + tmp_pos += delimiter_keyword.size(); + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // check for the separator + if ( desc[tmp_pos] != delimiter_sep ) continue; + + // skip spaces + ++tmp_pos; + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // here should start the "int" + pos_start = tmp_pos; + + // "count" the digits + while ( desc[tmp_pos] >= '0' && desc[tmp_pos] <= '9' ) ++tmp_pos; + + // here should be just after the "int" + pos_end = tmp_pos; + + if ( pos_start == pos_end ) continue; // no number found + + // skip spaces + while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; + + // check for the delimiter_end + if ( desc[tmp_pos] != delimiter_end ) { + // force another loop even if the number was found; + pos_start = pos_end = pos_max; + continue; + } + } + + if ( pos_start == pos_max || pos_end <= pos_start ) { // not found + return -1; + } + + std::istringstream i(desc.substr(pos_start, pos_end-pos_start)); + + long st; + i >> st; + + return st; +} + +IOpaqueAddress *RelyConverter::createTmpAddress(const std::string &src, + long storageType, + const std::string &name, + const CLID &clId, + const std::string &data, + MsgStream &log, + SmartIF<IAddressCreator>& creator) { + + if (storageType <= 0) { + log << MSG::ERROR << "invalid storage type " << storageType << endmsg; + return 0; + } + + // Create temporary address for the relevant type and classID + IOpaqueAddress *tmpAddress; + + // for XML string temporary address, I need a way to know which is the originating href + const std::string par[3] = { data, + name, + src }; + unsigned long ipar[2] = { 1,0 }; + StatusCode sc = creator->createAddress(storageType, clId , par, ipar, tmpAddress); + if (sc.isFailure()){ + log << MSG::ERROR + << "Persistency service could not create a new address" << endmsg; + return 0; + } + + return tmpAddress; +} diff --git a/Det/DetCond/src/component/RelyConverter.h b/Det/DetCond/src/component/RelyConverter.h new file mode 100755 index 000000000..0af71524c --- /dev/null +++ b/Det/DetCond/src/component/RelyConverter.h @@ -0,0 +1,148 @@ +#ifndef COMPONENT_RELYCONVERTER_H +#define COMPONENT_RELYCONVERTER_H 1 + +// Include files +#include "DetCond/CondDBGenericCnv.h" + +// Forward and external declarations +class ISvcLocator; +template <class TYPE> class CnvFactory; + +/** @class RelyConverter RelyConverter.h component/RelyConverter.cpp + * + * ConditionsDBCnvSvc rely on the functionalities provided by the XmlCnvSvc. + * RelyConverter delegate the creation of the object to the XmlCnvSvc + * (via DetectorPersistencySvc). + * + * @author Marco CLEMENCIC + * @date 2004-12-03 + */ +class RelyConverter: public CondDBGenericCnv { + + /// Friend needed for instantiation + friend class CnvFactory<RelyConverter>; + +public: + + /// Operations that can be performed by delegation + enum Operation { + CreateObject, + FillObjectRefs, + UpdateObjectRefs + }; + + /** + * Initializes the converter + * @return status depending on the completion of the call + */ + virtual StatusCode initialize(); + + /** + * Finalizes the converter + * @return status depending on the completion of the call + */ + virtual StatusCode finalize(); + + /** + * Creates the transient representation of an object. + * @param pAddress the address of the object representation + * @param pObject the object created + * @return status depending on the completion of the call + */ + virtual StatusCode createObj (IOpaqueAddress *pAddress, + DataObject *&pObject); + /** + * Resolve the references of the created transient object. + * @param pAddress the address of the object representation + * @param pObject the object created + * @return status depending on the completion of the call + */ + virtual StatusCode fillObjRefs (IOpaqueAddress *pAddress, + DataObject *pObject); + /** + * Resolve the references of the just updated transient object. + * @param pAddress the address of the object representation + * @param pObject the object created + * @return status depending on the completion of the call + */ + virtual StatusCode updateObjRefs (IOpaqueAddress *pAddress, + DataObject *pObject); + /** + * Updates the transient object from the other representation (not implemented). + * @param pAddress the address of the object representation + * @param pObject the object updated + * @return status depending on the completion of the call + */ + virtual StatusCode updateObj (IOpaqueAddress *pAddress, + DataObject *pObject); + + /** + * Converts the transient object to the requested representation (not implemented). + * @param refpAddress the address of the object representation + * @param pObject the object to convert + * @return status depending on the completion of the call + */ + virtual StatusCode createRep (DataObject* pObject, + IOpaqueAddress*& refpAddress); + + /** + * Updates the converted representation of a transient object. + * @param pAddress the address of the object representation + * @param pObject the object whose representation has to be updated + * @return status depending on the completion of the call + */ + virtual StatusCode updateRep (IOpaqueAddress* pAddress, + DataObject* pObject); + + /** + * Accessor to the type of elements that this converter converts. + * @return the classID for this type + */ + static const CLID& classID () { return CLID_Any; } + +protected: + /// Standard constructor + RelyConverter(ISvcLocator* svc); + virtual ~RelyConverter( ); ///< Destructor + +private: + + /** + * Do the needed steps to perform a creation by delegation. + */ + StatusCode i_delegatedCreation(IOpaqueAddress* pAddress, + DataObject *&pObject, + Operation op = CreateObject); + +public: + /** + * Extract the storage_type from the folder or description. + */ + static long getStorageType(const std::string &path, const std::string &desc); + + /** Generate a temporary IOpaqueAddress to be passed to a PersistencySvc for + * the actual conversion. + * + * @param src originating URL (required by the XML format) + * @param storageType storage type ID (@see getStorageType) + * @param name name of the object inside the storage container + * @param data data to embed in the address + * @param log MsgStream instance to report errors + * @param creator IAdressCreator to use + * + * @return an IOpaqueAddress pointer in case of success, 0 in case of failure. + */ + static IOpaqueAddress *createTmpAddress(const std::string &src, + long storageType, + const std::string &name, + const CLID &clId, + const std::string &data, + MsgStream &log, + SmartIF<IAddressCreator>& creator); + +private: + /// Handle to the IConversionSvc interface of the DetectorPersistencySvc + IConversionSvc* m_detPersSvc; + +}; +#endif // COMPONENT_XMLRELYCNV_H diff --git a/Det/DetCond/src/component/RunStampCheck.cpp b/Det/DetCond/src/component/RunStampCheck.cpp new file mode 100644 index 000000000..ee7d310d0 --- /dev/null +++ b/Det/DetCond/src/component/RunStampCheck.cpp @@ -0,0 +1,140 @@ +#include "GaudiKernel/Service.h" +#include "GaudiKernel/IIncidentListener.h" +#include "GaudiKernel/IIncidentSvc.h" +#include "GaudiKernel/Kernel.h" +#include "GaudiKernel/IDetDataSvc.h" +#include "GaudiKernel/IEventProcessor.h" +#include "DetCond/ICondDBReader.h" + +/** Simple service to check if the run stamp condition exists for the current + * event. + * + * To ensure that the content of the conditions database includes alignments + * and calibrations for the event being processed, when these conditions are + * stored we also store a special condition with closed Interval Of Validity + * (IOV) covering only the run for which they are valid (RunStamp condition). + * + * The time line of the RunStamp conditions is not completely covered, and the + * holes in the time line implicitly flag the events for which the alignments + * are not available. + * + * When RunStampCheck is instantiated in a Gaudi application, it checks for + * each event time if the RunStamp condition exists or not, in which case the + * application is terminated with an error code. + * + * So, to enable the check, it is enough to add to the options: + * \code{.py} + * from Configurables import ApplicationMgr, RunStampCheck + * ApplicationMgr().ExtSvc.append(RunStampCheck()) + * \endcode + * + * \see https://its.cern.ch/jira/browse/LBCORE-831 + * \see https://its.cern.ch/jira/browse/LHCBPS-1421 + */ +class RunStampCheck: public extends1<Service, IIncidentListener> { +public: + /// Constructor. Declares properties. + RunStampCheck(const std::string& name, ISvcLocator* svcloc): + base_class(name, svcloc) { + declareProperty("RunStamp", m_runStampCondition, + "Path in the conditions database of the RunStamp condition."); + declareProperty("CondDBReader", m_condDBReaderName, + "Name of the ICondDBReader instance to query for the RunStamp."); + } + /// Connect to the required services and register as BeginEvent listener. + StatusCode start() override { + StatusCode sc = Service::start(); + if (UNLIKELY(!sc)) return sc; + + // ensure that we have the EventClocksvc (to get the current event time in + // the DetectorDataSvc). + if (UNLIKELY(!serviceLocator()->service("EventClockSvc"))) { + error() << "Cannot get EventClockSvc" << endmsg; + return StatusCode::FAILURE; + } + + m_incSvc = serviceLocator()->service("IncidentSvc"); + if (UNLIKELY(!m_incSvc)) { + error() << "Cannot get IncidentSvc" << endmsg; + return StatusCode::FAILURE; + } + m_incSvc->addListener(this, IncidentType::BeginEvent); + + m_condDBReader = serviceLocator()->service(m_condDBReaderName); + if (UNLIKELY(!m_condDBReader)) { + error() << "Cannot get " << m_condDBReaderName << endmsg; + return StatusCode::FAILURE; + } + + m_detSvc = serviceLocator()->service("DetectorDataSvc"); + if (UNLIKELY(!m_detSvc)) { + error() << "Cannot get DetectorDataSvc" << endmsg; + return StatusCode::FAILURE; + } + + m_evtProc = serviceLocator(); + if (UNLIKELY(!m_detSvc)) { + error() << "Cannot get IEventProcessor" << endmsg; + return StatusCode::FAILURE; + } + + // reset the IOV for the current run (to something not valid) + m_currentRunIOV = {Gaudi::Time::epoch(), Gaudi::Time::epoch()}; + return sc; + } + /// Deregister as BeginEvent listener and release reference to services. + StatusCode stop() override { + m_incSvc->removeListener(this, IncidentType::BeginEvent); + m_incSvc.reset(); + m_condDBReader.reset(); + m_detSvc.reset(); + m_evtProc.reset(); + return Service::stop(); + } + /// Handle the BeginEvent incident to check if the RunStamp condition exists. + void handle(const Incident&) override { + auto when = m_detSvc->eventTime(); + // run the check only if the current event time falls outside the boundaries + // of the current run + if (when < m_currentRunIOV.since || when >= m_currentRunIOV.until) { + if (UNLIKELY(msgLevel(MSG::DEBUG))) + debug() << "Checking '" << m_runStampCondition + << "' for event time " << when << endmsg; + ICondDBReader::DataPtr p; + std::string desc; + StatusCode sc = m_condDBReader->getObject(m_runStampCondition, when, + p, desc, + m_currentRunIOV.since, m_currentRunIOV.until); + if (!sc) { + // we didn't manage to get the entry from the DB: we do not have data + // for this run + error() << "Database not up-to-date. No valid data for run at " + << when.format(false, "%Y-%m-%d %H:%M:%S") + << "." << when.nanoformat() << " UTC" << endmsg; + m_evtProc->stopRun(); + } else if (UNLIKELY(msgLevel(MSG::DEBUG))) { + debug() << "Found '" << m_runStampCondition + << "' valid in [" << m_currentRunIOV.since + << ", " << m_currentRunIOV.until << ")" << endmsg; + } + } + } +private: + /// Path in the conditions database of the RunStamp condition. + std::string m_runStampCondition = "/Conditions/Online/LHCb/RunStamp.xml"; + /// Path in the conditions database of the RunStamp condition. + std::string m_condDBReaderName = "CondDBCnvSvc"; + /// reference to the incident service. + SmartIF<IIncidentSvc> m_incSvc; + /// reference to the CondDB reader. + SmartIF<ICondDBReader> m_condDBReader; + /// reference to the detector transient store. + SmartIF<IDetDataSvc> m_detSvc; + /// reference to the event processor. + SmartIF<IEventProcessor> m_evtProc; + + /// IOV of the current RunStamp. + ICondDBReader::IOV m_currentRunIOV; +}; + +DECLARE_COMPONENT(RunStampCheck) diff --git a/Det/DetCond/src/dict/DetCondDict.h b/Det/DetCond/src/dict/DetCondDict.h new file mode 100755 index 000000000..48ebf7619 --- /dev/null +++ b/Det/DetCond/src/dict/DetCondDict.h @@ -0,0 +1,38 @@ +// ============================================================================ +#ifndef DETCOND_DETCONDDICT_H +#define DETCOND_DETCONDDICT_H 1 +// ============================================================================ +// Hack to get round gccxml parsing problem (SEAL bug 9704) +// ============================================================================ +#ifdef _WIN32 +#define LONG_LONG_MAX 0x7fffffffffffffffLL /*maximum signed __int64 value */ +#define LONG_LONG_MIN 0x8000000000000000LL /*minimum signed __int64 value */ +#define ULONG_LONG_MAX 0xffffffffffffffffLL /*maximum unsigned __int64 value */ +#endif +// ============================================================================ +// GaudiKernel +// ============================================================================ +#include "GaudiKernel/Time.h" +// ============================================================================ +// DetCond +// ============================================================================ +#include "DetCond/ICondDBAccessSvc.h" +#include "DetCond/ICondDBEditor.h" +#include "DetCond/ICondDBReader.h" +#include "DetCond/ICOOLConfSvc.h" +// ============================================================================ +// CORAL (not available through PyCool) +// ============================================================================ +#include "RelationalAccess/ConnectionService.h" +#include "RelationalAccess/IConnectionServiceConfiguration.h" +#include "RelationalAccess/IReplicaSortingAlgorithm.h" +// ============================================================================ +namespace _instantiations { + struct Instantiations { + ICondDBReader::IOVList _i1; + }; +} +// ============================================================================ +#endif // DETCOND_DETCONDDICT_H +// ============================================================================ + diff --git a/Det/DetCond/src/dict/DetCondDict.xml b/Det/DetCond/src/dict/DetCondDict.xml new file mode 100755 index 000000000..f77b7e2a3 --- /dev/null +++ b/Det/DetCond/src/dict/DetCondDict.xml @@ -0,0 +1,14 @@ +<lcgdict> + + <class name="ICondDBReader" /> + <class name="ICondDBReader::IOV" /> + <class name="ICondDBReader::IOVList" /> + <class name="ICondDBEditor" /> + <class name="ICondDBAccessSvc" /> + <class name="ICOOLConfSvc" /> + + <class name="coral::IReplicaSortingAlgorithm" /> + <class name="coral::IConnectionService" /> + <class name="coral::IConnectionServiceConfiguration" /> + +</lcgdict> diff --git a/Det/DetCond/tests/data/DQFLAGS.db b/Det/DetCond/tests/data/DQFLAGS.db new file mode 100644 index 0000000000000000000000000000000000000000..3d22d8afaf1d4504118821a0ce9ea7e18272305a GIT binary patch literal 48128 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/HBTEST.db b/Det/DetCond/tests/data/HBTEST.db new file mode 100644 index 0000000000000000000000000000000000000000..9f920f0ad02fe5b7fa8eb3bd9665321079dd0863 GIT binary patch literal 76800 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/RSTEST.db b/Det/DetCond/tests/data/RSTEST.db new file mode 100644 index 0000000000000000000000000000000000000000..3515b986f69afa926d429fed453e8b8ec2bccefd GIT binary patch literal 48128 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 RI0E+s0c!at2=p7{{{!*sn#TYD literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB0.db b/Det/DetCond/tests/data/TESTDB0.db new file mode 100755 index 0000000000000000000000000000000000000000..8b4accc2b6482e618dd4f1a4f2889ca964a149c4 GIT binary patch literal 183296 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 OmqP}+Lj*P-f&UM@pb-H8 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB1.db b/Det/DetCond/tests/data/TESTDB1.db new file mode 100755 index 0000000000000000000000000000000000000000..58d9abbd4b60ffef0f56a298db91069aaf558389 GIT binary patch literal 79872 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB2.db b/Det/DetCond/tests/data/TESTDB2.db new file mode 100755 index 0000000000000000000000000000000000000000..85025de79ca3b6799d245910308c24dd3edbe17d GIT binary patch literal 79872 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 baEUHTlnyT0JlQ$E|DD4fpAmumgTVg->-`Q9 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/TESTDB3.db b/Det/DetCond/tests/data/TESTDB3.db new file mode 100755 index 0000000000000000000000000000000000000000..2c58dab3ef0a1e0c3e6e9e95300a73ab98c08d0d GIT binary patch literal 183296 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 literal 0 HcmV?d00001 diff --git a/Det/DetCond/tests/data/genDQFLAGS.py b/Det/DetCond/tests/data/genDQFLAGS.py new file mode 100644 index 000000000..3d343c185 --- /dev/null +++ b/Det/DetCond/tests/data/genDQFLAGS.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +""" +Small script to generate the test database for the heart beat test. +(kept for reference) +""" + +from CondDBUI import CondDB +from PyCool import cool +from datetime import datetime, timedelta + +def toTimeStamp(dt): + t = dt - datetime(1970, 1, 1, 0) + return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 + +db = CondDB("sqlite_file:DQFLAGS.db/DQFLAGS", readOnly = False, create_new_db = True) + +db.createNode("/Conditions", storageType = "NODE") +db.createNode("/Conditions/DQ", storageType = "NODE") +db.createNode("/Conditions/DQ/Flags", versionMode = "SINGLE") + +def cond(d): + data = ['<item key="%s" value="%d"/>' % i for i in d.items()] + return """<?xml version='1.0' encoding='ISO-8859-1'?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> + <condition name="Flags"> + <map keytype="string" name="map" valuetype="int"> + %s + </map> + </condition> +</DDDB> +""" % ("\n ".join(data)) + +for since, until, d in [(datetime(2012, 1, 1, 0), datetime(2012, 1, 2, 0), {"DET1": 1}), + (datetime(2012, 1, 2, 0), datetime(2012, 1, 3, 0), {"DET2": 1}), + (datetime(2012, 1, 3, 0), datetime(2012, 1, 4, 0), {}), + (datetime(2012, 1, 5, 0), datetime(2012, 1, 6, 0), {"DET3": 1})]: + since, until = map(toTimeStamp, (since, until)) + db.storeXMLString("/Conditions/DQ/Flags", cond(d), since, until) diff --git a/Det/DetCond/tests/data/genHBTEST.py b/Det/DetCond/tests/data/genHBTEST.py new file mode 100644 index 000000000..9544d8d17 --- /dev/null +++ b/Det/DetCond/tests/data/genHBTEST.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +""" +Small script to generate the test database for the heart beat test. +(kept for reference) +""" + +from CondDBUI import CondDB +from PyCool import cool + +base_time = 1262304000 # (2010, 1, 1, 0, 0, 0, 4, 1, 0) GMT +unit = 60 + +db = CondDB("sqlite_file:HBTEST.db/HBTEST", readOnly = False, create_new_db = True) + +db.createNode("/Conditions", storageType = "NODE") +db.createNode("/Conditions/Online", storageType = "NODE") +db.createNode("/Conditions/Online/HeartBeatTest", storageType = "NODE") +db.createNode("/Conditions/Online/HeartBeatTest/Condition1", versionMode = "SINGLE") +db.createNode("/Conditions/Online/HeartBeatTest/Condition2", versionMode = "SINGLE") +db.createNode("/Conditions/Online/HeartBeatTest/Tick", versionMode = "SINGLE") + +cond = """<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> + <condition name = "Condition%d"> + <param name = "Data" type = "int"> %d </param> + </condition> +</DDDB> +""" + +db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, 0), 0, cool.ValidityKeyMax) +for t in [20, 40]: + db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) + +db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, 0), 0, cool.ValidityKeyMax) +for t in [20, 40, 80]: + db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) + +hb = """<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> +<condition name="Tick"> +<param name="Alive" type="int">1</param> +</condition> +</DDDB> +""" +db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, 0, cool.ValidityKeyMax) +db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, (base_time + 60 * unit) * 1000000000, cool.ValidityKeyMax) diff --git a/Det/DetCond/tests/data/genRSTEST.py b/Det/DetCond/tests/data/genRSTEST.py new file mode 100755 index 000000000..b20f67c00 --- /dev/null +++ b/Det/DetCond/tests/data/genRSTEST.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +""" +Small script to generate the test database for the run stamp test. +(kept for reference) +""" + +from CondDBUI import CondDB +from PyCool import cool + +def ts(*args): + from datetime import datetime + epoch = datetime(1970, 1, 1) + return int((datetime(*args) - epoch).total_seconds() * 1000000000) + +db = CondDB("sqlite_file:RSTEST.db/RSTEST", readOnly = False, create_new_db = True) + +db.createNode("/Conditions", storageType = "NODE") +db.createNode("/Conditions/Online", storageType = "NODE") +db.createNode("/Conditions/Online/LHCb", storageType = "NODE") +db.createNode("/Conditions/Online/LHCB/RunInfo", versionMode = "SINGLE") +db.createNode("/Conditions/Online/LHCb/RunStamp.xml", versionMode = "SINGLE") + +rs = """<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> +<DDDB> +<condition name="RunStamp"> +<param name="RunNumber" type="int">1</param> +</condition> +</DDDB> +""" +db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 9), ts(2015, 6, 10)) +db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 11), ts(2015, 6, 12)) diff --git a/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt b/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt new file mode 100755 index 000000000..3d63ec802 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt @@ -0,0 +1,60 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") + +from Configurables import DetCondTest__bug_80076 +alg = DetCondTest__bug_80076("Bug80076") +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1"] +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 3) +#MessageSvc(OutputLevel = 1) + +#from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +</text></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check that we find the expected lines in the right order +expected = [ + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 0.0 -> 1262305200.0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262305200.0 -> 1262306400.0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + ] + +regexp = r"^---|^Validity" + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt b/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt new file mode 100755 index 000000000..3ccd88fd5 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt @@ -0,0 +1,4 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/check_db_reading.py</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt b/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt new file mode 100755 index 000000000..75e6f9405 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt @@ -0,0 +1,4 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/configuration_module_test.py</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt b/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt new file mode 100644 index 000000000..1a70fb044 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt @@ -0,0 +1,11 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/connection_timeout.py</text></argument> +<argument name="validator"><text> +findReferenceBlock(""" +TEST ===> start +DDDB.TimeOutChe... INFO Disconnect from database after being idle for 5s (will reconnect if needed) +TEST ===> end +""") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt new file mode 100755 index 000000000..94bc9a6d0 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt @@ -0,0 +1,22 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>1</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/ObjectA +/dd/AutoMap/FolderSet2/ObjectB +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt new file mode 100755 index 000000000..fe3b24ca6 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt @@ -0,0 +1,25 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>2</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +/dd/AutoMap/FolderSet3 +/dd/AutoMap/FolderSet3/Object1 +/dd/AutoMap/FolderSet3/Object2 +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt new file mode 100755 index 000000000..e7c6714a0 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt @@ -0,0 +1,23 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>3</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +/dd/AutoMap/FolderSet2/ObjectA +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt new file mode 100755 index 000000000..965dce340 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt @@ -0,0 +1,19 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>0</text></set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt new file mode 100755 index 000000000..ea4f3ebcf --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt @@ -0,0 +1,27 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> +<argument name="args"><set><text>4</text></set></argument> +<argument name="prerequisites"><set> + <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> +</set></argument> +<argument name="validator"><text> +reference_block = ''' +=== Begin Nodes === +/dd +/dd/AutoMap +/dd/AutoMap/FolderSet1 +/dd/AutoMap/FolderSet1/Object1 +/dd/AutoMap/FolderSet2 +/dd/AutoMap/FolderSet2/Object1 +/dd/AutoMap/FolderSet2/Object2 +/dd/AutoMap/FolderSet2/ObjectA +/dd/AutoMap/FolderSet2/ObjectB +/dd/AutoMap/FolderSet3 +/dd/AutoMap/FolderSet3/Object1 +/dd/AutoMap/FolderSet3/Object2 +=== End Nodes === +''' +findReferenceBlock(reference_block, stdout, result, causes) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt new file mode 100755 index 000000000..90cc2a5a8 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt @@ -0,0 +1,63 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import DetCondTest__DQScanTest as DQScanTest +from Configurables import CondDBDQScanner, DDDBConf, CondDB, EventClockSvc, FakeEventTime + +from datetime import datetime, timedelta +def toTimeStamp(dt): + if isinstance(dt, timedelta): + t = dt + else: + t = dt - datetime(1970, 1, 1, 0) + return (t.days * 60 * 60 * 24 + t.seconds) + +def toTimeStampNS(dt): + return toTimeStamp(dt) * 1000000000 + +dddbConf = DDDBConf() + +cdb = CondDB() +cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" +cdb.Tags["DQFLAGS"] = "" + +ecs = EventClockSvc(InitialTime=toTimeStampNS(datetime(2012,1,1,12))) +ecs.addTool(FakeEventTime, "EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = ecs.InitialTime +ecs.EventTimeDecoder.TimeStep = toTimeStampNS(timedelta(days=1)) + +alg = DQScanTest() +alg.DQScanner = CondDBDQScanner() + +tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0)), + (datetime(2012,1,1,12), datetime(2012,1,3,12)), + (datetime(2012,1,2,12), datetime(2012,1,5,12)), + (datetime(2012,1,4,12), datetime(2012,1,6,12)), + (datetime(2012,1,3,12), datetime(2012,1,4,12)), + ] + +alg.IOVs = [(toTimeStamp(a), toTimeStamp(b)) for a, b in tests] + +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) +MessageSvc(OutputLevel = WARNING) + +</text></argument> +<argument name="validator"><text> +findReferenceBlock(""" +ApplicationMgr INFO Application Manager Started successfully +DetCondTest::DQ...SUCCESS Process IOV 1325376000.0 -> 1325635200.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325419200.0 -> 1325592000.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325505600.0 -> 1325764800.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET2: 1, DET3: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325678400.0 -> 1325851200.0 +DetCondTest::DQ...SUCCESS -> Flags: {DET3: 1} +DetCondTest::DQ...SUCCESS Process IOV 1325592000.0 -> 1325678400.0 +DetCondTest::DQ...SUCCESS -> Flags: {} +ApplicationMgr INFO Application Manager Stopped successfully +""") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt b/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt new file mode 100644 index 000000000..22a8fb7c8 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt @@ -0,0 +1,20 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/force_disconnect.py</text></argument> +<argument name="validator"><text> +findReferenceBlock(""" +TEST ===> start +LHCBCOND DEBUG Forced disconnect from database (will reconnect automatically) +LHCBCOND.TimeOu...VERBOSE Stopping +DQFLAGS DEBUG Database already disconnected +ONLINE_2008 DEBUG Forced disconnect from database (will reconnect automatically) +ONLINE_2008.Tim...VERBOSE Stopping +DDDB DEBUG Forced disconnect from database (will reconnect automatically) +DDDB.TimeOutChe...VERBOSE Stopping +TEST ===> reconnect +ONLINE_2008.Tim...VERBOSE Starting +DDDB.TimeOutChe...VERBOSE Starting +TEST ===> end +""") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt new file mode 100755 index 000000000..14360891b --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt @@ -0,0 +1,4 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>../scripts/getIOVs.py</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt b/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt new file mode 100755 index 000000000..3542de97d --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt @@ -0,0 +1,79 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +import GaudiKernel.SystemOfUnits as Units +Units.hours = Units.s * 3600 +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" +HBTEST.QueryGranularity = 1 * Units.hours +HBTEST.OutputLevel = DEBUG + +MessageSvc().setDebug.append("HBTEST.Cache") + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") +CondDB().QueryGranularity = 1 * Units.hours + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] +alg.LoadDuringInitialize = True +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) +#MessageSvc(OutputLevel = 1) + +from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] +UpdateManagerSvc().OutputLevel = DEBUG +MessageSvc().setDebug += ["UpdateManagerSvc::Item"] +</text></argument> +<argument name="exit_code"><integer>0</integer></argument> +<argument name="validator"><text> +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 MISSING +HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 0 - 1262305200000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262306400000000000 - 9223372036854775807, channel : 0 +HBTEST.Cache DEBUG Conflict found: item not inserted +HBTEST.Cache DEBUG IOV : 1262306400000000000 - 9223372036854775807 +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 FOUND +''', signature_offset = 1, id = "first_cond1") + +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 MISSING +HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 0 - 1262305200000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 +HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262306400000000000 - 1262308800000000000, channel : 0 +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 FOUND +''', signature_offset = 1, id = "first_cond2") + +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262305800000000000 channel 0 FOUND +''', signature_offset = 1, id = "second_cond1") + +findReferenceBlock(''' +UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider +HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262305800000000000 channel 0 FOUND +''', signature_offset = 1, id = "second_cond2") +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt b/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt new file mode 100644 index 000000000..f7bbfbeb5 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt @@ -0,0 +1,105 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] +alg.LoadDuringInitialize = True +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 4) +#MessageSvc(OutputLevel = 1) + +from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] +UpdateManagerSvc().OutputLevel = DEBUG +MessageSvc().setDebug += ["UpdateManagerSvc::Item"] +</text></argument> +<argument name="exit_code"><integer>4</integer></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check for bug #66497 (Velo motion system updated several times during initialization) +# 'marker1' must appear only once before 'maker2' +marker1 = "Condition2 from data provider" +marker2 = "Conditions loaded at initialize" +count = 0 +for l in outputlines: + if marker2 in l: + break + if marker1 in l: + count += 1 +if count != 1: + causes.append("bug #66497") + result["GaudiTest.marker.value"] = result.Quote(marker1) + result["GaudiTest.marker.count"] = result.Quote(str(count)) + result["GaudiTest.marker.count_expected"] = result.Quote("1") + +## Check that we find the expected lines in the right order +expected = [ + 'DetCondTest::Te... INFO Conditions loaded at initialize', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262308800.0 -> 1262307600.0', + '(int) Data = 80', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + 'HBTEST ERROR Database not up-to-date. Latest known update is at 2010-01-01 01:00:00.0 UTC, event time is 2010-01-01 01:10:00.0 UTC' + ] + +regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Conditions loaded at initialize|HBTEST.*ERROR" + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt b/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt new file mode 100644 index 000000000..d35694016 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt @@ -0,0 +1,35 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc() +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = 5 +ecs.EventTimeDecoder.TimeStep = 10 + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/Conditions/This/Does/Not/Exist"] +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) +#MessageSvc(OutputLevel = 1) + +</text></argument> +<argument name="exit_code"><integer>4</integer></argument> +<argument name="validator"><text> +## Find the error message about the problematic condition +import re +regexp = r"ERROR.*Conditions/This/Does/Not/Exist" +if not re.findall(regexp, stdout): + causes.append("output") + result["GaudiTest.output.expected_regexp"] = result.Quote(regexp) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt b/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt new file mode 100644 index 000000000..f92224120 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt @@ -0,0 +1,59 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + UpdateManagerSvc, CondDBAccessSvc, RunStampCheck) + +def ts(*args): + from datetime import datetime + epoch = datetime(1970, 1, 1) + return int((datetime(*args) - epoch).total_seconds() * 1000000000) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = ts(2015, 6, 10, 12, 00)) # no RunStamp for this time +ecs.addTool(FakeEventTime, "EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = ts(2015, 6, 9, 12, 00) +ecs.EventTimeDecoder.TimeStep = 24 * 60 * 60 * 1000000000 # 1 day + +RSTEST = CondDBAccessSvc("RSTEST", ConnectionString="sqlite_file:../data/RSTEST.db/RSTEST") + +CondDB().addAlternative(RSTEST, "/Conditions/Online/LHCb/RunStamp.xml") +CondDB().EnableRunStampCheck = True +RunStampCheck(OutputLevel=DEBUG) + +algMgr = ApplicationMgr(EvtSel = "NONE", EvtMax = 4) +#MessageSvc(OutputLevel = 1) +</text></argument> +<argument name="exit_code"><integer>4</integer></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check that we find the expected lines in the right order +expected = ''' +RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433851200.0 +RunStampCheck DEBUG Found '/Conditions/Online/LHCb/RunStamp.xml' valid in [1433808000.0, 1433894400.0) +RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433937600.0 +RunStampCheck ERROR Database not up-to-date. No valid data for run at 2015-06-10 12:00:00.0 UTC +EventLoopMgr SUCCESS Terminating event processing loop due to a stop scheduled by an incident listener +EventLoopMgr SUCCESS Terminating event processing loop due to scheduled stop +'''.strip().splitlines() + +regexp = '^(RunStampCheck.*(Checking|Found|Database)|.*Terminating event processing)' +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt b/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt new file mode 100755 index 000000000..7f49cd9bd --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt @@ -0,0 +1,71 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc() +ecs.addTool(FakeEventTime, "EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = 5 +ecs.EventTimeDecoder.TimeStep = 10 + +DBs = [] +for i in [0,3]: + data = { "name": "TESTDB%d"%i } + DBs.append(CondDBAccessSvc(data["name"], + ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) +readers = [] +for i in range(len(DBs)): + readers.append("'%s':(%d,%d)"%(DBs[i].getFullName(),i*10,(i+1)*10)) + +CondDB().addLayer(CondDBTimeSwitchSvc(Readers = readers, OutputLevel = DEBUG)) + +from Configurables import DetCondTest__TestConditionAlg +alg = DetCondTest__TestConditionAlg() +alg.Conditions = ["/dd/AutoMap/FolderSet1/Object1"] +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) +#MessageSvc(OutputLevel = 1) + +</text></argument> +<argument name="validator"><text> +## 1st check: Find reference block +reference_block = """ +CondDBTimeSwitc... DEBUG Configured CondDBReaders: +CondDBTimeSwitc... DEBUG 0.0 - 0.00000001: CondDBAccessSvc/TESTDB0 +CondDBTimeSwitc... DEBUG 0.00000001 - 0.00000002: CondDBAccessSvc/TESTDB3 +""" +findReferenceBlock(reference_block) + +## 2nd check: find data +expected = [ + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/AutoMap/FolderSet1/Object1', + 'Validity: 0.0 -> 0.00000001', + '(int) Data = 1', + 'DetCondTest::Te... INFO Requested Conditions:', + '--- /dd/AutoMap/FolderSet1/Object1', + 'Validity: 0.00000001 -> 0.00000002', + '(int) Data = 2'] + +regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions" +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt b/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt new file mode 100755 index 000000000..45a455863 --- /dev/null +++ b/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt @@ -0,0 +1,82 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<extension class="GaudiTest.GaudiExeTest" kind="test"> +<argument name="program"><text>gaudirun.py</text></argument> +<argument name="args"><set> +<text>-v</text> +</set></argument> +<argument name="options"><text> +from Gaudi.Configuration import * +from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, + CondDBAccessSvc, CondDBTimeSwitchSvc) + +DDDBConf() + +ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) +ecs.addTool(FakeEventTime,"EventTimeDecoder") +ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 +ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 + +HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") +HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" + +CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") + +from Configurables import DetCondTest__FinalizationEvtLoop +alg = DetCondTest__FinalizationEvtLoop() +alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] +alg.InitialTime = ecs.EventTimeDecoder.StartTime +alg.Step = ecs.EventTimeDecoder.TimeStep +alg.FinalTime = alg.InitialTime + 3 * alg.Step +ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) +#MessageSvc(OutputLevel = 1) + +#from Configurables import UpdateManagerSvc +#UpdateManagerSvc(DotDumpFile = "ums.dot") + +</text></argument> +<argument name="validator"><text> +outputlines = [ l.rstrip() for l in stdout.splitlines() ] + +## Check that we find the expected lines in the right order +expected = [ + 'DetCondTest::Fi... INFO Update for event time 1262304600.0', + 'DetCondTest::Fi... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 0.0 -> 1262305200.0', + '(int) Data = 0', + 'DetCondTest::Fi... INFO Update for event time 1262305800.0', + 'DetCondTest::Fi... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262305200.0 -> 1262306400.0', + '(int) Data = 20', + 'DetCondTest::Fi... INFO Update for event time 1262307000.0', + 'DetCondTest::Fi... INFO Requested Conditions:', + '--- /dd/Conditions/Online/HeartBeatTest/Condition1', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + '--- /dd/Conditions/Online/HeartBeatTest/Condition2', + 'Validity: 1262306400.0 -> 1262307600.0', + '(int) Data = 40', + + ] + +regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Update for event time" + +# grep +import re +exp = re.compile(regexp) +outputlines = [ l for l in outputlines if exp.match(l) ] + +if outputlines != expected: + causes.append("output") + result["GaudiTest.output.regexp"] = result.Quote(regexp) + result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) + result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) +</text></argument> +</extension> diff --git a/Det/DetCond/tests/scripts/check_db_reading.py b/Det/DetCond/tests/scripts/check_db_reading.py new file mode 100755 index 000000000..b3f23c080 --- /dev/null +++ b/Det/DetCond/tests/scripts/check_db_reading.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +import unittest + +import sys + +#import string +#import random + +class DetCondReadingTest(unittest.TestCase): + +# def assertEqualsConfig(self, lhs, rhs): +# self.assertEquals(lhs.getFullName(), rhs.getFullName()) + + def setUp(self): + unittest.TestCase.setUp(self) + self.testDB = 'sqlite_file:../data/TESTDB3.db/TESTDB3' + self.testFolder = '/lhcb.xml' + self.testout = '<?xml version="1.0" encoding="ISO-8859-1"?>\n<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd">\n<DDDB>\n <catalog name="dd">\n <catalogref href="AutoMap" />\n </catalog> \n</DDDB> \n' + self.Nmethods = 1 # number of methods + + def readDB(self): + from CondDBUI import CondDB + db = CondDB(self.testDB) + s = self.testFolder + if not db.db.existsFolder(s): return "" + data = db.getPayload(s,0,0) + if 'data' not in data: return "" + return data['data'] + +# def tearDown(self): +# unittest.TestCase.tearDown(self) + + def test_reading(self): + """Check CondDB reading """ + ret = self.readDB() + self.assertEquals(self.testout, ret) + +if __name__ == '__main__': + unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/configuration_module_test.py b/Det/DetCond/tests/scripts/configuration_module_test.py new file mode 100755 index 000000000..36276a6d7 --- /dev/null +++ b/Det/DetCond/tests/scripts/configuration_module_test.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python + +import unittest + +from Gaudi.Configuration import * +import GaudiKernel.Configurable +from GaudiKernel.Configurable import purge, applyConfigurableUsers +from Configurables import CondDB, DDDBConf +from Configurables import (CondDBCnvSvc, + CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc) + +#import logging +#from GaudiKernel.ProcessJobOptions import InstallRootLoggingHandler +#InstallRootLoggingHandler(level = logging.DEBUG) + +orig_reader = None +orig_dict = None +def equalConfigurable(lhs, rhs): + return lhs.getFullName() == rhs.getFullName() + +class DetCondConfigurationTest(unittest.TestCase): + + def assertEqualsConfig(self, lhs, rhs): + self.assertEquals(lhs.getFullName(), rhs.getFullName()) + + def setUp(self): + unittest.TestCase.setUp(self) + self.DDDB = DDDBConf() + self.CondDB = CondDB() + + def tearDown(self): + self.DDDB = self.CondDB = None + purge() + GaudiKernel.Configurable._appliedConfigurableUsers_ = False + unittest.TestCase.tearDown(self) + + def checkHeartBeat(self, conf, chkstr = ""): + conf = allConfigurables[eval(conf.split(':')[0]).split("/")[1]] + if isinstance(conf, CondDBLayeringSvc): + conf = conf.Layers[-1]# Only check the bottom layer + self.assertEquals(conf.getProp("HeartBeatCondition"), chkstr) + + + def test_000_originalConfiguration(self): + """Check the default configuration""" + applyConfigurableUsers() + global orig_reader, orig_dict + orig_reader = allConfigurables["CondDBCnvSvc"].CondDBReader + self.assertEquals(orig_reader.__class__.__name__, + "CondDBDispatcherSvc") + orig_dict = dict(orig_reader.Alternatives) + + def test_010_addCondDBLayer_1(self): + """Add one layer from CondDBAccessSvc instance""" + # Add the layer + layer = CondDBAccessSvc("layer") + self.CondDB.addLayer(layer) + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # check if we have a layering svc + self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") + # check for the new layer... + self.assertEqual(reader.Layers[0], layer) + # ... plus the original one + self.assertEqualsConfig(reader.Layers[1], orig_reader) + + def test_010_addCondDBLayer_2(self): + """Add layers from allowed Configurable instances""" + # Add the layers (one per type) + types = [CondDBAccessSvc, + CondDBDispatcherSvc, + CondDBLayeringSvc, + CondDBTimeSwitchSvc, + CondDBSQLiteCopyAccSvc] + layers = [] + for i in range(len(types)): + layer = types[i]("layer_%d"%i) + layers.append(layer) + self.CondDB.addLayer(layer) + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # check if we have a layering svc + self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") + # correct size? + self.assertEquals(len(reader.Layers), len(layers) + 1) + # correct order (inverse of insertion order)... + layers.reverse() + for i in range(len(types)): + self.assertEqual(reader.Layers[i], layers[i]) + # ... plus the original one + self.assertEqualsConfig(reader.Layers[len(layers)], orig_reader) + + def test_020_addCondDBAlternative_1(self): + """Add one alternative from CondDBAccessSvc instance""" + # Add the alternative + alternative = CondDBAccessSvc("alternative") + self.CondDB.addAlternative(alternative, "/Test") + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # the reader should not have changed + self.assertEqualsConfig(reader, orig_reader) + # correct size? + self.assertEquals(len(reader.Alternatives), len(orig_dict) + 1) + # check the previous alternatives + for k in orig_dict: + self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) + # plus the new one + self.assertEqualsConfig(reader.Alternatives["/Test"], alternative) + + def test_020_addCondDBAlternative_2(self): + """Replace one alternative from CondDBAccessSvc instance""" + path = orig_dict.keys()[0] + + # Add the alternative + alternative = CondDBAccessSvc("alternative") + self.CondDB.addAlternative(alternative, path) + + applyConfigurableUsers() + + reader = allConfigurables["CondDBCnvSvc"].CondDBReader + # the reader should not have changed + self.assertEqualsConfig(reader, orig_reader) + # correct size? + self.assertEquals(len(reader.Alternatives), len(orig_dict)) + # check the previous alternatives + for k in orig_dict: + if k != path: + self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) + else: + self.assertEqualsConfig(reader.Alternatives[k], alternative) + + def test_030_heartbeat(self): + """HeartBeat condition (off-line, Oracle, default)""" + self.CondDB.Online = False + self.CondDB.UseOracle = True + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") + + def test_031_heartbeat(self): + """HeartBeat condition (off-line, Oracle, ignore)""" + self.CondDB.Online = False + self.CondDB.UseOracle = True + self.CondDB.IgnoreHeartBeat = True + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "") + + def test_032_heartbeat(self): + """HeartBeat condition (off-line, SQLite, default)""" + self.CondDB.Online = False + self.CondDB.UseOracle = False + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers[:-1]: + self.checkHeartBeat(conf, "") + conf = online.Readers[-1] + self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") + + def test_033_heartbeat(self): + """HeartBeat condition (off-line, SQLite, ignore)""" + self.CondDB.Online = False + self.CondDB.UseOracle = False + self.CondDB.IgnoreHeartBeat = True + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers: + self.checkHeartBeat(conf, "") + + def test_040_heartbeat(self): + """HeartBeat condition (on-line, Oracle, not ignore)""" + self.CondDB.Online = True + self.CondDB.UseOracle = True + self.CondDB.IgnoreHeartBeat = False + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") + + def test_041_heartbeat(self): + """HeartBeat condition (on-line, Oracle, default)""" + self.CondDB.Online = True + self.CondDB.UseOracle = True + applyConfigurableUsers() + + hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") + + self.assertEquals(hbc, "") + + def test_042_heartbeat(self): + """HeartBeat condition (on-line, SQLite, not ignore)""" + self.CondDB.Online = True + self.CondDB.UseOracle = False + self.CondDB.IgnoreHeartBeat = False + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers[:-1]: + self.checkHeartBeat(conf, "") + conf = online.Readers[-1] + self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") + + def test_043_heartbeat(self): + """HeartBeat condition (on-line, SQLite, default)""" + self.CondDB.Online = True + self.CondDB.UseOracle = False + applyConfigurableUsers() + + online = allConfigurables["ONLINE"] + for conf in online.Readers: + self.checkHeartBeat(conf, "") + +if __name__ == '__main__': + unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/connection_timeout.py b/Det/DetCond/tests/scripts/connection_timeout.py new file mode 100644 index 000000000..aac17167b --- /dev/null +++ b/Det/DetCond/tests/scripts/connection_timeout.py @@ -0,0 +1,22 @@ +## @file +# Small script forcing a time-out in the access to the +from Gaudi.Configuration import * +from Configurables import CondDB, CondDBAccessSvc, DDDBConf + +DDDBConf() + +DDDB = CondDBAccessSvc("DDDB") +DDDB.ConnectionTimeOut = 5 + +#MessageSvc(OutputLevel = ERROR) + +import GaudiPython +app = GaudiPython.AppMgr() +app.initialize() +app.start() + +import time +app.detSvc()["/dd"] # access the DB +print "TEST ===> start" +time.sleep(6) # wait enough +print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/direct_mapping_test.py b/Det/DetCond/tests/scripts/direct_mapping_test.py new file mode 100755 index 000000000..10515b6fe --- /dev/null +++ b/Det/DetCond/tests/scripts/direct_mapping_test.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +""" +Script for the test of possible use-cases of the direct mapping between +the COOL hierarchy and the transient store one. +Use-cases: + 0) basic mapping (CondDBAccessSvc) + 1) alternative for a folderset in the main DB + 2) alternative for a folderset _not_ in the main DB + 3) alternative for a folder _not_ in the main DB + 4) layers +""" +__author__ = "Marco Clemencic" + +def configure(version): + from Gaudi.Configuration import (importOptions, + ApplicationMgr, + MessageSvc) + from Configurables import DDDBConf, CondDB, CondDBAccessSvc + dddbConf = DDDBConf() + cdb = CondDB() + + DBs = [] + for i in range(3): + data = { "name": "TESTDB%d"%i } + DBs.append(CondDBAccessSvc(data["name"], + ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) + + cdb.PartitionConnectionString["DDDB"] = DBs[0].ConnectionString + cdb.Tags["DDDB"] = "" + if version == 1: + cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2') + elif version == 2: + cdb.addAlternative(DBs[2],'/AutoMap/FolderSet3') + elif version == 3: + cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2/ObjectA') + elif version == 4: + cdb.addLayer(DBs[1]) + cdb.addLayer(DBs[2]) + elif version != 0: + raise RuntimeError("Invalid version number") + + ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") + #MessageSvc(OutputLevel = 1) + +def datastore_walk(ds, top = "/"): + if top == "/": + top = ds._idm.rootName() + obj = ds[top] + if obj is not None: + yield ds[top] + nodes = [ i.identifier() for i in ds.leaves(ds[top]) ] + for n in nodes: + for obj in datastore_walk(ds,n): + yield obj + +def node_names(ds, top = "/"): + return [ obj.registry().identifier() for obj in datastore_walk(ds,top) ] + +def main(conf): + configure(conf) + + from Gaudi.Configuration import configurationDict + from pprint import pprint + import GaudiPython + app = GaudiPython.AppMgr() + pprint(configurationDict()) + app.initialize() + + dds = app.detsvc() + # load everything in the store + nodes = node_names(dds) + nodes.sort() + + print "=== Begin Nodes ===" + for n in nodes: + print n + print "=== End Nodes ===" + +if __name__ == '__main__': + import sys + if len(sys.argv) < 2: + version = 0 + else: + version = int(sys.argv[1]) + + main(version) diff --git a/Det/DetCond/tests/scripts/force_disconnect.py b/Det/DetCond/tests/scripts/force_disconnect.py new file mode 100644 index 000000000..e504010ab --- /dev/null +++ b/Det/DetCond/tests/scripts/force_disconnect.py @@ -0,0 +1,28 @@ +## @file +# Small script forcing a time-out in the access to the +from Gaudi.Configuration import * +from Configurables import CondDB, CondDBAccessSvc, DDDBConf + +DDDBConf(DataType="2008") + +#DDDB = CondDBAccessSvc("DDDB") +#DDDB.ConnectionTimeOut = 5 + +partitions = ['DDDB', 'ONLINE_2008', 'LHCBCOND', 'DQFLAGS'] +msg = MessageSvc(OutputLevel=WARNING) +msg.setDebug.extend(partitions) +msg.setVerbose.extend([p + '.TimeOutChecker' for p in partitions]) + +import GaudiPython +app = GaudiPython.AppMgr() +app.initialize() +app.start() + +import time +app.detSvc()["/dd/Conditions/Online/LHCb"] # access the DB +print "TEST ===> start" +reader = app.service('CondDBCnvSvc', GaudiPython.gbl.ICondDBReader) +reader.disconnect() +print "TEST ===> reconnect" +app.detSvc()["/dd/Conditions/Online/LHCb/Tick"] # access the DB +print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/getIOVs.py b/Det/DetCond/tests/scripts/getIOVs.py new file mode 100755 index 000000000..8aa9c2cd4 --- /dev/null +++ b/Det/DetCond/tests/scripts/getIOVs.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +""" +Script for the test of IOV retrieval +""" +__author__ = "Marco Clemencic" + +import sys +from datetime import datetime, timedelta + +def toTimeStamp(dt): + if isinstance(dt, timedelta): + t = dt + else: + t = dt - datetime(1970, 1, 1, 0) + return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 + +def toDateTime(ts): + return datetime(1970, 1, 1, 0) + timedelta(seconds=ts/1000000000) + +def configure(): + from Gaudi.Configuration import (ApplicationMgr, + MessageSvc, ERROR) + from Configurables import DDDBConf, CondDB, CondDBAccessSvc, EventClockSvc, FakeEventTime + dddbConf = DDDBConf() + cdb = CondDB() + + cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" + cdb.Tags["DQFLAGS"] = "" + + ecs = EventClockSvc(InitialTime=toTimeStamp(datetime(2012,1,1,12))) + ecs.addTool(FakeEventTime, "EventTimeDecoder") + ecs.EventTimeDecoder.StartTime = ecs.InitialTime + ecs.EventTimeDecoder.TimeStep = toTimeStamp(timedelta(days=1)) + + ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") + MessageSvc(OutputLevel = ERROR) + +def checkIOVs(dbReader, since, until, expected): + import GaudiPython + IOV = GaudiPython.gbl.ICondDBReader.IOV + Time = GaudiPython.gbl.Gaudi.Time + + print "Checking %s -> %s ..." % (since, until), + t1 = Time(toTimeStamp(since)) + t2 = Time(toTimeStamp(until)) + iov = IOV(t1, t2) + result = dbReader.getIOVs("/Conditions/DQ/Flags", iov, 0) + + found = [(toDateTime(iov.since.ns()), toDateTime(iov.until.ns())) for iov in result] + + good = found == expected + if not good: + print "ERROR" + print " expected:", [tuple(map(str, iov)) for iov in expected] + print " found: ", [tuple(map(str, iov)) for iov in found] + else: + print "OK" + return good + +def main(): + configure() + + from Gaudi.Configuration import configurationDict + from pprint import pprint + import GaudiPython + app = GaudiPython.AppMgr() + pprint(configurationDict()) + app.initialize() + + dq = app.service("DQFLAGS", GaudiPython.gbl.ICondDBReader) + + dbData = [(datetime(2012,1,1,0), datetime(2012,1,2,0)), + (datetime(2012,1,2,0), datetime(2012,1,3,0)), + (datetime(2012,1,3,0), datetime(2012,1,4,0)), + (datetime(2012,1,5,0), datetime(2012,1,6,0))] + + tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0), dbData[0:3]), + (datetime(2012,1,1,12), datetime(2012,1,3,12), dbData[0:3]), + (datetime(2012,1,2,12), datetime(2012,1,5,12), dbData[1:4]), + (datetime(2012,1,4,12), datetime(2012,1,6,12), dbData[3:4]), + ] + print "\n=== Begin Tests ===" + bad = 0 + for since, until, expected in tests: + if not checkIOVs(dq, since, until, expected): + bad += 1 + print "=== End Tests ===" + + if bad: + print "\nFailed %d tests out of %d\n" % (bad, len(tests)) + sys.exit(1) + + print "" + +if __name__ == '__main__': + main() diff --git a/Det/DetCond/tests/src/DQScanTest.cpp b/Det/DetCond/tests/src/DQScanTest.cpp new file mode 100644 index 000000000..6ff5a6faa --- /dev/null +++ b/Det/DetCond/tests/src/DQScanTest.cpp @@ -0,0 +1,106 @@ +// Local custom parsers must be defined very early in the file. +#include "GaudiKernel/ParsersFactory.h" + +namespace Gaudi { + namespace Parsers { + // Note: to be kept in sync with the property in DetCondTest::DQScanTest + StatusCode parse(std::vector<std::pair<unsigned int, unsigned int> >& result, const std::string& input) { + return Gaudi::Parsers::parse_(result, input); + } + } +} + +// Include files + +#include "DetCond/ICondDBReader.h" + +// local +#include "DQScanTest.h" + +#include "boost/foreach.hpp" + +namespace { + inline long long s2ns(unsigned int s) { + return static_cast<long long>(s) * 1000000000; + } +} + +// ---------------------------------------------------------------------------- +// Implementation file for class: DQScanTest +// +// 31/01/2012: Marco Clemencic +// ---------------------------------------------------------------------------- +DECLARE_NAMESPACE_ALGORITHM_FACTORY(DetCondTest, DQScanTest) + +namespace DetCondTest { +// ============================================================================ +// Standard constructor, initializes variables +// ============================================================================ +DQScanTest::DQScanTest(const std::string& name, ISvcLocator* pSvcLocator) + : GaudiAlgorithm(name, pSvcLocator), m_scanner(0) +{ + declareProperty("DQScanner", + m_DQScannerName = "CondDBDQScanner", + "Type/name of the IDQScanner instance to use."); + declareProperty("IOVs", + m_iovsProp, + "List of IOVs (specified in seconds) to scan."); +} + +// ============================================================================ +// Destructor +// ============================================================================ +DQScanTest::~DQScanTest() {} + +// ============================================================================ +// Initialization +// ============================================================================ +StatusCode DQScanTest::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + + m_scanner = tool<IDQScanner>(m_DQScannerName); + + m_iovs.clear(); + BOOST_FOREACH(IOVPropType &iov, m_iovsProp) { + m_iovs.push_back(ICondDBReader::IOV(Gaudi::Time(s2ns(iov.first)), Gaudi::Time(s2ns(iov.second)))); + } + + return StatusCode::SUCCESS; +} + +// ============================================================================ +// Main execution +// ============================================================================ +StatusCode DQScanTest::execute() { + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; + + info() << "Execute" << endmsg; + + BOOST_FOREACH(ICondDBReader::IOV &iov, m_iovs) { + always() << "Process IOV " << iov.since << " -> " << iov.until << endmsg; + IDQFilter::FlagsType result = m_scanner->scan(iov.since, iov.until); + always() << "-> Flags: " << result << endmsg; + } + + return StatusCode::SUCCESS; +} + +// ============================================================================ +// Finalize +// ============================================================================ +StatusCode DQScanTest::finalize() { + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; + + if (release(m_scanner).isFailure()) { + warning() << "Failed to release tool " << m_DQScannerName << endmsg; + } + m_scanner = 0; + + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +// ============================================================================ +} // namespace DetCondTest diff --git a/Det/DetCond/tests/src/DQScanTest.h b/Det/DetCond/tests/src/DQScanTest.h new file mode 100644 index 000000000..78d13b015 --- /dev/null +++ b/Det/DetCond/tests/src/DQScanTest.h @@ -0,0 +1,51 @@ +#ifndef SRC_DQSCANTEST_H +#define SRC_DQSCANTEST_H 1 +// Include files +// from Gaudi +#include "GaudiAlg/GaudiAlgorithm.h" + +#include "Kernel/IDQScanner.h" + +#include "DetCond/ICondDBReader.h" + +namespace DetCondTest { + +/** @class DQScanTest DQScanTest.h src/DQScanTest.h + * + * Algorithm to test the behavior of an IDQScanner implementation. + * + * @author Marco Clemencic + * @date 31/01/2012 + */ +class DQScanTest: public GaudiAlgorithm { +public: + typedef std::pair<unsigned int, unsigned int> IOVPropType; + typedef std::vector<IOVPropType> IOVListPropType; + + /// Standard constructor + DQScanTest(const std::string& name, ISvcLocator* pSvcLocator); + virtual ~DQScanTest(); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization +protected: +private: + + /// Type/name of the IDQScanner instance. + /// (property DQScanner) + std::string m_DQScannerName; + + /// List of IOVs (with time specified in seconds) to try to retrieve (property). + IOVListPropType m_iovsProp; + + /// List of IOVs to try to retrieve. + ICondDBReader::IOVList m_iovs; + + /// Pointer to the IDQScanner instance. + IDQScanner *m_scanner; +}; + +} + +#endif // SRC_DQSCANTEST_H diff --git a/Det/DetCond/tests/src/TestConditionAlg.cpp b/Det/DetCond/tests/src/TestConditionAlg.cpp new file mode 100755 index 000000000..d749e5d05 --- /dev/null +++ b/Det/DetCond/tests/src/TestConditionAlg.cpp @@ -0,0 +1,287 @@ +// Include files +#include "GaudiKernel/Map.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/IDetDataSvc.h" +#include "DetDesc/Condition.h" + +#include <vector> + +namespace DetCondTest { + +/** @class TestConditionAlg TestConditionAlg.h component/TestConditionAlg.h + * + * Simple algorithm that prints the requested conditions at every event. + * + * @author Marco CLEMENCIC + * @date 2008-06-27 + */ +class TestConditionAlg : public GaudiAlgorithm { +public: + /// Standard constructor + TestConditionAlg( const std::string& name, ISvcLocator* pSvcLocator ); + + virtual ~TestConditionAlg( ); ///< Destructor + + virtual StatusCode initialize(); ///< Algorithm initialization + virtual StatusCode execute (); ///< Algorithm execution + virtual StatusCode finalize (); ///< Algorithm finalization + +protected: + + void i_dump(); + + /// Names of the conditions to print + std::vector<std::string> m_condPaths; + + /// Flag to decide if the conditions have to be loaded also during the + /// initialize step. + bool m_loadAtInit; + + /// Container of the conditions to print + std::vector<std::string> m_conditionDeps; + + /// Container of the conditions to print + GaudiUtils::Map<std::string,Condition*> m_conditions; +}; + +//----------------------------------------------------------------------------- +// Implementation file for class : TestConditionAlg +// +// 2008-06-27 : Marco CLEMENCIC +//----------------------------------------------------------------------------- + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= +TestConditionAlg::TestConditionAlg( const std::string& name, + ISvcLocator* pSvcLocator) + : GaudiAlgorithm ( name , pSvcLocator ) +{ + declareProperty("Conditions", m_condPaths, + "list of paths to conditions in the detector transient store"); + declareProperty("LoadDuringInitialize", m_loadAtInit = false, + "load the requested conditions already during the initialization"); + declareProperty("ConditionsDependencies", m_conditionDeps, + "declare dependencies between objects as a list of strings 'A -> B') " + "to indicate that the condition A depends on B."); +} +//============================================================================= +// Destructor +//============================================================================= +TestConditionAlg::~TestConditionAlg() {} + +namespace { + void printDepsError(MsgStream& stream, + size_t lineNo, const std::string& msg, + const std::string& line) { + stream << "Syntax error in item " << lineNo + << " of ConditionsDependencies: " << msg << endmsg; + stream << " '" << line << "'" << endmsg; + } +} +//============================================================================= +// Initialization +//============================================================================= +StatusCode TestConditionAlg::initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + + std::vector<std::string>::const_iterator path; + for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ + registerCondition<TestConditionAlg>(*path,m_conditions[*path],NULL); + } + + std::vector<std::string>::const_iterator deps; + for (deps = m_conditionDeps.begin(); deps != m_conditionDeps.end(); ++deps) { + std::string::size_type pos = deps->find("->"); + if (pos == std::string::npos) { + printDepsError(error(), deps - m_conditionDeps.begin(), "missing '->'", *deps); + return StatusCode::FAILURE; + } + std::string::size_type p0, p1; + p0 = deps->find_first_not_of(" \n\r\t"); + p1 = deps->find_last_not_of(" \n\r\t", pos - 1) + 1; + std::string first(*deps, p0, p1 - p0); + if (first.empty()) { + printDepsError(error(), deps - m_conditionDeps.begin(), "missing first argument", *deps); + return StatusCode::FAILURE; + } + p0 = deps->find_first_not_of(" \n\r\t", pos + 2); + p1 = deps->find_last_not_of(" \n\r\t") + 1; + std::string second(*deps, p0, p1 - p0); + if (second.empty()) { + printDepsError(error(), deps - m_conditionDeps.begin(), "missing second argument", *deps); + return StatusCode::FAILURE; + } + info() << "Declaring dependency of '" << first << "' on '" << second << "'" << endmsg; + updMgrSvc()->registerCondition(getDet<Condition>(first), second); + } + + if (m_loadAtInit) { + sc = updMgrSvc()->update(this); + info() << "Conditions loaded at initialize" << endmsg; + if (sc.isSuccess()){ + i_dump(); + } + else return sc; + } + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode TestConditionAlg::execute() { + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; + i_dump(); + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finalize +//============================================================================= +StatusCode TestConditionAlg::finalize() { + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; + + updMgrSvc()->unregister(this); + m_conditions.clear(); + m_condPaths.clear(); + + return GaudiAlgorithm::finalize(); // must be called after all other actions +} + +//============================================================================= +// Print the conditions +//============================================================================= +void TestConditionAlg::i_dump() +{ + info() << "Requested Conditions:\n"; + GaudiUtils::Map<std::string,Condition*>::iterator it; + for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { + info() << "--- " << it->first << "\n" << *(it->second) << "\n"; + } + info() << endmsg; +} + +//============================================================================= + + +/** Small algorithm that runs a fake event loop during finalize to scan the + * values of the conditions (see bug #74255). + * + * @author Marco CLEMENCIC + * @date 2010-10-25 + */ +class FinalizationEvtLoop: public GaudiAlgorithm { +public: + /// Standard constructor + FinalizationEvtLoop(const std::string& name, ISvcLocator* pSvcLocator): + GaudiAlgorithm(name, pSvcLocator) + { + declareProperty("Conditions", m_condPaths, + "list of paths to conditions in the detector transient store"); + declareProperty("InitialTime", m_initTime = 0, // 1970-01-01 00:00:00UTC + "First event time of the fake event loop"); + declareProperty("FinalTime", m_finalTime = m_initTime + 10000000000LL, // init + 10s + "Final time of the loop"); + declareProperty("Step", m_step = 1000000000LL, // 1s + "Step of the loop"); + } + + virtual ~FinalizationEvtLoop() {} + + virtual StatusCode initialize() { + StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first + if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm + + if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; + + std::vector<std::string>::const_iterator path; + for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ + registerCondition<FinalizationEvtLoop>(*path, m_conditions[*path], NULL); + } + + return StatusCode::SUCCESS; + } + + virtual StatusCode execute () { + return StatusCode::SUCCESS; + } + + virtual StatusCode finalize () { + Gaudi::Time t(m_initTime); + const Gaudi::Time fin(m_finalTime); + const Gaudi::TimeSpan step(m_step); + + SmartIF<IDetDataSvc> dds(detSvc()); + for ( ; t < fin; t += step) { + dds->setEventTime(t); + info() << "Update for event time " << t << endmsg; + if (updMgrSvc()->newEvent().isSuccess()) { + info() << "Requested Conditions:\n"; + GaudiUtils::Map<std::string,Condition*>::iterator it; + for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { + info() << "--- " << it->first << "\n" << *(it->second) << "\n"; + } + info() << endmsg; + } + else { + error() << "Failure updating" << endmsg; + return StatusCode::FAILURE; + } + } + + return StatusCode::SUCCESS; + } + +private: + /// First event time of the fake event loop + Gaudi::Time::ValueType m_initTime; + /// First event time of the fake event loop + Gaudi::Time::ValueType m_finalTime; + /// First event time of the fake event loop + Gaudi::Time::ValueType m_step; + + /// Names of the conditions to print + std::vector<std::string> m_condPaths; + + /// Container of the conditions to print + GaudiUtils::Map<std::string,Condition*> m_conditions; +}; + +/** Test algorithm that triggers the bug #80076 + * https://savannah.cern.ch/bugs/?80076 + */ +class bug_80076: public TestConditionAlg { +public: + /// Constructor. + bug_80076(const std::string& name, ISvcLocator* pSvcLocator): + TestConditionAlg(name, pSvcLocator) {} + + /// Override the initialize to ensure that the conditions are already loaded + /// during the initialize. + StatusCode initialize() { + StatusCode sc = TestConditionAlg::initialize(); + if (sc.isFailure()) return sc; + + std::vector<std::string>::const_iterator path; + for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ + // this ensures that the objects are loaded in the transient store + exist<DataObject>(detSvc(), *path); + } + + return sc; + } +}; + +} + +// Declaration of the Algorithm Factory +DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, TestConditionAlg ) +DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, FinalizationEvtLoop ) +DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, bug_80076 ) -- GitLab From 318869c4aafe6df629b110b030e65d695eece014 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 14:41:34 +0100 Subject: [PATCH 28/37] Update HPD disable tool to take into account disable reports that related to more than one event, by adding an event weight. Also low custom report buffer sizes --- .../RichMonitoringTools/IHpdUkL1DisableTool.h | 8 ++- .../src/component/HpdUkL1DisableTool.cpp | 50 +++++++++++++------ .../src/component/HpdUkL1DisableTool.h | 18 +++++-- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/Rich/RichMonitoringTools/RichMonitoringTools/IHpdUkL1DisableTool.h b/Rich/RichMonitoringTools/RichMonitoringTools/IHpdUkL1DisableTool.h index 08d46e808..7ca78101b 100755 --- a/Rich/RichMonitoringTools/RichMonitoringTools/IHpdUkL1DisableTool.h +++ b/Rich/RichMonitoringTools/RichMonitoringTools/IHpdUkL1DisableTool.h @@ -191,11 +191,15 @@ namespace Rich /// send disable request virtual void DisableHPD ( const LHCb::RichSmartID &smartID, - const std::string & reason = "" ) = 0; + const std::string & reason = "", + const int bufferSize = -1, + const double eventWeight = 1 ) = 0; /// send disable request virtual void DisableHPD ( const HPDData& data, - const std::string & reason = "" ) = 0; + const std::string & reason = "", + const int bufferSize = -1, + const double eventWeight = 1 ) = 0; /// report HPD as having some issue but not necessarily so severe you'd want to disable it virtual void ReportHPD ( const LHCb::RichSmartID &smartID, diff --git a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp index b136b6ca4..1e22ae04a 100755 --- a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp +++ b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.cpp @@ -17,7 +17,7 @@ HpdUkL1DisableTool::HpdUkL1DisableTool( const std::string& type, const std::string& name, const IInterface* parent ) : Rich::HistoToolBase ( type, name, parent ), - m_Name ( name ) + m_Name ( name ) { // interface declareInterface<Rich::Mon::IHpdUkL1DisableTool>(this); @@ -26,17 +26,20 @@ HpdUkL1DisableTool::HpdUkL1DisableTool( const std::string& type, declareProperty( "FailureRateThreshold" , m_failureRateThreshold = 0.01 ); declareProperty( "Plot2DHisto" , m_Plot2DHisto = false ); declareProperty( "SendDisableCommands" , m_SendDisableCommands = true ); - declareProperty( "HistoryTime" , m_HistoryTime = 5*60 ); // 5 mins + declareProperty( "HistoryTime" , m_HistoryTime = 5*60 ); // 5 mins declareProperty( "ClearListAtNewRun" , m_ClearListAtNewRun = true ); - declareProperty( "UpdateTimerInterval" , m_UpdateTimerInterval = 30 ); //30 secs + declareProperty( "UpdateTimerInterval" , m_UpdateTimerInterval = 30 ); // 30 secs declareProperty( "BufferSize" , m_bufferSize = 1000 ); declareProperty( "DisableCheckInterval" , m_DisableCheckInterval = 100 ); - declareProperty( "DisableCheckHeartBeat", m_DisableCheckHeartBeat = 2 ); // 2 secs + declareProperty( "DisableCheckHeartBeat", m_DisableCheckHeartBeat = 2 ); // 2 secs declareProperty( "CameraSummaryInterval", m_CamSummaryInterval = 5*60 ); declareProperty( "AlwaysDisable" , m_AlwaysDisable = false ); // Count instances (only one allowed) ++s_HpdUkL1DisableTool_InstanceCounter; + + // enable debug for testing + //setProperty( "OutputLevel", 1 ); } //============================================================================= @@ -198,15 +201,20 @@ StatusCode HpdUkL1DisableTool::finalize() //============================================================================= void HpdUkL1DisableTool::DisableHPD ( const LHCb::RichSmartID &smartID, - const std::string & reason ) + const std::string & reason, + const int bufferSize, + const double eventWeight ) { - if ( smartID.isValid() ) { DisableHPD( hpdData(smartID), reason ); } + if ( smartID.isValid() ) { DisableHPD( hpdData(smartID), reason, + bufferSize, eventWeight ); } } //============================================================================= void HpdUkL1DisableTool::DisableHPD ( const HPDData& data, - const std::string& reason ) + const std::string& reason, + const int bufferSize, + const double eventWeight ) { if ( msgLevel(MSG::VERBOSE) ) { @@ -225,13 +233,19 @@ void HpdUkL1DisableTool::DisableHPD ( const HPDData& data, // Allocate memory for the buffer of the indices of the events // for a HPD candidate for disabling. - if ( ! b.first.capacity() ) b.first.set_capacity( m_bufferSize ); + if ( ! b.buffer.capacity() ) + { + b.buffer.set_capacity( bufferSize > 0 ? bufferSize : m_bufferSize ); + } + // set event weight + b.eventWeight = eventWeight; + // Keep the index of the event that has generated the disabling request. - b.first.push_back( m_nMonitoredEvents ); + b.buffer.push_back( m_nMonitoredEvents ); // save the reason - ++(b.second[reason]); + ++(b.reasons[reason]); } //============================================================================= @@ -393,10 +407,14 @@ void HpdUkL1DisableTool::DisableAndPublish() // Publish info for disabled HPDs. int newHPDsToDisable = 0; + _ri_verbo << "Found " << m_disableCandidates.size() << " HPD(s) to disable" << endmsg; for ( const auto& cand : m_disableCandidates ) { const auto & data = cand.first; - const auto & indices = cand.second.first; + const auto & indices = cand.second.buffer; + _ri_verbo << data << " " << indices.size() << " " << indices.capacity() + << " " << cand.second.eventWeight + << endmsg; // Only proceed if enough counts if ( indices.size() == indices.capacity() ) @@ -406,7 +424,7 @@ void HpdUkL1DisableTool::DisableAndPublish() const auto max = *std::max_element( indices.begin(), indices.end() ); const double failureRate = - ( max != min ? indices.size() / double( max - min ) : 0 ); + cand.second.eventWeight * ( max != min ? indices.size() / double( max - min ) : 0 ); _ri_verbo << "HPD " << data << " has received " << 100. * failureRate << "% of disable requests." << endmsg; @@ -431,7 +449,7 @@ void HpdUkL1DisableTool::DisableAndPublish() { // get the string we send to DIM for this HPD - const std::string hpdIDString = GetDisableString(data); + const auto hpdIDString = GetDisableString(data); if ( !hpdIDString.empty() ) { @@ -450,7 +468,7 @@ void HpdUkL1DisableTool::DisableAndPublish() m_CamTool->Append("TEXT",mess.str().c_str()); // Append the reasons for the disable to this camera report - PrintReasons( cand.second.second ); + PrintReasons( cand.second.reasons ); if ( hasZW ) m_CamTool->Append("TEXT"," -> Has ZERO UKL1 Disabling weight"); @@ -627,7 +645,7 @@ void HpdUkL1DisableTool::processUKL1DimString( L1DimStringWrap * dim ) m_CamTool->Append("TEXT",mess.str().c_str()); // Append the reasons for the disable to this camera report - PrintReasons( m_disableCandidates[HPD].second ); + PrintReasons( m_disableCandidates[HPD].reasons ); if ( hasZW ) { m_CamTool->Append("TEXT"," -> Has ZERO UKL1 Disabling weight"); } @@ -890,7 +908,7 @@ void HpdUkL1DisableTool::RefreshReports(const bool camPrint) std::ostringstream hpdS; hpdS << HPD << " " << smartID; m_CamTool->Append("TEXT",hpdS.str().c_str()); - PrintReasons( m_disableCandidates[HPD].second ); + PrintReasons( m_disableCandidates[HPD].reasons ); if ( hasZW ) m_CamTool->Append("TEXT"," -> Has ZERO UKL1 Disabling weight"); } diff --git a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h index 660a274af..69cb02c73 100755 --- a/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h +++ b/Rich/RichMonitoringTools/src/component/HpdUkL1DisableTool.h @@ -164,10 +164,14 @@ namespace Rich /// send disable request void DisableHPD( const LHCb::RichSmartID &smartID, - const std::string & reason = "" ); + const std::string & reason = "", + const int bufferSize = -1, + const double eventWeight = 1 ); /// send disable request void DisableHPD( const HPDData& data, - const std::string & reason = "" ); + const std::string & reason = "", + const int bufferSize = -1, + const double eventWeight = 1 ); /// report HPD as having some issue but not necessarily so severe you'd want to disable it void ReportHPD ( const LHCb::RichSmartID &smartID, @@ -193,7 +197,14 @@ namespace Rich }; typedef std::map<HPDData,CountReasonMapAndTime> HPDCountReasonMap; typedef boost::circular_buffer<unsigned long> Buffer; - typedef std::pair< Buffer, CountReasonMap > BufferAndReasons; + //typedef std::pair< Buffer, CountReasonMap > BufferAndReasons; + class BufferAndReasons + { + public: + Buffer buffer; + CountReasonMap reasons; + double eventWeight{1.0}; + }; typedef std::map< HPDData, BufferAndReasons > HPDBuffer; private: @@ -224,6 +235,7 @@ namespace Rich /// Is the HPD disabling active ? inline bool isHpdDisablingActive() const { + //return true; return ( m_AlwaysDisable || lhcbState() == LHCbState::InPhysics || lhcState() == "PHYSICS" || -- GitLab From dafc2e0abd451aa4e3ae959e5d469fbb2fb71b92 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 14:43:42 +0100 Subject: [PATCH 29/37] update missing HPD tool to pass new event weight to HPD disable tool --- .../src/RichMissingHPDMonitor.cpp | 17 ++++++++++++----- .../src/RichMissingHPDMonitor.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp index ce0867c9d..85265ba3e 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp @@ -70,7 +70,12 @@ StatusCode MissingHPDMonitor::execute() if ( m_vetoNoBias ) { const Gaudi::Math::Bit< unsigned int, 2 > bit{}; - if ( bit(odin->eventType()) ) { return sc; } + if ( UNLIKELY( bit(odin->eventType()) ) ) + { + //info() << "Rejecting No bias event" << endmsg; + return sc; + } + //else { info() << "Selecting event" << endmsg; } } // count events and print on the first @@ -99,6 +104,9 @@ StatusCode MissingHPDMonitor::execute() // check for valid HPD if ( !smartIDHPD.isValid() ) { continue; } + // For testing, intentionally ignore an HPD + //if ( smartIDHPD == LHCb::RichSmartID(Rich::Rich1,Rich::top,10,3) ) continue; + // Flag this HPD as having been seen in the data, with the event count number m_hpdCount[ smartIDHPD ] = m_nEvts; } @@ -121,9 +129,8 @@ StatusCode MissingHPDMonitor::execute() // it is missing std::ostringstream mess; mess << "HPD active but no data seen for " << m_maxMissingEvents << " events or more"; - //hpdDisableTool() -> ReportHPD( HPD, mess.str() ); - hpdDisableTool() -> DisableHPD( HPD, mess.str() ); - //warning() << mess.str() << endmsg; + hpdDisableTool() -> DisableHPD( HPD, mess.str(), 10, m_nEvts-m_lastEventCheck ); + warning() << HPD << " " << mess.str() << endmsg; } } } @@ -141,7 +148,7 @@ StatusCode MissingHPDMonitor::execute() mess << "HPD inactive but present in the data during the last " << m_maxMissingEvents << " events"; hpdDisableTool() -> ReportHPD( HPD, mess.str() ); - //warning() << mess.str() << endmsg; + warning() << HPD << " " << mess.str() << endmsg; } } } diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h index 8ea76ea30..df3a7a51e 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.h @@ -139,7 +139,7 @@ namespace Rich std::string m_Name; ///< Name for camera messages /// keep tabs on the seen HPDs and the event number last seen in - std::map<LHCb::RichSmartID,unsigned long int > m_hpdCount; + std::map<LHCb::RichSmartID,unsigned long long int> m_hpdCount; /// Which RICHes are active (based on partition) bool m_activeRICH[Rich::NRiches]; -- GitLab From e8deb39570c1c0ef8fbafa86eb9044758c77f4f7 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 14:44:12 +0100 Subject: [PATCH 30/37] Add outputlevel setting --- Rich/Panoptes/options/RichDAQMon-Common.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Rich/Panoptes/options/RichDAQMon-Common.py b/Rich/Panoptes/options/RichDAQMon-Common.py index 268943ab5..dd9d44f21 100644 --- a/Rich/Panoptes/options/RichDAQMon-Common.py +++ b/Rich/Panoptes/options/RichDAQMon-Common.py @@ -20,6 +20,8 @@ print "CondDBTag =", Panoptes().CondDBtag, "DDDBTag = ", Panoptes().DDDBtag # Task name... Panoptes().MonName = "RichDAQMon" + + # # Reconstruction options # @@ -113,6 +115,7 @@ RichMonitoringSysConf().HPDDisable_DisableCheckInterval = 999999 RichMonitoringSysConf().HPDDisable_DisableCheckHeartBeat = 3 RichMonitoringSysConf().HPDDisable_CameraSummaryInterval = 300 RichMonitoringSysConf().HPDDisable_AlwaysDisable = False +#RichMonitoringSysConf().OutputLevelDisable = 1 # # Histogram saver cycle -- GitLab From 7d0534e7578122366ec3bbe970a6382bc11f7b7c Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 15:29:03 +0100 Subject: [PATCH 31/37] Remove DetCOnd, not wanted in MR --- Det/DetCond/CMakeLists.txt | 37 - Det/DetCond/DetCond/CondDBGenericCnv.h | 126 -- Det/DetCond/DetCond/ICOOLConfSvc.h | 36 - Det/DetCond/DetCond/ICondDBAccessSvc.h | 108 -- Det/DetCond/DetCond/ICondDBEditor.h | 75 - Det/DetCond/DetCond/ICondDBReader.h | 110 -- Det/DetCond/cmt/requirements | 79 - Det/DetCond/doc/release.notes | 1247 -------------- Det/DetCond/options/UseOracle.py | 3 - Det/DetCond/python/DetCond/Configuration.py | 788 --------- Det/DetCond/python/DetCond/HistoCond.py | 104 -- Det/DetCond/python/DetCond/__init__.py | 0 Det/DetCond/src/Lib/CondDBGenericCnv.cpp | 139 -- Det/DetCond/src/component/COOLConfSvc.cpp | 281 ---- Det/DetCond/src/component/COOLConfSvc.h | 94 -- Det/DetCond/src/component/CondDBAccessSvc.cpp | 1492 ----------------- Det/DetCond/src/component/CondDBAccessSvc.h | 506 ------ Det/DetCond/src/component/CondDBCache.cpp | 444 ----- Det/DetCond/src/component/CondDBCache.h | 279 --- Det/DetCond/src/component/CondDBCnvSvc.cpp | 197 --- Det/DetCond/src/component/CondDBCnvSvc.h | 123 -- Det/DetCond/src/component/CondDBCommon.cpp | 90 - Det/DetCond/src/component/CondDBCommon.h | 29 - Det/DetCond/src/component/CondDBDQScanner.cpp | 147 -- Det/DetCond/src/component/CondDBDQScanner.h | 56 - .../src/component/CondDBDispatcherSvc.cpp | 294 ---- .../src/component/CondDBDispatcherSvc.h | 109 -- .../src/component/CondDBLayeringSvc.cpp | 288 ---- Det/DetCond/src/component/CondDBLayeringSvc.h | 103 -- Det/DetCond/src/component/CondDBLogger.cpp | 250 --- Det/DetCond/src/component/CondDBLogger.h | 147 -- Det/DetCond/src/component/CondDBReplayAlg.cpp | 162 -- Det/DetCond/src/component/CondDBReplayAlg.h | 60 - .../src/component/CondDBSQLiteCopyAccSvc.cpp | 135 -- .../src/component/CondDBSQLiteCopyAccSvc.h | 55 - .../src/component/CondDBTimeSwitchSvc.cpp | 363 ---- .../src/component/CondDBTimeSwitchSvc.h | 198 --- Det/DetCond/src/component/IOVListHelpers.cpp | 23 - Det/DetCond/src/component/IOVListHelpers.h | 10 - Det/DetCond/src/component/LoadDDDB.cpp | 101 -- Det/DetCond/src/component/LoadDDDB.h | 35 - Det/DetCond/src/component/RelyConverter.cpp | 479 ------ Det/DetCond/src/component/RelyConverter.h | 148 -- Det/DetCond/src/component/RunStampCheck.cpp | 140 -- Det/DetCond/src/dict/DetCondDict.h | 38 - Det/DetCond/src/dict/DetCondDict.xml | 14 - Det/DetCond/tests/data/DQFLAGS.db | Bin 48128 -> 0 bytes Det/DetCond/tests/data/HBTEST.db | Bin 76800 -> 0 bytes Det/DetCond/tests/data/RSTEST.db | Bin 48128 -> 0 bytes Det/DetCond/tests/data/TESTDB0.db | Bin 183296 -> 0 bytes Det/DetCond/tests/data/TESTDB1.db | Bin 79872 -> 0 bytes Det/DetCond/tests/data/TESTDB2.db | Bin 79872 -> 0 bytes Det/DetCond/tests/data/TESTDB3.db | Bin 183296 -> 0 bytes Det/DetCond/tests/data/genDQFLAGS.py | 39 - Det/DetCond/tests/data/genHBTEST.py | 48 - Det/DetCond/tests/data/genRSTEST.py | 32 - .../tests/qmtest/detcond.qms/bug_80076.qmt | 60 - .../qmtest/detcond.qms/check_db_reading.qmt | 4 - .../detcond.qms/configuration_module.qmt | 4 - .../qmtest/detcond.qms/connection_timeout.qmt | 11 - .../detcond.qms/direct_mapping_altern1.qmt | 22 - .../detcond.qms/direct_mapping_altern2.qmt | 25 - .../detcond.qms/direct_mapping_altern3.qmt | 23 - .../detcond.qms/direct_mapping_base.qmt | 19 - .../detcond.qms/direct_mapping_layers.qmt | 27 - .../detcond.qms/dqscanner.qms/basic.qmt | 63 - .../qmtest/detcond.qms/force_disconnect.qmt | 20 - .../qmtest/detcond.qms/get_iovs.qms/basic.qmt | 4 - .../tests/qmtest/detcond.qms/granularity.qmt | 79 - .../tests/qmtest/detcond.qms/heart_beat.qmt | 105 -- .../qmtest/detcond.qms/missing_condition.qmt | 35 - .../tests/qmtest/detcond.qms/run_stamp.qmt | 59 - .../tests/qmtest/detcond.qms/time_switch.qmt | 71 - .../qmtest/detcond.qms/update_in_finalize.qmt | 82 - Det/DetCond/tests/scripts/check_db_reading.py | 40 - .../scripts/configuration_module_test.py | 231 --- .../tests/scripts/connection_timeout.py | 22 - .../tests/scripts/direct_mapping_test.py | 86 - Det/DetCond/tests/scripts/force_disconnect.py | 28 - Det/DetCond/tests/scripts/getIOVs.py | 96 -- Det/DetCond/tests/src/DQScanTest.cpp | 106 -- Det/DetCond/tests/src/DQScanTest.h | 51 - Det/DetCond/tests/src/TestConditionAlg.cpp | 287 ---- 83 files changed, 11521 deletions(-) delete mode 100644 Det/DetCond/CMakeLists.txt delete mode 100755 Det/DetCond/DetCond/CondDBGenericCnv.h delete mode 100755 Det/DetCond/DetCond/ICOOLConfSvc.h delete mode 100755 Det/DetCond/DetCond/ICondDBAccessSvc.h delete mode 100755 Det/DetCond/DetCond/ICondDBEditor.h delete mode 100755 Det/DetCond/DetCond/ICondDBReader.h delete mode 100755 Det/DetCond/cmt/requirements delete mode 100755 Det/DetCond/doc/release.notes delete mode 100644 Det/DetCond/options/UseOracle.py delete mode 100755 Det/DetCond/python/DetCond/Configuration.py delete mode 100644 Det/DetCond/python/DetCond/HistoCond.py delete mode 100644 Det/DetCond/python/DetCond/__init__.py delete mode 100755 Det/DetCond/src/Lib/CondDBGenericCnv.cpp delete mode 100755 Det/DetCond/src/component/COOLConfSvc.cpp delete mode 100755 Det/DetCond/src/component/COOLConfSvc.h delete mode 100755 Det/DetCond/src/component/CondDBAccessSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBAccessSvc.h delete mode 100755 Det/DetCond/src/component/CondDBCache.cpp delete mode 100755 Det/DetCond/src/component/CondDBCache.h delete mode 100755 Det/DetCond/src/component/CondDBCnvSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBCnvSvc.h delete mode 100755 Det/DetCond/src/component/CondDBCommon.cpp delete mode 100755 Det/DetCond/src/component/CondDBCommon.h delete mode 100644 Det/DetCond/src/component/CondDBDQScanner.cpp delete mode 100644 Det/DetCond/src/component/CondDBDQScanner.h delete mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBDispatcherSvc.h delete mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBLayeringSvc.h delete mode 100755 Det/DetCond/src/component/CondDBLogger.cpp delete mode 100755 Det/DetCond/src/component/CondDBLogger.h delete mode 100755 Det/DetCond/src/component/CondDBReplayAlg.cpp delete mode 100755 Det/DetCond/src/component/CondDBReplayAlg.h delete mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h delete mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp delete mode 100755 Det/DetCond/src/component/CondDBTimeSwitchSvc.h delete mode 100644 Det/DetCond/src/component/IOVListHelpers.cpp delete mode 100644 Det/DetCond/src/component/IOVListHelpers.h delete mode 100755 Det/DetCond/src/component/LoadDDDB.cpp delete mode 100755 Det/DetCond/src/component/LoadDDDB.h delete mode 100755 Det/DetCond/src/component/RelyConverter.cpp delete mode 100755 Det/DetCond/src/component/RelyConverter.h delete mode 100644 Det/DetCond/src/component/RunStampCheck.cpp delete mode 100755 Det/DetCond/src/dict/DetCondDict.h delete mode 100755 Det/DetCond/src/dict/DetCondDict.xml delete mode 100644 Det/DetCond/tests/data/DQFLAGS.db delete mode 100644 Det/DetCond/tests/data/HBTEST.db delete mode 100644 Det/DetCond/tests/data/RSTEST.db delete mode 100755 Det/DetCond/tests/data/TESTDB0.db delete mode 100755 Det/DetCond/tests/data/TESTDB1.db delete mode 100755 Det/DetCond/tests/data/TESTDB2.db delete mode 100755 Det/DetCond/tests/data/TESTDB3.db delete mode 100644 Det/DetCond/tests/data/genDQFLAGS.py delete mode 100644 Det/DetCond/tests/data/genHBTEST.py delete mode 100755 Det/DetCond/tests/data/genRSTEST.py delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt delete mode 100644 Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt delete mode 100755 Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt delete mode 100755 Det/DetCond/tests/scripts/check_db_reading.py delete mode 100755 Det/DetCond/tests/scripts/configuration_module_test.py delete mode 100644 Det/DetCond/tests/scripts/connection_timeout.py delete mode 100755 Det/DetCond/tests/scripts/direct_mapping_test.py delete mode 100644 Det/DetCond/tests/scripts/force_disconnect.py delete mode 100755 Det/DetCond/tests/scripts/getIOVs.py delete mode 100644 Det/DetCond/tests/src/DQScanTest.cpp delete mode 100644 Det/DetCond/tests/src/DQScanTest.h delete mode 100755 Det/DetCond/tests/src/TestConditionAlg.cpp diff --git a/Det/DetCond/CMakeLists.txt b/Det/DetCond/CMakeLists.txt deleted file mode 100644 index 4f314aebe..000000000 --- a/Det/DetCond/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -################################################################################ -# Package: DetCond -################################################################################ -gaudi_subdir(DetCond v12r47) - -gaudi_depends_on_subdirs(Det/DetDesc - GaudiAlg - GaudiKernel - Kernel/LHCbKernel) - -find_package(Boost COMPONENTS system thread filesystem) -find_package(COOL COMPONENTS CoolKernel CoolApplication) -find_package(CORAL COMPONENTS CoralBase CoralKernel RelationalAccess) - -gaudi_add_library(DetCondLib - src/Lib/*.cpp - PUBLIC_HEADERS DetCond - INCLUDE_DIRS Boost COOL CORAL - LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel) - -gaudi_add_module(DetCond - src/component/*.cpp - tests/src/*.cpp - INCLUDE_DIRS Boost COOL CORAL - LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib) - -gaudi_add_dictionary(DetCond - src/dict/DetCondDict.h - src/dict/DetCondDict.xml - INCLUDE_DIRS Boost COOL CORAL - LINK_LIBRARIES Boost COOL CORAL DetDescLib GaudiAlgLib GaudiKernel LHCbKernel DetCondLib - OPTIONS "-U__MINGW32__") - -gaudi_install_python_modules() - - -gaudi_add_test(QMTest QMTEST) diff --git a/Det/DetCond/DetCond/CondDBGenericCnv.h b/Det/DetCond/DetCond/CondDBGenericCnv.h deleted file mode 100755 index 08f112058..000000000 --- a/Det/DetCond/DetCond/CondDBGenericCnv.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef DETCOND_CONDDBGENERICCNV_H -#define DETCOND_CONDDBGENERICCNV_H 1 - -// Include files -#include <string> -#include <functional> - -#include "GaudiKernel/Converter.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -#include "DetCond/ICondDBReader.h" - -#include "CoolKernel/types.h" - -// Forward and external declarations -class ISvcLocator; -class IDetDataSvc; -class DataObject; - -template <class TYPE> class CnvFactory; - -/** @class CondDBGenericCnv CondDBGenericCnv.h DetCond/CondDBGenericCnv.h - * - * Generic converter for the CondDBCnvSvc. This generic converter - * provides common functions to access the CondDB in order to make it - * easier to write specific converters. - * - * @author Marco CLEMENCIC - * @date December 2004 - */ -class CondDBGenericCnv: public Converter { -public: - /** - * Initializes the converter. - * Here the pointers to common services are taken: - * <ul> - * <li> CondDBCnvSvc - * <li> DetectorDataSvc - * </ul> - * @return status depending on the completion of the call - */ - virtual StatusCode initialize(); - - /** - * Finalizes the converter. - * It releases the pointers to the taken services. - * @return status depending on the completion of the call - */ - virtual StatusCode finalize(); - - /** - * Accessor to the StorageType value - * @return the storage type for this object - */ - static long storageType() { - return CONDDB_StorageType; - } - - /** - * Accessor to the StorageType value - * @return the storage type for this object - */ - virtual long repSvcType() const { - return CONDDB_StorageType; - } - -protected: - - /// Standard constructor - CondDBGenericCnv(ISvcLocator* svc,const CLID& clid); - - virtual ~CondDBGenericCnv( ); ///< Destructor - - /** - * Ask to the DetectorDataSvc the curren event time. - * @return StatusCode::SUCCESS if the event time was defined. - */ - StatusCode eventTime(Gaudi::Time &time) const; - - /** - * Set the validity of the DataObject if it inherits from IValidity. - */ - void setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject); - - /// Pointer to the DetectorDataService. - SmartIF<IDetDataSvc> m_detDataSvc; - /// Pointer to the ICondDBReader interface; - SmartIF<ICondDBReader> m_condDBReader; - - /** - * Get an object from the Conditions DB. It tries all the CondDBReaders - * known by CondDBCnvSvc before returing a failure code. - * @param[in] path the path inside the CondDB - * @param[in] channel CondDB channel id - * @param[out] obj shared pointer to the COOL object - * @param[out] descr folder description string (used to know the storage type by RelyConverter) - * @param[out] since start of the IOV - * @param[out] until end of the IOV - * The IOV is inside the object itself as two cool::ValidityKey, the since and until are - * used to avoid the conversion outside this method.<BR> - * If the path point to a FolderSet, channel is ignored and the boost::shared_ptr obj is - * set to NULL. - */ - StatusCode getObject(const std::string &path, const cool::ChannelId &channel, - ICondDBReader::DataPtr &obj, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until); - - /// Method kept for backward compatibility - inline StatusCode getObject(const std::string &path, - ICondDBReader::DataPtr &obj, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until) - { - return getObject(path,0,obj,descr,since,until); - } - - /// Find the children nodes of a given FolderSet path. - /// When using multiple databases, only the first one which contains - /// this folderset is used, so it must have at least dummy entries for each sub-node - /// (to be changed in the future). - StatusCode getChildNodes(const std::string &path,std::vector<std::string> &node_names); - -private: - -}; -#endif // DETCOND_CONDDBGENERICCNV_H diff --git a/Det/DetCond/DetCond/ICOOLConfSvc.h b/Det/DetCond/DetCond/ICOOLConfSvc.h deleted file mode 100755 index 5636805cf..000000000 --- a/Det/DetCond/DetCond/ICOOLConfSvc.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef DETCOND_ICOOLCONFSVC_H -#define DETCOND_ICOOLCONFSVC_H 1 - -// Include files -#include <GaudiKernel/IInterface.h> - -// Forward declarations -namespace coral { - class IConnectionService; -} -namespace cool { - class IDatabaseSvc; -} - -/** @class ICOOLConfSvc ICOOLConfSvc.h DetCond/ICOOLConfSvc.h - * - * Class used as interface to instantiate a COOL application and configure it - * (and CORAL). - * - * @author Marco CLEMENCIC - * @date 2007-12-07 - */ -class ICOOLConfSvc : virtual public IInterface { -public: - /// InterfaceID - DeclareInterfaceID(ICOOLConfSvc, 3, 0); - - /// Access to the CORAL connection service used by COOL (if needed). - virtual coral::IConnectionService& connectionSvc() = 0; - - /// Get the COOL Database service (used to connect to the databases). - virtual cool::IDatabaseSvc& databaseSvc() = 0; - -}; - -#endif // DETCOND_ICOOLCONFSVC_H diff --git a/Det/DetCond/DetCond/ICondDBAccessSvc.h b/Det/DetCond/DetCond/ICondDBAccessSvc.h deleted file mode 100755 index 85ae8d611..000000000 --- a/Det/DetCond/DetCond/ICondDBAccessSvc.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef DETCOND_ICONDDBACCESSSVC_H -#define DETCOND_ICONDDBACCESSSVC_H 1 - -// Include files -// from STL -#include <string> -#include <vector> -#include <set> -#include <map> - -// from Gaudi -#include <GaudiKernel/IInterface.h> - -// from COOL -#include "CoolKernel/types.h" -#include "CoolKernel/ChannelId.h" -#include "CoolKernel/pointers.h" -#include "CoolKernel/ValidityKey.h" - -// Forward declarations -namespace Gaudi { - class Time; -} -namespace cool { - class IRecord; - class IRecordSpecification; -} - -/** @class ICondDBAccessSvc ICondDBAccessSvc.h DetCond/ICondDBAccessSvc.h - * - * Class used as interface to LCG COOL library API. It should expose as less as - * possible COOL internal details. - * - * CondDBAccessSvc can be operated with only an in-memory CondDB, setting both the options NoBD and useCache to true. The memory - * database can be populated using cacheAddFolder and cacheAddObject (or their XML counter parts). The CondDB folders of the - * memory db are equivalent to COOL single-version folders (see COOL documentation for details). - * - * @author Marco CLEMENCIC - * @date 2005-01-11 - */ -class ICondDBAccessSvc : virtual public IInterface { -public: - /// InterfaceID - DeclareInterfaceID(ICondDBAccessSvc, 2, 0); - - /// Used to obtain direct access to the database. - virtual cool::IDatabasePtr& database() = 0; - - /// Convert from Gaudi::Time class to cool::ValidityKey. - virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const = 0; - - /// Convert from cool::ValidityKey to Gaudi::Time class. - virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const = 0; - - /// Return the currently set TAG to use. - virtual const std::string &tag() const = 0; - - /// Set the TAG to use. - virtual StatusCode setTag(const std::string &_tag) = 0; - - /// Return the connection string used to connect to the database. - virtual const std::string &connectionString() const = 0; - - /// Add a folder to the cache (bypass the DB) - virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec) = 0; - - /// Add a folder-set to the cache (bypass the DB) - virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr) = 0; - - /// Add an XML folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path) = 0; - - /// Add an XML folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) = 0; - - /// Add an object to the cache (bypass the DB) - virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const cool::IRecord &payload, cool::ChannelId channel = 0) = 0; - - /// Deprecated: use ICondDBAccessSvc::cacheAddXMLData instead - inline StatusCode cacheAddXMLObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string &data, cool::ChannelId channel = 0) - { - return cacheAddXMLData(path, since, until, data, channel); - } - - - /// Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string &data, cool::ChannelId channel = 0) = 0; - - /// Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::map<std::string,std::string> &data, cool::ChannelId channel = 0) = 0; - - /// Clear the cache - virtual void clearCache() = 0; - - /// Dump the cache (debug) - virtual void dumpCache() const = 0; - -protected: - -private: - -}; -#endif // DETCOND_ICONDDBACCESSSVC_H diff --git a/Det/DetCond/DetCond/ICondDBEditor.h b/Det/DetCond/DetCond/ICondDBEditor.h deleted file mode 100755 index 0edce1b8b..000000000 --- a/Det/DetCond/DetCond/ICondDBEditor.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef DETCOND_ICONDDBEDITOR_H -#define DETCOND_ICONDDBEDITOR_H 1 - -// Include files -// from STL -#include <string> -#include <map> -#include <set> - -// from Gaudi -#include "GaudiKernel/IInterface.h" - -// from COOL -#include "CoolKernel/types.h" -#include "CoolKernel/ChannelId.h" - -/** @class ICondDBEditor ICondDBEditor.h DetCond/ICondDBEditor.h - * - * - * @author Marco CLEMENCIC - * @date 2006-07-10 - */ -class ICondDBEditor : virtual public IInterface { -public: - /// InterfaceID - DeclareInterfaceID(ICondDBEditor, 2, 0); - - /// Possible recognized node types. - enum StorageType { FOLDERSET, XML, Native }; - /// Known types of leaf nodes (aka Folders). - enum VersionMode { SINGLE, MULTI }; - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - StorageType storage = XML, - VersionMode vers = MULTI) const = 0; - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - const std::set<std::string> &fields, - StorageType storage = XML, - VersionMode vers = MULTI) const = 0; - - /// Deprecated: use ICondDBEditor::storeXMLData instead. - inline StatusCode storeXMLString(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const - { - return storeXMLData(path, data, since, until, channel); - } - - /// Utility function that simplifies the storage of an XML string. - virtual StatusCode storeXMLData(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; - - /// Utility function that simplifies the storage of a set of XML strings. - virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const = 0; - - /// Tag the given leaf node with the given tag-name. - virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, - const std::string &description = "") = 0; - - /// Tag the given middle node with the given tag-name, recursively tagging the head - /// of child nodes with automatically generated tag-names. - virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, - const std::string &description = "") = 0; - -protected: - -private: - -}; -#endif // DETCOND_ICONDDBEDITOR_H diff --git a/Det/DetCond/DetCond/ICondDBReader.h b/Det/DetCond/DetCond/ICondDBReader.h deleted file mode 100755 index 0131d2e01..000000000 --- a/Det/DetCond/DetCond/ICondDBReader.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef DETCOND_ICONDDBREADER_H -#define DETCOND_ICONDDBREADER_H 1 - -// Include files -// from STL -#include <string> - -// from Gaudi -#include "GaudiKernel/IInterface.h" -#include "GaudiKernel/Time.h" - -// from LHCb -#include "Kernel/ICondDBInfo.h" - -// from COOL -#include "CoolKernel/types.h" -#include "CoolKernel/pointers.h" -#include "CoolKernel/ChannelId.h" - -// Forward declarations -namespace cool { - class IRecord; -} - -/** @class ICondDBReader ICondDBReader.h DetCond/ICondDBReader.h - * - * Interface to retrieve data from the conditions database. - * - * @author Marco Clemencic - * @date 2006-07-10 - */ -class ICondDBReader : virtual public ICondDBInfo { -public: - /// InterfaceID - DeclareInterfaceID(ICondDBReader, 2, 1); - - /// virtual destructor - virtual ~ICondDBReader() {} - -#ifdef COOL_HAS_CPP11 - typedef std::shared_ptr<const cool::IRecord> DataPtr; -#else - typedef boost::shared_ptr<const cool::IRecord> DataPtr; -#endif - - /// Helper class to easily manage an interval of validity as a pair of Gaudi::Time - /// instances. - struct IOV { - /// Constructor - IOV(Gaudi::Time _since = Gaudi::Time::epoch(), - Gaudi::Time _until = Gaudi::Time::max()): - since(_since), until(_until) - {} - /// Boundaries of the interval. - Gaudi::Time since, until; - /// Define a simple order between two IOV instances. - inline bool operator<(const IOV& rhs) const { - return since < rhs.since; - } - }; - - /// List of IOV instances. - typedef std::vector<IOV> IOVList; - - /// Retrieve data from the condition database. - /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0) = 0; - - /// Retrieve data from the condition database. - /// Returns a shared pointer to an attribute list, the folder description and the IOV limits. - /// (Version with alphanumeric channel id) - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) = 0; - - /// @{ - /// Return the list of occupied IOVs in the given path and channel, for the given IOV. - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0) = 0; - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel) = 0; - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names) = 0; - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) = 0; - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path) = 0; - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path) = 0; - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path) = 0; - - /// Disconnect from the database. - virtual void disconnect() = 0; - -protected: - -private: - -}; - -#endif // DETCOND_ICONDDBREADER_H diff --git a/Det/DetCond/cmt/requirements b/Det/DetCond/cmt/requirements deleted file mode 100755 index 2770d40a8..000000000 --- a/Det/DetCond/cmt/requirements +++ /dev/null @@ -1,79 +0,0 @@ -# ==================================================================== -package DetCond -version v12r47 - -# =========== structure =================================================== -branches DetCond doc cmt src - -# =========== dependencies ================================================ -use GaudiKernel v* -use GaudiAlg v* -use COOL v* LCG_Interfaces -use CORAL v* LCG_Interfaces -use Boost v* LCG_Interfaces -use DetDesc v* Det - -# This one is for the interface ICondDBInfo and IDQScanner -use LHCbKernel v* Kernel - -macro_append Boost_linkopts " $(Boost_linkopts_system) " - - -# =========== own includes ================================================ -apply_pattern install_more_includes more=DetCond - -#===================================================================== -# Needed to resolve external symbols -apply_tag NEEDS_COOL_FACTORY -apply_tag NEEDS_CORAL_RELATIONAL_ACCESS -# Work-around for a problem in COOL/CORAL requirements files (after fix to bug #41579) -macro CORAL_linkopts ' $(CORAL_libs) $(CORAL_relacc_libs) ' - -# =============== LCG Dictionary =========================================== -apply_pattern reflex_dictionary \ - dictionary=DetCond \ - headerfiles=$(DETCONDROOT)/src/dict/DetCondDict.h \ - selectionfile=$(DETCONDROOT)/src/dict/DetCondDict.xml \ - options="-U__MINGW32__" -# Disable some compiler warnings in the automatically generated dict code -macro_append DetCondDict_cppflags "" \ - target-icc " -wd2259" - -# =========== constituents ================================================= -library DetCondLib Lib/*.cpp -library DetCond component/*.cpp ../tests/src/*.cpp - -# =========== standard patterns (the order is essential!) ====================== -apply_pattern component_library library=DetCond -apply_pattern linker_library library=DetCondLib - -private -# DetCond Configurable uses the generated configurables -macro_append DetCondGenConfUser_dependencies DetCondConfDbMerge -# Have to look in local DetCondConf.py, install_python has to come later -path_prepend PYTHONPATH ${DETCONDROOT}/genConf -end_private -apply_pattern install_python_modules - -# ==================================================================== -private - -macro_append DetCond_use_linkopts " $(Boost_linkopts_thread) $(Boost_linkopts_filesystem_mt) $(Boost_linkopts_date_time) " - -apply_pattern QMTest -# ===================================== -# Packages needed for tests -macro DetCond_use_CondDBUI "" QMTest "CondDBUI v* Tools" -use $(DetCond_use_CondDBUI) - -macro DetCond_use_DDDB "" QMTest "DDDB v* Det" -use $(DetCond_use_DDDB) - -macro DetCond_use_DetDescSvc "" QMTest "DetDescSvc v* Det" -use $(DetCond_use_DetDescSvc) - -macro DetCond_use_DetDescCnv "" QMTest "DetDescCnv v* Det" -use $(DetCond_use_DetDescCnv) -# ===================================== - -end_private diff --git a/Det/DetCond/doc/release.notes b/Det/DetCond/doc/release.notes deleted file mode 100755 index 71d560ebc..000000000 --- a/Det/DetCond/doc/release.notes +++ /dev/null @@ -1,1247 +0,0 @@ -!----------------------------------------------------------------------------- -! Package : Det/DetCond -! Responsible : Marco Clemencic -! Purpose : Interface between LHCb and LGC/COOL project -!----------------------------------------------------------------------------- - -! 2016-03-31 - Roel Aaij - - Fix CondDB configuration. The online snapshots were configured even if - UseDBSnapshot was set to True. - -!========================= DetCond v12r47 2016-03-18 ========================= -! 2016-03-18 - Roel Aaij - - Remove configuration of environment variables meant to setup access to the - LHCb online oracle instance. This should be done online as part of the - environment. - -!========================= DetCond v12r46 2016-01-27 ========================= -! 2016-01-06 - Gerhard Raven - - prefer SmartIF over raw pointer to interface - -! 2015-12-17 - Christopher Burr - - Prevent CondDBCache from logging " FOUND" as a warning - -!========================= DetCond v12r45 2015-11-23 ========================= -! 2015-11-02 - Gerhard Raven - - pass sink arguments by value, and std::move them - - replace deprecated std::auto_ptr with std::unique_ptr - - prefer range-based for loops - - prefer emplace_back over push_back - -!========================= DetCond v12r44 2015-10-12 ========================= -! 2015-09-25 - Liang Sun - - Remove references to SQLDDDB*.py option files - - If UseOracle & Online options are both set to True, the Oracle ONLINE db is used, instead of sqlite db files - -! 2015-08-03 - Gerhard Raven - - remove #include of obsolete Gaudi headers - -!========================= DetCond v12r43 2015-07-20 ========================= -! 2015-06-30 - Marco Clemencic - - Fixed LHCBPS-1425: ensure that the "InitialTime" is stable. - -! 2015-06-25 - Eduardo Rodrigues - - Undid the reference update from yesterday as the difference is in fact - *not* expected nor understood, see https://its.cern.ch/jira/browse/LHCBPS-1425. - -! 2015-06-24 - Eduardo Rodrigues - - Updated expected reference block for test force_disconnect. - -!========================= DetCond v12r42 2015-06-17 ========================= -! 2015-06-16 - Marco Clemencic - - LHCBPS-1421: Modified RunStampCheck to instantiate EventClockSvc. - To ensure that it does get a "current event time", RunStampCheck triggers - the instantiation of EventClockSvc, so that it is not needed to explicitly - do it in the configuration. - -! 2015-06-16 - Marco Clemencic - - LHCBPS-1421: Updated CondDB configurable to enable/disable RunStampCheck - The RunStampCheck is enabled by default for "Offline" (i.e. not Online - nor Simulation). - -! 2015-06-11 - Marco Clemencic - - LHCBPS-1421: added a first implementation of RunStampCheck - The optional service RunStampCheck can be instantiated (via - ApplicationManager::ExtSvc) to check if a special "run stamp" - condition exist for the current run. - -! 2015-06-05 - Liang Sun - - Set LoadCALIBDB default value to HLT1 for Simulation option - -! 2015-06-05 - Liang Sun - - Set LoadCALIBDB default value to HLT1 for Online and Upgrade options - - Change in detcond.configuration_module to avoid checking layered ONLINE partition - -! 2015-06-04 - Liang Sun - - Finalized support for CALIBOFF by loading the partition as an additional layer only above every ONLINE snapshot no earlier than 2015 - - Bug fix for mistakenly loading CALIBOFF for upgrade CondDB - -!========================= DetCond v12r41 2015-04-20 ========================= -! 2015-04-16 - Liang Sun - - Further support for loading CALIBOFF.db file as an additional layer above all partitions, for testing purpose only - -! 2015-03-18 - Liang Sun - - Fix the nightlies after the last commit. The XML extensions of the condition files within TESTDB?.db are now removed. - -! 2015-03-12 - Marco Clemencic - - Changed the policy of CondDB::generateXMLCatalog to exclude folders with - names ending with ".xml" from the generated catalog. - This is required to allow mixed content in the Online CondDB partition for - the split Hlt, where the files with ".xml" are not meant to be automatically - mapped. - -!========================= DetCond v12r40p1 2015-01-14 ========================= -! 2015-01-07 - Marco Cattaneo - - Fix gcc49 unused function warning in DQScanTest.cpp - -!========================= DetCond v12r40 2014-12-11 ========================= -! 2014-12-03 - Liang Sun - - In Configuration.py: Fixing the cases without valid DQFLAGS tags - -! 2014-12-02 - Liang Sun - - In Configuration.py: Adding option LatestGlobalTagByDataTypes to allow for multiple datatypes. - - In Configuration.py: Inclusion of DQFLAGS to assign the most recent tag for a given datatype - -!========================= DetCond v12r39 2014-10-14 ========================= -! 2014-10-07 - Gerhard Raven - - DetCond configurable: remove explicit paritition name and defer this to the - keys (i.e. filename) in the RunChangeHandlerCondiions map. - -!========================= DetCond v12r38 2014-09-30 ========================= -! 2014-09-30 - Gerhard Raven - - DetCond configurable: combine the RunChangeHandlerConditions and XMLFilename - properties into a single dictioary of filename -> list of conditions so that - the RunChangeHandler can be configured to use multiple <subsystem>_<runnr>.xml - files. - - avoid a spurios warning about ONLINE tag - -!========================= DetCond v12r37 2014-09-08 ========================= -! 2014-09-02 - Liang Sun - - In Configuration.py: Keep the lines related to the import of SQLDDDB-Oracle.py for the UseOracle option, in order not to fail the nightlies - -! 2014-09-01 - Liang Sun - - Changes in Configuration.py: - - Removal of the support for Oracle by commenting out the lines related to the option "UseOracle" - - Added a layer of CALIBOFF above LHCBCOND when LoadCALIBDB option is OFFLINE - -! 2014-07-24 - Liang Sun - - Added qmtest module "detcond.check_db_reading" to check the db reading functionality in Tools/CondDBUI - - -!========================= DetCond v12r36 2014-05-12 ========================= -! 2014-05-05 - Gerhard Raven - - do not truncate partitionname - -!========================= DetCond v12r35 2014-04-29 ========================= - -!========================= DetCond v12r34 2014-04-29 ========================= - -! 2014-04-28 - Gerhard Raven - - make the conditions which the RunChangeHanderSvc updates a property - - make the (last part of the) filename used by the RunChangeHandlerSvc a property - -! 2014-03-26 - Liang Sun - - CondDB preparation for 2015 in Configuration.py: new CondDB partitions 'CALIB' - and 'CALIBOFF' as additional layers above 'ONLINE' partition. New options for - 'LoadCALIBDB' to enable/disable loading the new layers. The default option is - to add the new layers from $SQLITEDBPATH/CALIB-[YEAR].db and $SQLITEDBPATH/CALIBOFF.db - files automatically if exist. - -!========================= DetCond v12r33 2014-02-17 ========================= -! 2013-12-05 - Marco Clemencic - - Fixed the use of boost::shared_ptr according to the macro COOL_HAS_CPP11 (the - one used in COOL headers). - -! 2013-12-05 - Marco Clemencic - - Do not explicitly use boost::shared_ptr. - See https://sft.its.cern.ch/jira/browse/ROOT-5806 - -! 2013-07-18 - Marco Clemencic - - Minor change. - -!========================= DetCond v12r32 2013-07-17 ========================= -! 2013-06-12 - Marco Cattaneo - - Add virtual destructor to ICondDBReader interface class. Fixes gcc48 warning - virtual-move-assign, see explanation in https://sft.its.cern.ch/jira/CFHEP-87 - -!========================= DetCond v12r31 2013-06-03 ========================= -! 2013-05-07 - Marco Clemencic - - Moved the class CondDBCompression to Tools/CondDBEntityResolver, including - dictionary and tests. - -! 2013-05-02 - Liang Sun - - Removed one defunct line to please Coverity. Added in GaudiException() to handle LZMA errors - -!========================= DetCond v12r30 2013-04-29 ========================= -! 2013-04-26 - Liang Sun - - Removed all references to BZip2. We still need 32Bit machines - -! 2013-04-26 - Marco Clemencic - - Removed the temporary hack used for C++11 (it was needed only because Boost - was not yet built with C++11 enabled). - -! 2013-04-25 - Marco Clemencic - - Fixed an issue with the previous change (the environment variable expansion - was prevented in too many places). - -! 2013-04-24 - Illya Shapoval - - A bug fix: an expansion of the SQLITEUPGRADEDBPATH env. variable is prevented. - -! 2013-04-18 - Liang Sun - - Two redundant variables removed to quell the warning messages. - -! 2013-04-17 - Liang Sun - - Added the compression method of LZMA from ROOT with the assigned method number at 0, the method number for BZip2 now changed to 1. - -! 2013-04-02 - Marco Cattaneo - - Fix UNINIT_CTOR defects - -! 2013-03-21 - Liang Sun - - Minor fix on a few potential memory leaks - - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45083&defectInstanceId=156348385&fileInstanceId=111518946 - - http://lhcb-coverity.cern.ch:8080/sourcebrowser.htm?projectId=10002#mergedDefectId=45084&defectInstanceId=156348386&fileInstanceId=111518946 - -! 2013-03-18 - Vanya Belyaev - - - comment usage of python module from removed package HistoStrings - -! 2013-03-12 - Marco Clemencic - - Added hints to Coverity to fix a few flas positives: - - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45071&defectInstanceId=156278261&fileInstanceId=111423297 - - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45070&defectInstanceId=156277446&fileInstanceId=111423297 - - https://lhcb-coverity.cern.ch:8443/sourcebrowser.htm?projectId=10002#mergedDefectId=45069&defectInstanceId=156277445&fileInstanceId=111423297 - -! 2013-03-12 - Liang Sun - - Minor fix on coverity defects (0&i++) - -! 2013-03-11 - Liang Sun - - Set up prototype to allow multiple compression methods, with an additional byte identifying the method prepended to the compressed string - -! 2013-03-08 - Marco Clemencic - - Fixed compilation on 32 bits with a hack (the 32 bits dev version of bz2 - cannot be installed on lxbuild because of missing templates). - -! 2013-02-27 - Liang Sun - - Fix the type conversions to quell the -pedantic warnings - -! 2013-02-23 - Marco Clemencic - - Forgot to add -lbz2 after removing the 'use' statement. - -! 2013-02-22 - Marco Clemencic - - Added use of BZip2 in CMakeLists.txt and removed the use of LCG_Interfaces/bz2lib - from the requirements (we must pick up the system version because the one in - lcg/externals is obsolete and deprecated). - -! 2013-02-21 - Liang Sun - - Added functionalities of compression and decompression on CondDB with new class CondDBCompression - -!========================= DetCond v12r29 2013-02-04 ========================= -! 2012-12-20 - Marco Clemencic - - Stop the TimeOutChecker thread when explicitly disconnected. The thread is - restarted automatically when we reconnect. - -!========================= DetCond v12r28 2012-11-26 ========================= -! 2012-11-21 - Marco Clemencic - - Modified the ICondDBReader interface to allow explicit disconnection from - databases (useful after a fork). - -! 2012-11-15 - Marco Clemencic - - Added CMake configuration file. - -!========================= DetCond v12r27 2012-09-28 ========================= -! 2012-09-26 - Marco Clemencic - - Removed comments from __init__.py - -! 2012-09-21 - Marco Clemencic - - Temporary hack to compile with -std=c++11 (-std=c++0x). - -! 2012-08-09 - Marco Clemencic - - Workaround for bug #96673. - -! 2012-08-08 - Marco Clemencic - - Added python/DetCond/__init__.py. - -!========================= DetCond v12r26 2012-07-24 ========================= -! 2012-07-10 - Patrick Koppenburg - - Bug: https://savannah.cern.ch/bugs/?94454 - . Allow _configureDBSnapshot to work without UseOracle = True statement - . Remove MagneticFieldSvc().UseSetCurrent = True that should be set - in the application's configuration. - -!========================= DetCond v12r25 2012-06-25 ========================= -! 2012-06-12 - Illya Shapoval - - Configuration.py: - + new property is added. "CondDB().Upgrade = True" will switch the CondDB - machinery to talk to the Upgrade database. - + three new properties are added: - CondDB().LatestGlobalTagByDataType = "DataType0" - CondDB().LatestLocalTagsbyDataType = ["DataType1","DataType2",...] - CondDB().AllLocalTagsbyDataType = ["DataType1","DataType2",...] - Setting this will launch the SAX machinery to fetch and set the latest - global tags, latest locals tags, and all local tags, respectively, marked - with requested DataType(s). This is an extension to the previous configuration - machinery (CondDB().UseLatestTags = ["DataType"]) which is still supported. - -!========================= DetCond v12r24 2012-05-02 ========================= -! 2012-04-26 - Patrick Koppenburg - - Configuration: add properties allowing to configure from online_RunNumber.xml - snapshots. For Online Brunel. This is stolen from Moore. - -!========================= DetCond v12r23 2012-02-01 ========================= -! 2012-02-01 - Marco Clemencic - - Modified DQScanTest to work around a small problem in the configuration on - 32 bits builds. - -! 2012-01-31 - Marco Clemencic - - Implemented CondDBDQScanner: a tool to collect (merge) the DQ flags from the - Conditions Database in a given IOV. - - Added a test to validate the output of CondDBDQScanner. - -! 2012-01-31 - Marco Clemencic - - Fixed a couple of compilation warnings. - -! 2012-01-30 - Marco Clemencic - - Added new methods to the ICondDBReader interface (getIOVs), to retrieve the - list of IOVs in a folder for an IOV. - - Added a test for the implementation of getIOVs in CondDBAccessSvc, and fixes. - -! 2012-01-06 - Marco Clemencic - - Modified LoadDDDB to trigger the initialization of the UpdateManagerSvc in - the initialize (to avoid that is gets triggered in the middle of an event). - -! 2012-01-05 - Marco Clemencic - - Fixed ICC warning (Boost 1.48). - -!========================= DetCond v12r22 2011-12-14 ========================= -! 2011-12-09 - Marco Cattaneo - - Add explicit Boost_linkopts for compatibility with Gaudi v23 - -!========================= DetCond v12r21 2011-08-30 ========================= -! 2011-08-26 - Alexander Mazurov - - Update of parser function in CondDBTimeSwitchSvc. This version works only with - Gaudi version > v22r2 (where the new parser model is provided) - -!========================= DetCond v12r20 2011-07-25 ========================= -! 2011-07-20 - Marco Cattaneo - - Create MSG::VERBOSE and MSG::DEBUG messages only when output level requires - it, also using UNLIKELY macro - -!========================= DetCond v12r19 2011-06-14 ========================= -! 2011-06-06 - Illya Shapoval - - Another minor add-on for the 'UseLatestTags' warning output case. - -! 2011-06-03 - Illya Shapoval - - Added a missing configuration bit for the case of per-year-made ONLINE - snapshots: if per-year scheme is met 'CondDBAccessSvc' services are also - created per-year (before they were created per-month but pointing to a single - per-year ONLINE snapshot). SQLDDDB needs a minor change to enable this - configuration change. - - Warnings about latest tags usage are made more meaningful. - -!========================= DetCond v12r18 2011-04-04 ========================= - **** requires LHCbKernel > v12r8 **** -! 2011-03-31 - Marco Clemencic - - Modified the interfaces to use the pattern of Gaudi v21. - - Fixed a few Eclipse warnings. - - Removed CVS keywords. - - Added the possibility to fetch condition for a range of times instead of - only for the current event time. The CondDBAccessSvc property QueryGranularity - can be used to define the width of the time range (around the event time) to - use. The boundaries are rounded so that the requested range is stable. For - example, with a granularity of one hour, the event times 19:10:00, 19:23:15, - 19:56:10 will all fetch the same range 19:00:00-20:00:00. - The set the QueryGranularity property in a standard configuration: - - import GaudiKernel.SystemOfUnits as Units - Units.hours = Units.s * 3600 - - from Configurables import CondDB - CondDB(QueryGranularity = 2 * Units.hours) - -! 2011-03-28 - Marco Clemencic - - Added a test to expose bug #80076 (wrong condition used on first event). - -!========================= DetCond v12r17 2011-01-31 ========================= -! 2011-01-28 - Illya Shapoval - - Configuration machinery is upgraded to load DQFLAGS partition (implemeted in - standalone SQLite file in SQLDDDB) to populate '/Conditions/DQ/Flags' - condition of LHCBCOND partition. SIMCOND has a placeholder for this condition - too but remains empty (there is no need in DQ flags in simulations). - -! 2011-01-10 - Marco Cattaneo - - Fix icc warnings and remarks - -!========================= DetCond v12r16 2010-10-28 ========================= - -! 2010-10-28 - Marco Clemencic - - Fixed a 32bit compilation problem in some new test code. - -! 2010-10-25 - Marco Clemencic - - Added a test to expose bug #74255 - (fake event loop during finalize doesn't work). - -! 2010-10-17 - Illya Shapoval - - CondDBAccessSvc method getChildNodes is modified to load only those Online - folders in SIMCOND which are tagged with a tag being set to load db. - Modification is done in a binary backwards compatible way. - -!===================== Det/DetCond v12r15 2010-09-28 ========================= -! 2010-09-28 - Marco Clemencic - - Updated tests to expect the return codes of Gaudi (v21r11). - -! 2010-09-24 - Marco Clemencic - - Added a test to verify that a failure to load a condition in the - UpdateManagerSvc is properly reported. - -!===================== Det/DetCond v12r14 2010-08-25 ========================= -! 2010-08-06 - Marco Clemencic - - Improved DetCondTest::TestConditionAlg to allow testing artificial - dependencies between conditions. - - Modified test detcond.heart_beat to expose bug #66497 (velo motor positions - updated several times). - -!===================== Det/DetCond v12r13 2010-05-21 ========================= -! 2010-05-18 - Marco Clemencic - - Fixed few Windows warnings. - -! 2010-05-12 - Marco Clemencic - - Modified the message printed in case of a failure of the heart-beat check to - show the time in human-readable format (UTC). - -!===================== Det/DetCond v12r12 2010-04-09 ========================= -! 2010-03-27 - Illya Shapoval - - CondDB configurable is tuned to override all default and user tags settings - by the latest tags for defined DataType if the 'UseLatestTags' property is - set (before an exception was thrown if found multiple definitions). - -! 2010-03-26 - Illya Shapoval - - Added new CondDB().UseLatestTags = [DataType,OnlyGlobalTags=False] property. - Previous CondDB().useLatestTags(DataType,OnlyGlobalTags=False) method is - preserved. Now it is possible to set the latest tags also for the simulation - case. - -!===================== Det/DetCond v12r11 2010-03-17 ========================= -! 2010-03-17 - Marco Clemencic - - Changes to the CondDB configurable - - in the online environment (Online == True) the IgnoreHeartBeat property is - defaulted to True - - added the property HeartBeatCondition to set the location of the heart-beat - condition - -! 2010-03-05 - Marco Clemencic - - Fixed a problem in the CondDB configurable for the usage of Oracle in the - PIT. - -! 2010-02-25 - Marco Clemencic - - Removed the dependency on rx (obsolete). - -!===================== Det/DetCond v12r10 2010-02-12 ========================= -! 2010-02-12 - Illya Shapoval - - Minor change to the CondDB.useLatestTags(DataType) function. Added the - mode for it to find and set only the latest global tag for a - particular DataType, dropping the latest local tags on top of it. - New syntax: CondDB.useLatestTags(DataType,OnlyGlobalTags = False). - -! 2010-02-05 - Marco Clemencic - - Added the function CondDB.useLatestTags(DataType) to automatically select - the latest local and global tags for a given data type from the SQLDDDB - release notes. - -!===================== Det/DetCond v12r9 2010-01-20 ========================== -! 2010-01-19 - Marco Clemencic - - Fixes to the first implementation of task #13270. - - Handle properly cool and coral exceptions when retrieving the heart beat - condition to be able to issue a meaningful error. - - Modified the automatic setting of the HeartBeatCondition property for the - readers of CondDBTimeSwitchSvc. The property is added only to the last - reader because the other readers are (by construction) accessing limited - partitions. - -! 2010-01-12 - Marco Clemencic - - Completed task #13270: Block access to conditions in ONLINE partition if - validity interval is not closed - - Modified CondDBAccessSvc to accept a new property (HeartBeatCondition). The - property specified the path in the database to be used as heart beat, i.e. - the partition is considered not up-to-date if the latest update of that - condition is less recent than the event time being processed. - Since the test is done only when actually accessing the CondDBAccessSvc, - to ensure that we get there when the event exceeds the validity of the - database, the returned validities are artificially cut at the latest heart - beat. - - Modified the ConfigurableUser CondDB to set the HeartBeatCondition for the - Online partition and snapshots (can be disabled with the property - IgnoreHeartBeat). - - Removed the OnlineDBValidatorSvc because it is not needed anymore. - - Adapted the TestCondition algorithm to test the new feature and added the - relative test. - NOTE: In the special case when there are conditions with initial validity - after the latest heart beat, there may be problem during the initialize - if exposed validity (artificially cut) is checked (the UpdateManagerSvc - and the DetectorDataSvc are not doing it). - - Added the properties "DisableLFC" and "Online" to the ConfigurableUser CondDB - to be able to ignore the LFC when using Oracle and enable special - configuration for the Online environment (Oracle). - -!===================== Det/DetCond v12r8 2009-12-11 ========================== -! 2009-12-11 - Marco Cattaneo - - Remove obsolete file DetCond_dll.cpp - -! 2009-12-05 - Dmitry GOLUBKOV - - python/DetCond/HistoCond.py: new python module to decorate the Condition - object with functions which extract the histograms from the parameters and to - define functions which convert histograms to Condition parameter xml strings. - - cmt/requirements: version increment to v12r8 - -!===================== Det/DetCond v12r7 2009-06-16 ========================== -! 2009-06-03 - Marco Clemencic - - Changes in the CondDB ConfigurableUser: - - Fixed a bug causing a failure when using SQLite local copies and - CondDBTimeSwitchSvc. - - Changed the policy when both UseOracle and SQLiteLocalCopiesDir are active: - issue a warning and ignores SQLiteLocalCopiesDir instead of raising an - exception. - -!===================== Det/DetCond v12r6 2009-05-28 ========================== -! 2009-04-28 - Marco Cattaneo - - In Configurable, do not access MessageSvc() directly, use instead - getConfigurable("MessageSvc"), allow to replace MessageSvc instance online - -! 2009-05-27 - Marco Clemencic - - Modified the way CondDBAccessSvc::finalize() synchronizes with the second - thread. - - Updated the usage of the Boost Thread module (use more recent classes). - - Added a test triggering the connection time-out. - -!===================== Det/DetCond v12r5p3 2009-05-06 ======================== -! 2009-04-17 - Marco Cattaneo - - Replace endreq by endmsg - -!===================== Det/DetCond v12r5p2 2009-03-09 ======================== -! 2009-03-09 - Marco Cattaneo - - Add options/UseOracle.py: additional options for gaudirun.py command line - to get conditions from Oracle DB - -!===================== Det/DetCond v12r5p1 2009-02-18 ======================== -! 2009-01-29 - Marco Cattaneo - - Fix compilation warning from Boost 1.38 - -!===================== Det/DetCond v12r5 2009-01-08 ========================== -! 2009-01-07 - Marco Clemencic - - Improvements to the CondDB configurable: - - added the possibility to use local copies of the SQLite databases (through - CondDBSQLiteCopyAccSvc) - - added the possibility of specifying alternatives and layers with only the - connection string or the SQLite filename - -!===================== Det/DetCond v12r4 2008-11-17 ========================== -! 2008-11-17 - Marco Cattaneo - - Fix to requirements avoid warnings when making configurables database - - Add LoadDDDB algorithm, moved from DetDescChecks to avoid tests dependency - on DetDescChecks package - - Add missing dependencies for QMTest - -! 2008-11-14 - Marco Cattaneo - - In Configurable, set up VFSSvc, e.g. for use by ParticlePropertySvc - -! 2008-11-11 - Marco Clemencic - - Fixed configuration problems in the test after the changes in DDDB. - -! 2008-11-06 - Marco Clemencic - - Added the ConfigurableUser CondDB for the high level configuration of the - conditions database. The old configuration function (addCondDBLayer etc.) are - still available for backward compatibility, but implemented using the new - configurable which allows to specify local tags too. - -! 2008-10-31 - Marco Cattaneo - - Fix for gcc 4.3 - - NEEDS: LCGCMT > 55a - -! 2008-10-10 - Marco Clemencic - - Modified the requirements file following the changes in the CORAL interface - package (see bug #41579). - -!===================== Det/DetCond v12r3 2008-09-30 ========================== -! 2008-09-29 - Marco Clemencic - - Fixed a bug in CondDBCommon::generateXMLCatalog, failing for folders with - names shorter than 4 chars. - -!===================== Det/DetCond v12r2 2008-07-30 ========================== -! 2008-07-30 - Marco Clemencic - - Changed the name of the configurables for online partition from ONLINE-YYYYMM - to ONLINE_YYYYMM. - -! 2008-07-28 - Marco Cattaneo - - Fix windows compilation - -! 2008-07-23 - Marco Clemencic - - Changed the type of CondDBDispatcherSvc.Alternatives from list of strings - to map<string,string>. - - Added tests for DetCond.Configuration. - - Fixed a problem with conversion between 'double' and 'long long' in - CondDBTimeSwitchSvc. - -! 2008-07-21 - Marco Clemencic - - Added a function to DetCond.Configuration (configureOnlineSnapshots) to - prepare the configuration using monthly snapshots of the ONLINE partition. - The first and last snapshot used extend their validity to 0 and +infinity - respectively. - -!===================== Det/DetCond v12r1 2008-07-16 ========================== -! 2008-07-10 - Marco Clemencic - - Fixed a tiny memory leak introduced in COOLConfSvc during the deSEALing. - -!===================== Det/DetCond v12r0 2008-06-30 ========================== -! 2008-07-02 - Marco Clemencic - - Introduced a work-around for COOL bug #38422, which was preventing the usage - of local tags as overlays. - - Removed a left-over in the requirements file needed for some tests. - (It was breaking compilation on win32) - -! 2008-06-27 - Marco Clemencic - - Introduced the ICondDBReader implementation CondDBTimeSwitch. - - it allows to use different partitions for different IOVs - - added a simple test for it (using a test algorithm added to the package: - DetCondTest::TestConditionAlg). - -! 2008-06-26 - Marco Clemencic - - Improved direct mapping between the COOL hierarchy and the transient store - one: - - direct mapping enabled by default (can be turned off via options to improve - the performances of CondDBLayeringSvc and CondDBDispatcherSvc) - - correct mapping in CondDBDispatcherSvc and CondDBLayeringSvc: - - CondDBDispatcherSvc: add entries implied by alternatives - - CondDBLayeringSvc: expose all the possible entries - - modified ICondDBReader (needed for a generic implementation of the mapping) - - added tests for foreseen use-cases - - the code to generate the XML catalog has been moved to a separate file to - be shared among the implementations of ICondDBReader - - Added dictionaries for few CORAL interfaces that are not available through - COOL. - -! 2008-06-24 - Marco Clemencic - - Fixed a bug in the direct mapping between the hierarchy of the COOL - database and the transient store one. - -! 2008-06-10 - Marco Clemencic - - Adapted to the new SEAL-less COOL and CORAL. Needs LCG_55 (Gaudi v20r0) - -!===================== Det/DetCond v11r11 2008-05-19 ========================= -! 2008-05-19 - Marco Clemencic - - Added the possibility of direct mapping between the hierarchy of the COOL - database and the transient store one. - Disabled by default, but needed to use the Online partition of the condition - database. - The implementation still lacks few features: - - does not work if the cache is not enabled - - it is implemented only at the CondDBAccessSvc (it should work at the - CondDBDispatcherSvc and CondDBLayeringSvc level too) - -!===================== Det/DetCond v11r10 2008-04-24 ========================= -! 2008-04-24 - Marco Clemencic - - Improved the algorithm to select the closest replica of the database when - using LFCReplicaSvc. The local site (preferred replica), can be specified, in - order of priority, with job option (of COOLConfSvc), the environment - variables DIRACSITE and LHCBPRODSITE or the hard-coded default "CERN.ch". The - value of local site can be any substring (case insensitive) to be matched in - the "host" field of the CORAL LFC entries. The fall-back servers are used in - random order. - -! 2008-04-22 - Marco Clemencic - - Fixed a problem in CondDBAccessSvc related to the usage of local tags. - -! 2008-04-09 - Marco Clemencic - - Modified default idle connection time-out in CondDBAccessSvc from 600s to - 120s. - -!===================== Det/DetCond v11r9 2008-03-03 ========================== -! 2008-03-03 - Marco Clemencic - - Added the function "useCondDBLogger" to DetCond.Configuration. - - Modified DetCond.Configuration to expose the configurables provided by the - package when imported. - -! 2008-02-29 - Marco Clemencic - - Added the Python module DetCond.Configuration to provide useful functions - for the configuration of the CondDB: - - addCondDBLayer - - addCondDBAlternative - -! 2008-02-22 - Marco Cattaneo - - Remove hacks in requirements no longer needed with Gaudi v19r7 - -! 2008-02-12 - Marco Clemencic - - Fixed a problem occurring when trying to retrieve a folder which is not in - the database (typical case for CondDBLayeringSvc), due to an uninitialized - variable. - -!===================== Det/DetCond v11r8 2008-01-28 ========================== - NEEDS: LCGCMT >= 54 -! 2008-01-26 - Marco Clemencic - - Added the service CondDBLogger (implementation of ICondDBReader) that, if put - between a user and a provider of the ICondDBReader interface, stores in a - file all the requests that were made to the CondDBReader, with the time of - the request. - The class allows to generate some history of the CondDB traffic to be able to - analyze and replay it afterward. - - Added the algorithm CondDBReplayAlg. It can read a file produced with - CondDBLogger to replay the requests to the database. - - Modified ICondDBReader and CondDBAccessSvc to allow the retrieval of objects - from the conditions database using the channel name (available since COOL - 2.3.0, LCGCMT 54). - -! 2008-01-21 - Marco Clemencic - - Improved error messages in case of CORAL exceptions. - -! 2007-12-20 - Marco Clemencic - - Allow to use tags that are not global in CondDBAccessSvc. - - Added a service (COOLConfSvc/ICOOLConfSvc) dedicated to the instantiation and - configuration of COOL/CORAL. The options to configure COOL and CORAL have - been moved from CondDBAccessSvc to the new service. - -! 2007-12-20 - Marco Cattaneo - - Replace homemade linkopts with new Boost_linkopts_filesystem_mt - - Remove slc3 specific set, no longer supported in LCG_54 - -!===================== Det/DetCond v11r7 2007-12-03 ========================== -! 2007-11-29 - Marco Clemencic - - Added two options to CondDBAccessSvc to control the retrial period and - retrial time-out of CORAL. - -!===================== Det/DetCond v11r6 2007-09-04 ========================== -! 2007-08-01 - Marco Clemencic - - Fixed a bug connected to "lazy connection" feature. I was using an instance - of a cool object to call a static member function. - -! 2007-07-31 - Marco Clemencic - - Fixed a bug with the "lazy connection" feature. The thread to disconnect from - the database was started even if we never connect. - Now it is started only at the first connection. - -!===================== Det/DetCond v11r5 2007-07-05 ========================== -! 2007-07-05 - Marco Clemencic - - Added the possibility to connect to the database only when needed (and made - it the default), so a job does not need the database does not need to be - able to connect to it or to be reconfigured. - To restore the old behavior (connection at initialize) use the option: - CondDBAccessSvc.LazyConnect = False; - -!===================== Det/DetCond v11r4 2007-06-15 ========================== - NEEDS: LCGCMT >= 52 -! 2007-06-06 - Marco Clemencic - - Removed the check on macro CORAL_1_8_x (use always the new CORAL feature). - -!===================== Det/DetCond v11r3 2007-05-16 ========================== - NEEDS: LHCbKernel >= v7r3 (ICondDBInfo) - LCGCMT >= 51 (if macro CORAL_1_8_x is set, - for CORAL 1.8.0) - -! 2007-05-16 - Marco Clemencic - - The parts that depend on CORAL 1.8.0 API are now enclosed in #ifdef/#endif - directives, so that DetCond can be compiled with the old version of CORAL. - -! 2007-05-11 - Marco Clemencic - - Extended ICondDBReader with the interface ICondDBInfo from LHCbKernel and - implemented the new function in all the ICondDBReader's (CondDBCnvSvc, - CondDBAccessSvc, CondDBLayeringSvc, CondDBDispatcherSvc). - NOTE: this introduce a dependency on LHCbKernel. - -! 2007-05-03 - Marco Clemencic - - Added service OnlineDBValidatorSvc to check if the Online CondDB replica - is recent enough. (see doxygen documentation) - -! 2007-05-02 - Marco Clemencic - - First implementation of the algorithm to sort DB replicas extracted from - LFC. - -!===================== Det/DetCond v11r2 2007-04-23 ========================== -! 2007-04-20 - Marco Clemencic - - Added ICondDBAccessSvc::connectionString() to be able to find the - connection string that was used without looking in the options. - - Use a static std::auto_ptr instead of a basic pointer and a counter of - instances (for CondDBAccessSvc::s_XMLstorageSpec). - - Added class CondDBSQLiteCopyAccSvc to copy an SQLite file and connect to - the copy. - -!===================== Det/DetCond v11r1 2007-03-22 ========================== -! 2007-03-22 - Marco Clemencic - - Small improvement to the database disconnect message. - -! 2007-03-16 - Marco Clemencic - - Added an option to enable CORAL LFCReplicaService (off by default). - - Added an option to enable CORAL automatic connection purge. - - Added a check on the database in CondDBAccessSvc::i_checkTag to avoid - segmentation possible faults. - - Disable some compiler optimizations in libstdc++ on slc3, because it seems - that on SLC3 there are problems with multithreaded applications. - -!===================== Det/DetCond v11r0 2007-03-05 ========================== - NEEDS LCGCMT >= 50 - -! 2007-03-05 - Marco Cattaneo - - Removed obsolete DetCond_load.cpp file - -! 2007-02-28 - Marco Clemencic - - Removed a work-around for missing library in LCG_Interfaces/COOL - -! 2007-02-22 - Marco Clemencic - - Fixed a bug (segfault) occurring when requiring the time-out task without - a connection (pure memory cache). - - Moved few message from DEBUG to INFO and added few more messages (like - the connection string and the tag used). - - Activated by default the disconnect on time-out feature (with time out set - to 10 min.) - -! 2007-02-19 - Marco Clemencic - - Minor change in RelyConverter.cpp (removed a useless line) - -! 2007-02-14 - Marco CLEMENCIC - - Updated to changes in COOL API - - Added to CondDBAccessSvc a function to clear the cache - -!================ Det/DetCond v10r0 2007-01-31 ============================= -! 2007-01-31 - Marco Cattaneo - - Fix and retag requirements to link on Windows. - -! 2006-12-06 - Florence RANJARD - - apply_pattern install_more_includes - - fixes for new plugins (P.Mato) - -!================= Det/DetCond v9r1 2006-09-04 ============================== -! 2006-09-04 - Marco Clemencic - - Modified the way of specifying one of the element of the condition. Now the - path to a condition in XML is: - - "conddb:/path/to/condition/[attribute@]Folder.xml[:channel][#Name]" - -! 2006-08-31 - Marco Clemencic - - Added the possibility of using one CondDB condition to store more than one - file using elements of the attribute list. - Backward compatible chages in the API (with deprecated functions). - -! 2006-08-31 - Marco Clemencic - - Added the possibility of disconnection from the DB after an inactivity - period defined by CondDBAvvessSvc.ConnectionTimeOut. - (The feature is implemented using Boost.Thread) - -! 2006-08-30 - Marco Clemencic - - Fixed a bug in CondDBDispatcherSvc: the correct alternative database was - never selected - - Fixed a bug in RelyConverter that was causing a segmentation fault if the - retreived XML string didn't start with "<?xml" (it is not a valid XML - string, but it does not justfy a segfault ;) - -!================= Det/DetCond v9r0 2006-07-18 ============================== -! 2006-07-18 - Marco CLEMENCIC - - Added to CondDBAccessSvc the possibility of chosing between read-only and - read-write connections to the database. (default is read-only) - -! 2006-07-17 - Marco CLEMENCIC - - Using Gaudi random generator service instad of the posix one in - CondDBAccessSvc (needed for recursive tagging) - -! 2006-07-14 - Marco CLEMENCIC - - Removed interface ICondDBCnvSvc. Now CondDBCnvSvc is an ICondDBReader and - the layering of databases is delegated to the class CondDBLayeringSvc. - - Removed the obsolete method ICondDBEditor::createFolder - -! 2006-07-12 - Marco CLEMENCIC - - Fixed a small bug in the code for the selection of the alternative in - CondDBDispatcherSvc. - -! 2006-07-11 - Marco CLEMENCIC - *** will be v9r0 *** - - Completely redesigned the support for alternative DBs: - - Reverted to previous implementation of CondDBAccessSvc - - Splitted ICondDBAccessSvc in 3: - 1) ICondDBReader: read only functions - 2) ICondDBEditor: write functions (storeXML, createNode, etc.) - 3) ICondDBAccessSvc: access function (setTag, etc.) - - Added the class CondDBDispatcherSvc as an implementation of ICondDBReader. - This one is selecting the appropriate alternative AccessSvc to use. - The alternative is declared with something like: - CondDBDispatcherSvc.Alternatives += { "/OnLine=CondDBAccessSvc/OnlineAccSvc" }; - The new functionality is not tested, but it is backward compatible even using - CondDBDispatcherSvc with only the default access service (CondDBAccessSvc). - - Dictionary updated to include the 2 new interfaces. - - Removed dependency on PCRE (not needed anymore) - - Documentation still to be updated. - -! 2006-07-07 - Marco CLEMENCIC - - Added the possibility of specifying alternative databases for certain - sub trees to a CondDBAccessSvc. - Now you have a default DB (backward compatible) and you can use a different - COOL DB for all the directories under e.g. "/OnLine", with an option like - CondDBAccessSvc.AlternativeDBs += { "/OnLine=<connectionString>" }; - Note: it still has to be tested, but it is backward compatible. - - Added dependency on PCRE (used to parse the string to specify alternative DB) - -! 2006-06-16 - Marco CLEMENCIC - - Removed some code used for debugging which is not needed. - - Added the possibility to wait that the requested tag appears - (configurable number of trials and time between trials) - -! 2006-06-12 - Marco CLEMENCIC - - Many API changes - - remamed ICondDBAccessSvc::createFolder to ICondDBAccessSvc::createNode - - removed the version of ICondDBAccessSvc::storeXMLString taking two doubles - because it was obsolete and confunding - - replaced ICondDBAccessSvc::tagFolder with the two functions - ICondDBAccessSvc::tagLeafNode and ICondDBAccessSvc::recursiveTag - (the first for Folders, the second for sub-trees) - - removed obsolete properties: HostName, User, Password, HidePassword, - Database, Schema, BackEnd - - property TAG renamed to DefaultTAG - - default value for property UseCache set to true (it was false) - - Enabled tagging functionalities (based on COOL HVS) - -!================= Det/DetCond v8r0 2006-04-25 ============================== -! 2006-04-25 - Marco Clemencic - **** requires LCGCMT_43 **** - - Updated to COOL_1_3_x - -! 2006-04-13 - Marco Clemencic - - Fixed a problem with uninitialized variables just affecting the case of - a FolderSet stored in the CondDB cache. - -!================= Det/DetCond v7r10p1 2006-03-29 ============================ -! 2006-03-29 - Marco Cattaneo - - Trivial fix in requirements for GCCXML+Boost on Windows with LCG_v42a - -!================= Det/DetCond v7r10 2006-03-22 ============================== -! 2006-03-22 - Marco Cattaneo - - Add DetCondDict (to remove dependency on DetCond in DetSys) - -!================= Det/DetCond v7r9 2006-02-03 =============================== -! 2006-02-01 - Marco Clemencic - - Updated to Gaudi v18r2 (use Gaudi::Time instead of ITime+TimePoint) - - Added Boost and SEAL to the dependencies because they are not inherited - from other packages anymore - -! 2006-01-25 - Nicolas Gilardi - - Allow to use a COOL connection string instead of the splitted credentials - - Modified Function CondDBAccessSvc::createFolder() to use large (16M) - strings by default in the CondDB folders. - -! 2006-01-22 - Marco Clemencic + Nicolas Gilardi - - Updated to improved COOL API. - -================= Det/DetCond v7r8 2006-01-20 ================================ -! 2006-01-20 - Marco Cattaneo - - Add use CORAL to requirements. N.B.: this is temporary, should be done - directly in COOL interface package - -! 2005-12-08 - Marco Clemencic - - Use GaudiUtils::HashMap in CondDBCache.h - -================= Det/DetCond v7r7 2005-11-04 ================================ -! 2005-10-18 - Marco Clemencic - - Cosmetic improvements - (RelyConverter, CondDBGenericCnv, CondDBAccessSvc, CondDBCnvSvc) - - Added `#include <vector>' in ICondDBAccessSvc.h and ICondDBCnvSvc.h - -! 2005-10-05 - Marco Clemencic - - Minimal update to follow API changes from COOL_1_1_0 to COOL_1_2_4 - -================= Det/DetCond v7r6 2005-09-19 ================================ -! 2005-09-18 - Marco Clemencic - - Allow direct mapping of the CondDB structure to the DetectorDataSvc tree - (no need to pass through an XML file/string with only catalogs) - - Use the 3rd string of the GenericAddress to store the origin of the XML - string (needed for self referencing XML string with DetDescCnv > v2r8) - -! 2005-08-31 - Marco Clemencic - - Implemented RelyConverter::updateObjRefs in order to re-initialize - correctly the updated conditions. - -! 2005-08-30 - Marco Clemencic - - Added support to cool::ChannelId (needs DetDescCnv > v2r8) - - Fixed a bug in CondDBCache - (the search of conflicts in the IOVs worked only in a well defined case, - the one tested!) - -================= Det/DetCond v7r5 2005-07-21 ================================ -! 2005-07-21 - Marco Clemencic - - Apply always tag NEEDS_COOL_FACTORY (is needed by Windows and Python) - -! 2005-07-11 - Marco Clemencic - - Removed unused pointers from CondDBCnvSvc - -! 2005-07-07 - Marco Cattaneo - - Fix a doxygen warning - -! 2005-07-07 - Marco Clemencic - - Abstract interfaces moved to DetDesc (to allow python bindings) - - Added CondDBAccessSvc::dumpCache(), it prints (level=DEBUG) the content - of the cache. - -! 2005-06-30 - Marco Clemencic - - Added RelyConverter::fillObjectRefs (was missing, but needed for - initialization of objects) - -================= Det/DetCond v7r4 2005-06-23 ================================ -! 2005-06-23 - Marco Clemencic - - Added the possibility of having an in-memory copy of the CondDB. - -! 2005-06-14 - Marco Clemencic - - Renamed ConditionsDBCnvSvc to CondDBCnvSvc and added the interface - ICondDBCnvSvc - -================= Det/DetCond v7r3 2005-06-14 ================================ -! 2005-06-14 - Marco Cattaneo - - Move ConditionsDbCnvSvc and RelyConverter to component library. - -! 2005-06-14 - Marco Clemencic - - CondDBAccessSvc does not complain anymore if the user is not specified - (adapted to POOL XML authentication service, COOL > 1.1.0) - -! 2005-06-08 - Marco Clemencic - - Changed from "component library" to "component + link library" - -================= Det/DetCond v7r2 =========================================== -! 2005-05-27 - Marco Clemencic - - fixed compilation issue for Windows - -! 2005-05-25 - Marco Clemencic - - Adapted to COOL 1.1.0 (LCG_35) - -================= Det/DetCond v7r1 =========================================== -! 2005-05-12 - Marco Clemencic - - Fixed the compilation on WIN32 - - Added support to multiple databases through option - ConditionsDBCnvSvc.CondDBAccessServices - -================= Det/DetCond v7r0 =========================================== -! 2005-04-25 - Marco CLEMENCIC - - Upgrade to COOL_1_0_0 (first production release) - - Works with LHCb v18r3 - -================= Det/DetCond v6r1 =========================================== -! 2005-04-22 - Marco CLEMENCIC - - Upgrade to COOL_0_1_0-pre2 - - Support for tagging - - almost all the technicalities (POOL/COOL) moved to CondDBAccessSvc - - some clean up - - commit before the first production release - -============================================================================== -! 2005-02-09 - Marco CLEMENCIC - - Upgrade to first public preliminary version of COOL (COOL_0_0_3-pre1) - - Renamed XMLRelyCnv to RelyConverter (it can use, in principle, any - conversion service). - - Moved CondDBGenericCnv to the public interface in order to allow public - usage of RelyConverter. - -============================================================================== -! 2005-01-27 - Marco CLEMENCIC - - Upgrade to first preliminary version of the Conditions Database API: - COOL_0_0_1 - -============================================================================== -! 2004-12-08 - Marco Clemencic - - Upgrade to latest stable version of CondDB (CONDDB_0_2_0) and fixed for the -changes in Gaudi/LHCb - - Moved and modified part of the ConditionsDBCnvSvc to a dedicated converter -(XmlRelyCnv) + a generic CondDB converter to put common Converter functions in -one place - - Implemented the possibility to use a fall back Converter (the one relying on -DetectorPersistencySvc) if no dedicated converter is found. -Requirements v5r0 - -============================================================================== -!20030131 - Andrea Valassi -Upgrade to DetDesc v11r8. -Only change is in recommended CMTPATH. -- DetDesc is included in LHCB_v11r5 for all of rh61dbx, rh73dbx and Windows -- This makes it easier to distribute as DetDesc does not need to be recompiled -Requirements v4r3, private tag h20030131 - -============================================================================== -!20021203 - Andrea Valassi -Include the MySQL implementation for both RH73 and WIN32 -- DetCond on RH73/WIN32 now depends on both Oracle and MySQL implementations - > multiple "use..." in the requirements - > if the "use..." statement is removed, some code is #ifndef'd away - (as the base packages propagate to DetCond the relevant cppflags) - > to make the code more readable, implementation-specific init() and - i_buildCondDBInfo() have been introduced (#ifdef'd in only if necessary!) - > I assume RH61 is always Objy only -- Implementation is read at runtime from the job options - > ConditionsDBGate.condDBImpl = one of CondDBObjy, CondDBOracle, CondDBMySQL -- Remove CondDBKey.h from DetCond (I forgot to remove it on h20020301!) -Requirements v4r2, private tag h20021203 - -============================================================================== -!20021125 - Andrea Valassi -Upgrade to CondDBOracle v4r16, Gaudi v11r2 and DetDesc v11r2. -Upgrade to RedHat73 on lxplus7. -- no major change to DetCond code - > disable WIN32 compilation warning 4786 in ConditionsDBGate.cpp - > print out ORA_NLS33 and NLS_LANG to keep track of their values -- dependency on Det/CondDBOracle changed from v4r15 to v4r16 (RH7,WIN) -- dependency on Gaudi changed to v13r* (tested with v13r2) -- dependency on GaudiSvc changed to v10r* (tested with v10r1) -- dependency on Det/DetDesc changed to v11r* (tested with v11r2) -Modify CMT requirements to allow for runtime choice between Oracle and MySQL. -- precompiler directives are inherited from CondDB package(s) -- dependency on CONDDB (using Objectivity) changed to v3r02p3 (RH6) -Requirements v4r1, private tag h20021125 - -============================================================================== -!20020725 - Andrea Valassi -Upgrade to CondDBOracle v4r15 and Gaudi v10r4. -- no change to DetCond code -- dependency on Det/CondDBOracle changed from v3r10p1 to v4r15 (RH7,WIN) -- dependency on CONDDB (using Objectivity) remains v3r02p2 (RH6) -- dependency on Gaudi tested with GaudiKernel v12r3 and GaudiSvc v8r3 -- dependency on Det/DetDesc (v10r*) tested with v10r3 -Requirements v4r0, private tag h20020725 - -============================================================================== -!20020417 - Andrea Valassi -Upgrade to Gaudi v10 -- use RedHat7.2 tag rh72_gcc2952 (not rh72_gcc29521), defined in GaudiPolicy -- dependency on Det/CondDBOracle changed from v3r10 to v3r10p1 -- dependency on CONDDB changed from v3r02p1 to v3r02p2 (bug fix) -- adapt to new version of MsgStream.h in GaudiKernel for longlong printout -- dependency on Det/DetDesc changed from v9r* to v10r* -Requirements v3r0, private tag h20020417 - -============================================================================== -!20020405 - Andrea Valassi -Minor modifications to requirements -- dependency on CONDDB changed from v3r02 to v3r02p1 -- env. variable CONDDB_implementation is defined in CONDDB or Det/CondDBOracle -Requirements v2r1, private tag h20020405 - -============================================================================== -!20020328 - Andrea Valassi -First Oracle implementation ported to Linux (RedHat 7.2 only) -See doc/README.RedHat72 in Ex/DetCondExample for more details -Corresponds to Emil's first official release of ConditionsDB (0.3.1.0) -- change WIN32 dependency on Det/CondDBOracle package to version v3r10 -- add rh72_gcc29521 dependency on Det/CondDBOracle v3r10 -- keep rh61_gcc29521 dependency on CONDDB v3r02 -Requirements v2r1, private tag h20020328. - -============================================================================== -!20020308 - Andrea Valassi -Change dependency on CondDBOracle package to version v2r10 (0.2.1.0). -Requirements v2r1, private tag h20020308. - -============================================================================== -!20020301 - Andrea Valassi -First version supported on Windows using an Oracle implementation of CondDB. -- Platform-specific support - > remove CondDBKey.h from DetCond: use that from the ConditionsDB package - > interchange the contents of DetCond_dll and DetCond_load - > remove #ifdef's with dummy failure codes for non-Linux platforms -- Support of Oracle (needed also to suppport Oracle under Linux) - > implementation specified in the requirements is propagated via #ifdef's - > new init string for the Oracle database including host, user and password - > CondDBOracleMgrFactory or CondDBObjyDBMgrFactory called in either case -Requirements v2r1, private tag h20020301. - -============================================================================== -!20020110 - Flr - requirements - apply packageShr instead of ld_library_path pattern because - it is a component library. - do not apply package_Lshlibflags, there is no linker library. - -!20011220 - Andrea Valassi -Simplify dependencies on the Gaudi framework. - -============================================================================== -!20011216 - Andrea Valassi -Major changes due to tighter coordination with DetDesc and XmlDDDB packages. -- Update cannot be delegated to XmlCnvSvc until major changes in DetDes - > code creating and interpreting DOM trees in each Xml converter should be - executed also in updateObj(): to avoid duplicating code, a solution is - to move it from createObj() to updateObj() or better updateObjRefs(), - which should be called internally from createObj() - > my (temporary?) solution is to create a new object using the address, and - deep copy part of it into the old one by a Condition::update(Condition&) - method to deep copy only those properties of a DataObject that refer - to a Condition (eg validity and parameters); the registry, address, - reference counts and other DataObject properties should not be deep - copied instead (hence an overloaded operator= is not introduced) - > update of DataObjects is only possible for Conditions (and derived classes) - because this method exists only for Conditions - > this is the only reason to have a dependency on DetDesc - > however, DataObjects not implementing IValidity are now assumed valid - (previously, an error was returned when updating them) -- Changes in folder description - > classID are removed from all XML refs: remove it from folder description - > assume that secondary storage type is always read from folder description -- Remove ConditionsDBAddress (a GenericAddress of type CONDDB is enough) - > par[0] is still the COndDB folder name - > the tag name is not anymore in the CONDDB address - > par[1] is now the name of the element (e.g. the name of an XML element) - > the string storage type is not in the CONDDB address - (it is now assumed that it is always read from the folder description) - > ipar{0,1] are not used anymore -- Registry entry (can be 0) is used in creating and updating Conditions - > for instance: this is needed for catalog conversion - > it is set in the secondary temporary address (e.g. an XML catalog address) -- Minor changes in messaging: use VERBOSE tag for verbose comments -- Overload methods for writing representations in ConditionsDBCnvSvc - > they must be overloaded because this CnvSvc has no converters - > they are empty for the moment (not yet implemented) -- Upgrade to CMT v1r10: remove scripts and hacks needed to cure a bug in CMT -Requirements v2r0, private tag h20011216. - -============================================================================== -!20011130 - Andrea Valassi -Modified version of DetDataSvc in GaudiSvc committed to CVS -- Contains main features of ConditionDataSvc and ConditionsDBDataSvc -- Remove ConditionDataSvc and ConditionsDBDataSvc from this package - -============================================================================== -!20011129 - Andrea Valassi -- Remove the IConditionsDBDataSvc special interface - > ConditionsDBDataSvc now does little more than ConditionDataSvc -- Implement a dummy IIncidentListener interface in ConditionDataSvc -- Redefine ConditionsDBAddress_undefinedClassID = CLID_NULL (it will disappear) - -============================================================================== -!20011128 - Andrea Valassi -Move the global tag from the ConditionsDBDataSvc to the ConditionsDBCnvSvc -- Use IAddressCreator interface of CnvSvc to create addresses with global tag - > "DEFAULT" becomes a reserved word to indicate the global tag -- Remove method setGlobalTag (the tag can only be set in the job options) - -============================================================================== -!20011127 - Andrea Valassi -A few more changes before including my detector data service in GaudiSvc -- The event time is not passed in an address from the DataSvc to the CnvSvc - > remove IConditionAddress - > ConditionsDBCnvSvc now reads the event time from the DetDataSvc - > ConditionDataSvc::updateObject now just checks validity before delegating -- Move interface IDetDataSvc (formerly IConditionDataSvc) to GaudiKernel - > needed to retrieve the event time within the ConditionsDBCnvSvc - > the setEventTime method is temporary (eventually: use the IncidentService) -- Store ConditionsDBAddress private data as GenericAddress private data - -============================================================================== -!20011126 - Andrea Valassi -A few changes before including my data service in GaudiSvc. -- Move ConditionData from DetCond/src/Lib to DetCondExample - > only DataObjects are manipulated, with dynamic casts to IValidity - > no Lib anymore in DetCond/src -- Manipulate ITime and TimePoint objects rather than ITime pointers - > add bool method to check if the event time is defined in ConditionDataSvc - -============================================================================== -!20011123 - Andrea Valassi -Upgrade to Gaudi v9 -- Addresses now inherit from GenericAddress (which has been simplified a lot) -- There are no address factories any more -- Adapt to changes in RegistryEntry (which now implements IRegistry) -- Add dummy methods fillObjRefs and updateObjRefs in ConditionsDBCnvSvc -- Notify (by flag "true") ServiceLocator to create services not existing yet -Requirements v2, private tag h20011123. - -============================================================================== -!20010914 - Andrea Valassi -New package. -Requirements v1, private tag v1. - diff --git a/Det/DetCond/options/UseOracle.py b/Det/DetCond/options/UseOracle.py deleted file mode 100644 index 142aec20d..000000000 --- a/Det/DetCond/options/UseOracle.py +++ /dev/null @@ -1,3 +0,0 @@ -# Additional options for accessing Oracle conditions DB. -from Configurables import CondDB -CondDB(UseOracle = True) diff --git a/Det/DetCond/python/DetCond/Configuration.py b/Det/DetCond/python/DetCond/Configuration.py deleted file mode 100755 index 038fa6b7e..000000000 --- a/Det/DetCond/python/DetCond/Configuration.py +++ /dev/null @@ -1,788 +0,0 @@ -""" -High level configuration tools for Conditions Database. -""" -__author__ = "Marco Clemencic <Marco.Clemencic@cern.ch>" - -from Gaudi.Configuration import allConfigurables, ConfigurableUser, importOptions, getConfigurable, log -from Configurables import ( CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBCnvSvc, - CondDBSQLiteCopyAccSvc, - CondDBLogger, - COOLConfSvc, - ApplicationMgr ) - -import os, re -from os.path import exists, join - -class CondDB(ConfigurableUser): - """ - Configurable user to allow high-level configuration of the access to the - conditions database. - """ - __slots__ = { "Tags" : {}, - "Simulation" : False, - "Upgrade" : False, - "UseOracle" : False, - "LocalTags" : {}, - "LogFile" : "", - "Overrides" : [], - "PartitionConnectionString": {}, - "SQLiteLocalCopiesDir": "", - "OverwriteSQLiteLocalCopy": False, - "DisableLFC" : False, - "Online" : False, - "IgnoreHeartBeat": False, - "HeartBeatCondition" : "/Conditions/Online/LHCb/Tick", - "EnableRunStampCheck": False, - "RunStampCondition": "", - "LatestGlobalTagByDataType" : "", - "LatestGlobalTagByDataTypes" : [], - "LatestLocalTagsByDataType": [], - "AllLocalTagsByDataType": [], - "UseLatestTags" : [], - "QueryGranularity" : 0, - "UseDBSnapshot" : False , - "DBSnapshotDirectory" : "/group/online/hlt/conditions" , - 'EnableRunChangeHandler' : False, - 'RunChangeHandlerConditions' : { 'online_%d.xml' : [ "Conditions/Online/LHCb/Magnet/Set" - , "Conditions/Online/Velo/MotionSystem" - , "Conditions/Online/LHCb/Lumi/LumiSettings" - , "Conditions/Online/LHCb/LHCFillingScheme" - , "Conditions/Online/LHCb/RunParameters" - , "Conditions/Online/Rich1/R1HltGasParameters" - , "Conditions/Online/Rich2/R2HltGasParameters" ] }, - 'LoadCALIBDB' : "OFFLINE" - } - _propertyDocDct = { - 'Tags' : """ Dictionary of tags (partition:tag) to use for the COOL databases """, - 'Simulation' : """ Boolean flag to select the simulation or real-data configuration """, - 'Upgrade' : """ Boolean flag to select the Upgrade simulation configuration """, - 'UseOracle' : """ Boolean flag to enable the usage of the CondDB from Oracle servers. NB: Obsolete as Oracle support is now dropped""", - 'LocalTags' : """ Dictionary with local tags to use to override the global ones (partition: list of local tags) """, - 'LogFile' : """ Record the requests to the database the specified file """, - 'Overrides' : """ Internal property used to add layers or alternatives """, - 'PartitionConnectionString' : """ Dictionary with alternative connection strings for the CondDB partitions """, - 'SQLiteLocalCopiesDir' : """ The directory where to copy the SQLite files before accessing them """, - 'OverwriteSQLiteLocalCopy' : """ When using SQLite local copies, overwrite existing files """, - 'DisableLFC' : """ Do not use LFC lookup even if we are connecting to Oracle """, - 'Online' : """ Flag to activate configuration options specific for the Online environment """, - 'IgnoreHeartBeat' : """ Do not set the HeartBeatCondition for the Online partition """, - 'HeartBeatCondition' : """ Location of the heart-beat condition in the database """, - 'EnableRunStampCheck': """ Enable the check for the special RunStamp condition """, - 'RunStampCondition': """ Path (in the CondDB) to the special RunsTamp condition. """, - 'LatestGlobalTagByDataType' : """ Use latest CondDB global tag marked with the data type""", - 'LatestGlobalTagByDataTypes' : """ Use latest CondDB global tag marked with the data type, will override LatestGlobalTagByDataType if set""", - 'LatestLocalTagsByDataType' : """ Use all latest CondDB local tags marked with the data type """, - 'AllLocalTagsByDataType' : """ Use all CondDB local tags marked with the data type """, - 'UseLatestTags' : """ List of the form [DataType, OnlyGlobalTags = False] to turn on the usage of the latest tags """, - 'QueryGranularity': """Granularity of the query in the database (in time units)""", - 'LoadCALIBDB': """ Load CALIB*.db file as additional layers on top of ONLINE-*.db file, could be either "HLT1" (w/o layering, ONLINE only), or "OFFLINE" (Layer CALIBOFF above CALIB & ONLINE ), Do not set it for the Online environment""", - } - LAYER = 0 - ALTERNATIVE = 1 - # List of known implementations of ICondDBReader (str is used for backward compatibility) - __CondDBReaders__ = [ CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc, - str ] - - def _checkOverrideArgs(self, accessSvc, connStr, dbFile, dbName): - """ - Check if the accessSvc is a valid CondDBReader or build one using the - other arguments. - """ - kwargs = { "accessSvc": accessSvc, "connStr": connStr, "dbFile": dbFile, "dbName": dbName } - if accessSvc is None: - if not connStr: - if dbFile: - if not dbName: - dbName = os.path.basename(dbFile) - m = re.match(r'([A-Z][A-Z0-9_]{0,7})(_\w+)?.db', dbName) - if m: - dbName = m.group(1) - else: - raise ValueError('invalid arguments %r' % kwargs) - connStr = "sqlite_file:%s/%s" % (dbFile, dbName) - else: - raise ValueError('invalid arguments %r' % kwargs) - name = dbName - else: - name = connStr.rsplit('/')[-1] - if not re.match(r'[A-Z][A-Z0-9_]{0,7}', name): - name = 'CondDBAccessSvc' - # make a unique name for the configurable - name = "automatic_" + name - name_format = name + '_%d' - i = 0 - while name in allConfigurables: - i += 1 - name = name_format % i - accessSvc = CondDBAccessSvc(name, ConnectionString = connStr) - elif type(accessSvc) not in __CondDBReaders__: # Check for supported types - raise TypeError("'%s' not supported as CondDBReader"%accessSvc.__class__.__name__) - return accessSvc - - def addLayer(self, accessSvc = None, connStr = None, dbFile = None, dbName = None): - """ - Add the given CondDBReader as a layer on top of the existing configuration. - - Example: - CondDB().addLayer(myDB) - """ - # Check the arguments and/or prepare a valid access svc - accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) - self.Overrides.append((self.LAYER, accessSvc)) - def _addLayer(self, accessSvc): - cnvSvc = allConfigurables["CondDBCnvSvc"] - - originalReader = cnvSvc.CondDBReader - if type(originalReader) == CondDBLayeringSvc: - # If the original reader is already a layering svc, we can extend the - # configuration. - originalReader.Layers.insert(0,accessSvc) - else: - # We have to create a new layering svc. - name = "CondDBLayeringSvc" - i = 0 - while name in allConfigurables: - i += 1 - name = "CondDBLayeringSvc_%d"%i - cnvSvc.CondDBReader = CondDBLayeringSvc(name, - Layers = [accessSvc, - originalReader]) - - def addAlternative(self, accessSvc = None, path = None, connStr = None, dbFile = None, dbName = None): - """ - Add the given CondDBReader as an alternative to the existing configuration - for the specified path. - - Example: - CondDB().addAlternative(myDB,"/Conditions/MyDetector/Alignment") - """ - if path is None: - raise ValueError("'path' must be specified") - # Check the arguments and/or prepare a valid access svc - accessSvc = self._checkOverrideArgs(accessSvc, connStr, dbFile, dbName) - self.Overrides.append((self.ALTERNATIVE, accessSvc, path)) - - def _addAlternative(self, accessSvc, path): - cnvSvc = allConfigurables["CondDBCnvSvc"] - - originalReader = cnvSvc.CondDBReader - if type(originalReader) == CondDBDispatcherSvc: - # If the original reader is already a dispatcher, we can extend the - # configuration: - originalReader.Alternatives[path] = accessSvc - else: - # We have to create a new dispatcher - name = "CondDBDispatcherSvc" - i = 0 - while name in allConfigurables: - i += 1 - name = "CondDBDispatcherSvc_%d"%i - cnvSvc.CondDBReader = CondDBDispatcherSvc(name, - MainAccessSvc = originalReader, - Alternatives = { path: accessSvc } - ) - - def useLatestTags(self, DataType, OnlyGlobalTags = False): - self.UseLatestTags = [DataType, OnlyGlobalTags] - - def _useLatestTags(self, DataTypes, OnlyGlobalTags = False, OnlyLocalTags = False): - """ - Configure the conditions database to use the latest local tags on top of the latest global tag for a given data type. - """ - # Check arguments - if type(DataTypes) is not list: - DataTypes = [DataTypes] - - # Check if the latest tags should be set for simulation or not - if not self.getProp("Simulation"): - partitions = ["DDDB", "LHCBCOND", "DQFLAGS"] - if os.environ['LoadCALIBDB'] is "OFFLINE": - partitions += ["CALIBOFF"] - else: - partitions = ["DDDB", "SIMCOND"] - - # Set the latest tags - from CondDBUI.Admin.TagsFilter import last_gt_lts - rel_notes = None - if self.getProp('Upgrade'): - rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') - - for partition in partitions: - gt, lts = None, [] - for dt in DataTypes: - tags = last_gt_lts(partition, dt, rel_notes) - if not tags: - # Allowing absence of valid tags for DQFLAGS - if partition == 'DQFLAGS': continue - # Allowing absence of valid tags for CALIBOFF before 2015 - elif partition == 'CALIBOFF' and dt.isdigit() and int(dt)<2015: continue - else: - raise RuntimeError("Cannot find tags for partition '%s'," - " data type '%s'" % (partition, dt)) - if not gt: - gt = tags[0] - lts += tags[1] - - if not OnlyLocalTags and gt: # Only for partitions with available global tags - self.Tags[partition] = gt - if not OnlyGlobalTags and lts: - if partition in self.LocalTags: self.LocalTags[partition] += lts - else: self.LocalTags[partition] = lts - - def _useAllLocalTags(self, DataTypes): - """ - Configure the conditions database to use all local tags for a given data type. - """ - - # Check arguments - if type(DataTypes) is not list: - DataTypes = [DataTypes] - - # Check if the latest tags should be set for simulation or not - if not self.getProp("Simulation"): - partitions = ["DDDB", "LHCBCOND"] - if os.environ['LoadCALIBDB'] is "OFFLINE": - partitions += ["CALIBOFF"] - else: - partitions = ["DDDB", "SIMCOND"] - - # Set the latest tags - from CondDBUI.Admin.TagsFilter import all_lts - rel_notes = None - if self.getProp('Upgrade'): - rel_notes = os.path.join(os.environ['SQLITEUPGRADEDBPATH'], '..', 'doc', 'release_notes.xml') - - for partition in partitions: - local_tags = [] - for dt in DataTypes: - lts = all_lts(partition, dt, rel_notes) - if lts: local_tags += lts - if partition in self.LocalTags: self.LocalTags[partition] += local_tags - else: self.LocalTags[partition] = local_tags - - def __make_sqlite_local_copy__(self, accsvc, local_dir = None, force_copy = None): - if isinstance(accsvc, str): - # convert the string in an actual configurable instance - # This is both for backward compatibility and CondDBTimeSwitchSvc - if "/" in accsvc: - tp, name = accsvc.split("/",1) - else: - tp = name = accsvc - accsvc = getConfigurable(name, tp) - if local_dir is None: - local_dir = self.getProp("SQLiteLocalCopiesDir") - if force_copy is None: - force_copy = self.getProp("OverwriteSQLiteLocalCopy") - # If the directory for the local copies is not specified, we do nothing - if not local_dir: - return accsvc - # Check if we are using Oracle or SQLite -# if self.getProp("UseOracle"): -# log.warning("Conflicting properties in CondDB Configurable: " -# "ignoring SQLiteLocalCopiesDir because UseOracle is set to True") -# return accsvc - # Modify partitions to use local copies of the DBs - newaccsvc = accsvc # fallback return value (no change) - if isinstance(accsvc, CondDBAccessSvc): - # replace the reader with another - m = re.match(r"^sqlite_file:(.*)/([_0-9A-Z]{1,8})$", - accsvc.getProp("ConnectionString")) - if not m: # not SQLite connection string - return accsvc - newaccsvc = CondDBSQLiteCopyAccSvc(accsvc.name() + "_local") - newaccsvc.OriginalFile = m.group(1) - newaccsvc.DestinationFile = os.path.join(local_dir, - os.path.basename(m.group(1))) - newaccsvc.DBName = m.group(2) - newaccsvc.ForceCopy = force_copy - newaccsvc.IgnoreCopyError = not force_copy # ignore copy errors if we do not overwrite (needed for local tags) - if hasattr(accsvc, "CacheHighLevel"): - newaccsvc.CacheHighLevel = accsvc.CacheHighLevel - elif isinstance(accsvc, CondDBDispatcherSvc): - # use the same dispatcher replacing its content - mainAccSvc = accsvc.getProp("MainAccessSvc") - accsvc.MainAccessSvc = self.__make_sqlite_local_copy__(mainAccSvc, local_dir) - alternatives = accsvc.getProp("Alternatives") - for alt in alternatives.keys(): - accsvc.Alternatives[alt] = \ - self.__make_sqlite_local_copy__(alternatives[alt], local_dir) - elif isinstance(accsvc, CondDBLayeringSvc): - # use the same layering service replacing its content - new_layers = [] - for layer in accsvc.getProp("Layers"): - new_layers.append(self.__make_sqlite_local_copy__(layer, local_dir)) - accsvc.Layers = new_layers - elif isinstance(accsvc, CondDBTimeSwitchSvc): - # use the same time switcher replacing its content, - # but we need to parse its options (in format "'%s':(%d,%d)") - readers_list = accsvc.getProp("Readers") - new_readers = [] - for line in readers_list: - # Parse the line for the reader (it looks like "'name':(0,1)") - r, iov = map(eval, line.rsplit(":")) - new_reader = self.__make_sqlite_local_copy__(r, local_dir) - new_readers.append("'%s':(%d,%d)" % - (new_reader.getFullName(), iov[0], iov[1])) - accsvc.Readers = new_readers - elif isinstance(accsvc, CondDBLogger): - # use the same logger replacing its content - logged = accsvc.getProp("LoggedReader") - accsvc.LoggedReader = self.__make_sqlite_local_copy__(logged, local_dir) - elif isinstance(accsvc, CondDBCnvSvc): - # use the same conversion service replacing its content - reader = accsvc.getProp("CondDBReader") - accsvc.CondDBReader = self.__make_sqlite_local_copy__(reader, local_dir) - return newaccsvc - - def _configureDBSnapshot(self): - - baseloc = self.getProp( "DBSnapshotDirectory" ) - self.DisableLFC = True - - # Set alternative connection strings and tags - # if simulation is False, we use DDDB, LHCBCOND and ONLINE - # True DDDB, SIMCOND - # (see Det/DetCond's configurable... ) - dbPartitions = { False : [ "DDDB", "LHCBCOND", "ONLINE" ] - , True : [ "DDDB", "SIMCOND" ] - } - - tag = self.getProp("Tags") - for part in dbPartitions[ self.getProp('Simulation') ] : - if tag[part] is 'default' : raise KeyError('must specify an explicit %s tag'%part) - self.PartitionConnectionString[part] = "sqlite_file:%(dir)s/%(part)s_%(tag)s.db/%(part)s" % {"dir": baseloc, - "part": part, - "tag": tag[part]} - self.Tags[part] = tag[part] - - # Set the location of the Online run-by-run conditions - if self.getProp('EnableRunChangeHandler') : - from Configurables import RunChangeHandlerSvc - rch = RunChangeHandlerSvc() - rch.Conditions = dict( (c,'/'.join([baseloc,f])) for f,cs in self.getProp("RunChangeHandlerConditions").iteritems() for c in cs ) - ApplicationMgr().ExtSvc.append(rch) - - def __apply_configuration__(self): - """ - Converts the high-level information passed as properties into low-level configuration. - """ - # special case for online - if self.getProp('UseDBSnapshot') : self._configureDBSnapshot() - - # In the Online/Upgrade/Simulation environment, LoadCALIBDB should be defaulted to HLT1 - if self.getProp("Online") or self.getProp('Upgrade') or self.getProp('Simulation'): - self._properties["LoadCALIBDB"].setDefault("HLT1") - # Set up environment variables for loading CALIBOFF layers, must be before loading any tags - LoadCALIBDB = self.getProp('LoadCALIBDB') - loadcaliboptions = ["HLT1", "OFFLINE"] - if LoadCALIBDB not in loadcaliboptions: - raise ValueError("'%s' is not a valid LoadCALIBDB value. Allowed: %s" %(LoadCALIBDB, loadcaliboptions)) - if LoadCALIBDB is "OFFLINE" and not exists(join(os.environ["SQLITEDBPATH"], "CALIBOFF.db")): - LoadCALIBDB = "HLT1" # When CALIBOFF.db is not there, reset the option - os.environ['LoadCALIBDB'] = LoadCALIBDB - - # Set the usage of the latest global/local tags - old_latest_Tags_prop = self.getProp("UseLatestTags") # it is deprecated - latest_GTags_prop = self.getProp("LatestGlobalTagByDataTypes") - if not latest_GTags_prop: # if property not set - latest_GTags_prop = self.getProp("LatestGlobalTagByDataType") - latest_LTags_prop = self.getProp("LatestLocalTagsByDataType") - all_LTags_prop = self.getProp("AllLocalTagsByDataType") - - if old_latest_Tags_prop: - if latest_GTags_prop or latest_LTags_prop: - log.warning("The property 'UseLatestTags' is deprecated:" - "'LatestGlobalTagByDataType(s)' and 'LatestLocalTagsByDataType'" - " will be used instead.") - else: - latest_GTags_prop = old_latest_Tags_prop[0] - if type(old_latest_Tags_prop[-1]) != bool or \ - (type(old_latest_Tags_prop[-1]) == bool and not old_latest_Tags_prop[1]): - latest_LTags_prop = old_latest_Tags_prop[0] - - if latest_GTags_prop: - datatype = latest_GTags_prop - if self.getProp("Tags"): - self.Tags = {} - self._useLatestTags(datatype, OnlyGlobalTags = True) - log.warning("Default global tags will be overridden with the latest ones" - " available for '%s' data type: %s"%(datatype, self.getProp("Tags")) ) - - if latest_LTags_prop: - datatypes = latest_LTags_prop - #if self.getProp("LocalTags"): - # self.LocalTags = {} - self._useLatestTags(datatypes, OnlyLocalTags = True) - log.warning("Latest unbound local tags on top of the latest global tags" - " of %s data type(s) are added: %s" - %(datatypes, self.getProp("LocalTags"))) - - if all_LTags_prop: - datatypes = all_LTags_prop - self._useAllLocalTags(datatypes) - log.warning("ALL local tags of %s data type(s) are added: %s" - %(datatypes, self.getProp("LocalTags"))) - - # Import SQLDDDB specific info - if self.getProp("UseOracle"): - CondDBAccessSvc("ONLINE", ConnectionString = "CondDBOnline/ONLINE") - if self.getProp("DisableLFC"): - COOLConfSvc(UseLFCReplicaSvc = False) - elif self.getProp('UseDBSnapshot'): - CondDBAccessSvc("ONLINE") - else: - configureOnlineSnapshots() -# importOptions("$SQLDDDBROOT/options/SQLDDDB.py") - - ######################################################################### - # Access to ConditionsDB - ########################################################################## - conns = self.getProp("PartitionConnectionString") - tags = self.getProp("Tags") - # DB partitions - partition = {} - parttypes = [ ("DDDB", CondDBAccessSvc), - ("LHCBCOND", CondDBAccessSvc), - ("ONLINE", CondDBTimeSwitchSvc), - ("SIMCOND", CondDBAccessSvc), - ("DQFLAGS", CondDBAccessSvc)] - if LoadCALIBDB is "OFFLINE": - # CALIBOFF not needed for the upgrade - parttypes += [("CALIBOFF", CondDBAccessSvc)] - - for (p ,t) in parttypes: - partition[p] = getAnyDBReader(p, t) - # Override connection strings: - if p in conns: - if type(partition[p]) is CondDBAccessSvc: - partition[p].ConnectionString = conns[p] - del conns[p] - - # Override connection strings for Upgrade case - if self.getProp('Simulation') and self.getProp('Upgrade') and type(partition[p]) is CondDBAccessSvc: - partition[p].ConnectionString = os.path.join('sqlite_file:$SQLITEUPGRADEDBPATH', p + '.db', p) - # Override tags - if p in tags and p != "ONLINE": - partition[p].DefaultTAG = tags[p] - del tags[p] - # Set the query granularity - if p != "CALIBOFF": self.propagateProperty("QueryGranularity", partition[p]) - if type(partition[p]) is CondDBTimeSwitchSvc: # also online - for r in partition[p].Readers: - config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] - if isinstance(config, CondDBAccessSvc): - self.propagateProperty("QueryGranularity", config) - # Pass along the configuration for the layered DBs - elif isinstance(config, CondDBLayeringSvc): - for ly in config.Layers: - if isinstance(ly, CondDBAccessSvc): - self.propagateProperty("QueryGranularity", ly) - - if conns: - log.warning("Cannot override the connection strings of the partitions %r", conns.keys()) - if tags and tags.keys()!=['ONLINE']: - log.warning("Cannot set the tag for partitions %r", tags.keys()) - - # In the Online environment, IgnoreHeartBeat should be defaulted to True - if self.getProp("Online"): - self._properties["IgnoreHeartBeat"].setDefault(True) - if not self.getProp("IgnoreHeartBeat"): - if isinstance(partition["ONLINE"], CondDBAccessSvc): - self.propagateProperty("HeartBeatCondition", partition["ONLINE"]) - elif isinstance(partition["ONLINE"], CondDBTimeSwitchSvc): - # Add the heart beat conditions to the latest snapshot only since the - # others are limited but valid by construction. - if partition["ONLINE"].Readers: - latest = partition["ONLINE"].Readers[-1] - config = allConfigurables[eval(latest.split(':')[0]).split("/")[1]] - if isinstance(config, CondDBAccessSvc): - self.propagateProperty("HeartBeatCondition", config) - # Pass along the configuration for the layered DBs - elif isinstance(config, CondDBLayeringSvc): - for ly in config.Layers: - #Only apply HeartBeatCondition for ONLINE - if isinstance(ly, CondDBAccessSvc) and ly.getName().startswith("ONLINE_"): - self.propagateProperty("HeartBeatCondition", ly) - - if not self.getProp("Simulation"): - # Standard configurations - # - Reconstruction / analysis - disp = CondDBDispatcherSvc("MainCondDBReader", - MainAccessSvc = partition["DDDB"], - Alternatives = { - "/Conditions": partition["LHCBCOND"], - "/Conditions/Online": partition["ONLINE"], - "/Conditions/DQ": partition["DQFLAGS"] - }) - else: - # - Simulation - disp = CondDBDispatcherSvc("SimulationCondDBReader", - MainAccessSvc = partition["DDDB"], - Alternatives = { - "/Conditions": partition["SIMCOND"] - }) - CondDBCnvSvc( CondDBReader = disp ) - - if not (self.getProp("Online") or self.getProp("Simulation")): - self._properties["EnableRunStampCheck"].setDefault(True) - if self.getProp("EnableRunStampCheck"): - from Configurables import RunStampCheck - rsc = RunStampCheck() - self.propagateProperty("RunStampCondition", rsc) - ApplicationMgr().ExtSvc.append(rsc) - - # Load the CALIBOFF layer above everything if it exists -# if len([x for x in parttypes if x[0] == 'CALIBOFF']): -# self._addLayer(getAnyDBReader('CALIBOFF')) - - localTags = self.getProp("LocalTags") - not_applied = [] - for p in localTags: - if p in partition: - taglist = list(localTags[p]) - taglist.reverse() # we need to stack the in reverse order to use the first as on top of the others - i = 0 # counter - if p is "CALIBOFF": - if LoadCALIBDB is not "OFFLINE": - raise ValueError("invalid argument LoadCALIBDB set at '%s' instead of 'OFFLINE' for accessing local tags for CALIBOFF.db" % LoadCALIBDB) - pcolayers = [] - for t in taglist: - pcolayers.append(partition[p].clone("CALIBOFF_%d" %i, DefaultTAG = t)) - i += 1 - for r in partition["ONLINE"].Readers: - config = allConfigurables[eval(r.split(':')[0]).split("/")[1]] - if isinstance(config, CondDBLayeringSvc): - config.Layers = pcolayers + config.Layers - elif type(partition[p]) is not CondDBTimeSwitchSvc: - for t in taglist: - self._addLayer(partition[p].clone("%s_%d" % (p, i), - DefaultTAG = t)) - i += 1 - else: - not_applied.append(p) - else: - not_applied.append(p) - if not_applied: - log.warning("Cannot set the local tags for partitions %r", not_applied) - - # Modify partitions to use local copies of the DBs - # before adding user layers and alternatives, which should be already local. - # This is a no-operation if the property is not set - self.__make_sqlite_local_copy__(CondDBCnvSvc()) - - # Add layers and alternatives - call = { self.LAYER : self._addLayer, - self.ALTERNATIVE : self._addAlternative } - for override in self.getProp("Overrides"): - apply(call[override[0]], override[1:]) - - # Add the logger - filename = self.getProp("LogFile") - if filename: - cnvSvc = allConfigurables["CondDBCnvSvc"] - cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader, - LogFile = filename) - - # Suppress pointless warning from COOL_2_5_0 - msgSvc = getConfigurable("MessageSvc") - msgSvc.setError.append("RelationalDatabase") - - # Set up Virtual File System service, can be used by ParticlePropertySvc - from Gaudi.Configuration import VFSSvc - from Configurables import CondDBEntityResolver - VFSSvc().FileAccessTools.append(CondDBEntityResolver()) - - -# Exported symbols -__all__ = [ "addCondDBLayer", "addCondDBAlternative", "useCondDBLogger", - "configureOnlineSnapshots" ] -# Configurables provided by the package -__all__ += [ "CondDBAccessSvc", - "CondDBDispatcherSvc", "CondDBLayeringSvc", "CondDBTimeSwitchSvc", - "CondDBSQLiteCopyAccSvc", "CondDBLogger", - "CondDBCnvSvc", - "CondDB" ] - -# List of known implementations of ICondDBReader (str is used for backward compatibility) -__CondDBReaders__ = [ CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc, - str ] - -def _assertConfig(funcname): - """ - Check if the default configuration has been loaded. - """ - if "CondDBCnvSvc" not in allConfigurables: - raise RuntimeError("You cannot call '%s' before the standard CondDB configuration"%funcname) - -def addCondDBLayer(accessSvc): - """ - Add the given CondDBReader as a layer on top of the existing configuration. - - Example: - addCondDBLayer(myDB) - """ - DetCond().addLayer(accessSvc) - -def addCondDBAlternative(accessSvc, path): - """ - Add the given CondDBReader as an alternative to the existing configuration - for the specified path. - - Example: - addCondDBAlternative(myDB,"/Conditions/MyDetector/Alignment") - """ - DetCond().addAlternative(accessSvc, path) - -def useCondDBLogger(filename = None, logger = None): - """ - Add the CondDBLogger to the chain of CondDBReaders. - - The simplest usage is to call the function without options (use defaults), or - pass a file name. - """ - _assertConfig('useCondDBLogger') - cnvSvc = allConfigurables["CondDBCnvSvc"] - if logger is None: - # use the default configuration - cnvSvc.CondDBReader = CondDBLogger(LoggedReader = cnvSvc.CondDBReader) - elif type(logger) is CondDBLogger: - # use the user-provided configurable - logger.LoggedReader = cnvSvc.CondDBReader - cnvSvc.CondDBReader = logger - else: - raise TypeError("useCondDBLogger does not support '%s'"%logger.__class__.__name__) - # Use the user specified filename, if any - if filename: - cnvSvc.CondDBReader.LogFile = filename - -def _timegm(t): - """Inverse of time.gmtime. Implementation from Gaudi::Time.""" - import time - if t[8] != 0: # ensure that dst is not set - t = tuple(list(t[0:8]) + [0]) - t1 = time.mktime(t) - gt = time.gmtime(t1) - t2 = time.mktime(gt) - return t1 + (t1 - t2) - -def defConnStrFunc(ym_tuple): - return self.connStrOnline(ym_tuple) - -def connStrOnline(ym_tuple): - dbpath = os.environ["SQLITEDBPATH"] - if exists(join(dbpath, "ONLINE-%04d%02d.db" % ym_tuple)): - return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d%02d.db/ONLINE" % ym_tuple - return "sqlite_file:$SQLITEDBPATH/ONLINE-%04d.db/ONLINE" % ym_tuple[0] - -def getAnyDBReader(layer = 'CALIBOFF', svc = CondDBAccessSvc): - CacheHighLevel = 200 - if layer == 'DDDB' : CacheHighLevel = 1700 - # Put the discovered layer on top - cfg = getConfigurable(layer, svc) - if svc is not CondDBAccessSvc: return cfg - try: cfg.ConnectionString - except AttributeError: # Set up connection for the 1st time - connstr = "sqlite_file:$SQLITEDBPATH/%s.db/%s" % (layer, layer) - if layer == 'DQFLAGS' : - cfg = CondDBAccessSvc(layer, ConnectionString = connstr, - CacheLowLevel = 5, CacheHighLevel = 10) - else: - cfg = CondDBAccessSvc(layer, ConnectionString = connstr, - CacheHighLevel = CacheHighLevel) - return cfg - -def getOnlineDBReader(ym_tuple, granularity = 'YEARLY', connStrFunc = None): - cnstr = '' - ymstr = '' - if granularity == 'YEARLY': - ymstr = "%04d" %ym_tuple[0] - cnstr = connStrFunc((ym_tuple[0],13)) - else: - ymstr = "%04d%02d" %ym_tuple - cnstr = connStrFunc(ym_tuple) - - ptnm = "ONLINE_" + ymstr - accSvc = CondDBAccessSvc(ptnm, ConnectionString = cnstr) - dblayers = [ accSvc ] - LoadCALIBDB = os.environ.get('LoadCALIBDB') - if ym_tuple[0] < 2015 or LoadCALIBDB is not "OFFLINE": # For datatype before 2015, no CALIBOFF layer is needed - return accSvc - dbpath = os.environ["SQLITEDBPATH"] - layer = 'CALIBOFF' - if exists(join(dbpath, layer + '.db')): - # Put the discovered layer on top - cfg = getConfigurable(layer, CondDBAccessSvc) - try: cfg.ConnectionString - except AttributeError: # Set up connection for the 1st time - cfg = CondDBAccessSvc("CALIBOFF", ConnectionString = - cnstr.replace('ONLINE-%s.db/ONLINE' %ymstr, "%s.db/%s" % (layer, layer)), CacheHighLevel = 200) - dblayers.insert(0, cfg) - - if (len(dblayers) == 1): return accSvc # In case no CALIBOFF.db is found - return CondDBLayeringSvc("ONLINELAYER_"+ymstr, Layers = dblayers ) - -def configureOnlineSnapshots(start = None, end = None, connStrFunc = None): - if connStrFunc is None: - connStrFunc = connStrOnline - - # prepare the configurable instance - ONLINE = CondDBTimeSwitchSvc("ONLINE") - - # Default snapshots granularity - granularity = 'YEARLY' - - # Set the first available snapshot pair: per-year by default - if start is None: - first_snapshot = (2008, None) - else: - first_snapshot = start - - # Set the last available snapshot pair: current year by default - if end is None: - import time - last_snapshot = (time.gmtime()[0], None) - else: - last_snapshot = end - - # If last snapshot is per-month switch the first one to be also per-month - if last_snapshot[1]: - granularity = 'MONTHLY' - first_snapshot = (2008, 6) - - # reset the list of readers, for safety - ONLINE.Readers = [] - # loop from first to last-1 - i = first_snapshot - until = 0 # this makes the first service used from times starting from 0 - while i < last_snapshot: - accSvc = getOnlineDBReader(i, granularity, connStrFunc) - since = until - # increment - if granularity == 'YEARLY': - i = (i[0]+1, None) - until = int(_timegm(tuple([i[0], 1, 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 - else: - if i[1] == 12: i = (i[0]+1,1) - else: i = (i[0],i[1]+1) - until = int(_timegm(tuple([i[0], i[1], 1, 0, 0, 0, 0, 0, 0]))) * 1000000000 - descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) - ONLINE.Readers.append(descr) - - # append the last database with validity extended to the maximum validity - accSvc = getOnlineDBReader(i, granularity, connStrFunc) - since = until - until = 0x7fffffffffffffffL # Defined in PyCool.cool as ValidityKeyMax - descr = "'%s':(%d,%d)" % ( accSvc.getFullName(), since, until ) - ONLINE.Readers.append(descr) diff --git a/Det/DetCond/python/DetCond/HistoCond.py b/Det/DetCond/python/DetCond/HistoCond.py deleted file mode 100644 index c89d49911..000000000 --- a/Det/DetCond/python/DetCond/HistoCond.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -# ============================================================================= -## @file DetCond/HistoCond.py -# Decorate the Condition object with functions to extract 1d and 2d-histograms -# @authorVanya BELYAEV Ivan.Belyaev@nikhef.nl -# @date 2009-12-01 -# ============================================================================= -""" -Decorate the Condition object with functions to extract 1d and 2d-histograms, and -define functions to convert 1d and 2d histograms to Condition parameter strings. -""" -# ============================================================================= -__author__ = "Vanya BELYAEV Ivan.Belyaev@nikhef.nl and Dmitry Golubkov" -__version__ = "CVS Tag $Name: not supported by cvs2svn $, verison $Revision: 1.1 $" -# ============================================================================= -# export nothing -__all__ = () ## export nothing -# ============================================================================= - -## import HistoStrings.Histos -from GaudiPython.Bindings import gbl as cpp - -_C = cpp.Condition -# ============================================================================= -## function to convert 1D histogram to an xml param string -def histo1DAsParam ( h1d, name = 'name', comment = 'comment' ) : - """ - Convert 1D histogram to an xml param string - """ - param_head = '\n <param name = "%s" type = "Histo1D" comment="%s">\n' - param_tail = '\n </param>\n' - - return param_head % (name, comment) + h1d.toString() + param_tail -# ============================================================================= -## function to convert 2D histogram to an xml param string -def histo2DAsParam ( h2d, name = 'name', comment = 'comment' ) : - """ - Convert 2D histogram to an xml param string - """ - param_head = '\n <param name = "%s" type = "Histo2D" comment="%s">\n' - param_tail = '\n </param>\n' - - return param_head % (name, comment) + h2d.toString() + param_tail -# ============================================================================= -## decorate the condition object: -if not hasattr ( _C , 'paramAsH1' ) : - - _F1 = cpp.DetDesc.Params.paramAsHisto1D - - # ========================================================================= - ## Extract the 1D-histogram form condition objects - # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - # @date 2009-12-01 - def _paramAsH1_ ( self , name ) : - """ - Extract the 1D-histiogram from condition objects - - >>> cond = ... ## get the condition object - >>> name = ... ## the name - - >>> h1 = cond.paramAsH1 ( name ) - >>> h1 = cond.paramAsHisto1D ( name ) # same as Condition.paramAsH1 - """ - return _F1 ( self , name ) - - _paramAsH1_ . __doc__ += '\n' + _F1 . __doc__ - _C .paramAsH1 = _paramAsH1_ - _C .paramAsHisto1D = _paramAsH1_ - -# ============================================================================= -## decorate the condition object: -if not hasattr ( _C , 'paramAsH2' ) : - - _F2 = cpp.DetDesc.Params.paramAsHisto2D - - # ========================================================================= - ## Extract the 2D-histogram form condition objects - # @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - # @date 2009-12-01 - def _paramAsH2_ ( self , name ) : - """ - Extract the 2D-histiogram from condition objects - - >>> cond = ... ## get the condition object - >>> name = ... ## the name - - >>> h2 = cond.paramAsH2 ( name ) - >>> h2 = cond.paramAsHisto2D ( name ) # same as Condition.paramAsH2() - """ - return _F2 ( self , name ) - - _paramAsH2_ . __doc__ += '\n' + _F2 . __doc__ - _C .paramAsH2 = _paramAsH2_ - _C .paramAsHisto2D = _paramAsH2_ - -if '__main__' == __name__ : - - print __doc__ - print __author__ - print __version__ - -# ============================================================================= -# The END -# ============================================================================= diff --git a/Det/DetCond/python/DetCond/__init__.py b/Det/DetCond/python/DetCond/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/Det/DetCond/src/Lib/CondDBGenericCnv.cpp b/Det/DetCond/src/Lib/CondDBGenericCnv.cpp deleted file mode 100755 index b83b90922..000000000 --- a/Det/DetCond/src/Lib/CondDBGenericCnv.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// Include files -#include "GaudiKernel/IDetDataSvc.h" -#include "GaudiKernel/Time.h" -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/IValidity.h" -#include "GaudiKernel/DataObject.h" - -#include "DetDesc/IDetectorElement.h" -#include "DetDesc/ValidDataObject.h" - -#include "CoolKernel/ValidityKey.h" -#include "CoolKernel/IFolder.h" -#include "CoolKernel/IObject.h" -#include "CoolKernel/IDatabase.h" -#include "CoolKernel/Exception.h" - -// local -#include "DetCond/CondDBGenericCnv.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBGenericCnv -// -// 2004-12-03 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBGenericCnv::CondDBGenericCnv(ISvcLocator* svc,const CLID& clid): - Converter(CONDDB_StorageType,clid,svc) -{} -//============================================================================= -// Destructor -//============================================================================= -CondDBGenericCnv::~CondDBGenericCnv() = default; - -//========================================================================= -// Initialization -//========================================================================= -StatusCode CondDBGenericCnv::initialize() { - // Initializes the grand father - StatusCode sc = Converter::initialize(); - - // Query the IDetDataSvc interface of the detector data service - m_detDataSvc = serviceLocator()->service("DetectorDataSvc"); - if( !sc.isSuccess() ) { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - log << MSG::ERROR << "Can't locate DetectorDataSvc" << endmsg; - return sc; - } else { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Succesfully located DetectorDataSvc" << endmsg; - } - // Get a pointer to the CondDBReader (implemented by the conversion service) - m_condDBReader.reset( conversionSvc().get() ); - if ( !m_condDBReader ) { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - log << MSG::ERROR << "The conversion service does not implement ICondDBReader!" << endmsg; - return StatusCode::FAILURE; - } - - return sc; -} - -//========================================================================= -// Finalization -//========================================================================= -StatusCode CondDBGenericCnv::finalize() { - m_detDataSvc.reset(); - m_condDBReader.reset(); - return Converter::finalize(); -} - -//========================================================================= -// Ask the event time to the DetectorDataSvc -//========================================================================= - -StatusCode CondDBGenericCnv::eventTime(Gaudi::Time &time) const { - if (!m_detDataSvc->validEventTime()){ - return StatusCode::FAILURE; - } - time = m_detDataSvc->eventTime(); - return StatusCode::SUCCESS; -} - -//========================================================================= -// Set the validity of the object -//========================================================================= -void CondDBGenericCnv::setObjValidity(Gaudi::Time &since, Gaudi::Time &till, DataObject *pObject){ - // Set validity of created object - IValidity* pValidity = dynamic_cast<IValidity*>(pObject); - - if ( pValidity != NULL ) { // it has a validity - - pValidity->setValidity(since, till); - - } else { - - // I cannot set the validity range - MsgStream log(msgSvc(),"CondDBGenericCnv"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG - << "Created object (CLID = " << pObject->clID() - << ") does not implement IValidity: cannot set validity" - << endmsg; - } -} - -//========================================================================= -// get an object from the conditions database -//========================================================================= -StatusCode CondDBGenericCnv::getObject (const std::string &path, const cool::ChannelId &channel, - ICondDBReader::DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until) { - - Gaudi::Time now; - StatusCode sc = eventTime(now); - if (sc.isFailure()) { - MsgStream log(msgSvc(),"CondDBGenericCnv"); - log << MSG::ERROR << "Cannot create DataObject: event time undefined" << endmsg; - return sc; - } - - return m_condDBReader->getObject(path,now,data,descr,since,until,channel); -} - -//========================================================================= -// get get the list of nodes in a folderset from the conditions database -//========================================================================= -StatusCode CondDBGenericCnv::getChildNodes(const std::string &path,std::vector<std::string> &node_names){ - MsgStream log(msgSvc(),"CondDBGenericCnv"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; - - return m_condDBReader->getChildNodes(path,node_names); -} -//============================================================================= - diff --git a/Det/DetCond/src/component/COOLConfSvc.cpp b/Det/DetCond/src/component/COOLConfSvc.cpp deleted file mode 100755 index 384a0b8f0..000000000 --- a/Det/DetCond/src/component/COOLConfSvc.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#ifdef __INTEL_COMPILER // Disable ICC remark from CORAL MessageStream and Boost - #pragma warning(disable:2259) -#endif - -// Include files -#include "RelationalAccess/ConnectionService.h" -#include "RelationalAccess/IConnectionServiceConfiguration.h" -#include "RelationalAccess/IReplicaSortingAlgorithm.h" -#include "RelationalAccess/IDatabaseServiceDescription.h" - -#include "CoolKernel/IDatabaseSvc.h" -#include "CoolApplication/Application.h" -#include "CoolApplication/DatabaseSvcFactory.h" - -#include "COOLConfSvc.h" - -#ifdef WIN32 -#define NOMSG -#define NOGDI -#endif - -// For the case insensitive string comparison (boost::algorithm::icontains). -#include "boost/algorithm/string/predicate.hpp" -// For random numbers not affecting simulation. -#include "boost/random/linear_congruential.hpp" -//#include "boost/random/uniform_smallint.hpp" -#include "boost/date_time/posix_time/posix_time_types.hpp" - -namespace -{ - - /** @class ReplicaSortAlg - * - * Small class implementing coral::IReplicaSortingAlgorithm interface to allow dynamic sorting of - * database replicas obtained from LFC. - * - * When retrieving the list of DB replicas, LFCReplicaService obtains a list in an arbitrary order. - * We have to provide to CORAL a class to be used to sort the list of replicas according to our - * needs. First we want the closest DB, identified by the environment variable LHCBPRODSITE, then - * the CERN server (LCG.CERN.ch), while the remaining one can be in any order (this implementation - * uses the natural string ordering). - * - * @author Marco Clemencic - * @date 2007-05-02 - */ - class ReplicaSortAlg: virtual public coral::IReplicaSortingAlgorithm - { - typedef coral::IDatabaseServiceDescription dbDesc_t; - typedef std::vector< const dbDesc_t * > replicaSet_t; - - /** @class ReplicaSortAlg::Comparator - * - * Comparison function defining which replica comes before another. - * - * This class is used via the STL algorithm "sort" to order the list the way we need it. - * - * @author Marco Clemencic - * @date 2007-05-02 - */ - class Comparator: public std::binary_function<const dbDesc_t*,const dbDesc_t*,bool> - { - typedef boost::rand48 RandomGenType; - typedef RandomGenType::result_type WeightType; - typedef std::map<std::string,WeightType> WeightMap; - - /// Site that have to be used before the others - std::string site; - /// Map used to remember the priority of the sites. - /// the local site has weight -1, the other are randomly chosen the first - /// time they are encountered. - mutable WeightMap weights; - /// Random number generator. Using Boost to avoid interactions with the - /// random generator services. - mutable RandomGenType gen; - - WeightType getWeight(const std::string& key) const { - WeightMap::iterator i = weights.find(key); - if ( weights.end() == i ) { // not found - WeightType newWeight = 0; - if (boost::algorithm::icontains(key,site)) { - // it means that this is the site with highest priority - newWeight = gen.max(); - } else { - // all other sites are distributed randomly - newWeight = gen(); - } - weights[key] = newWeight; - return newWeight; - } - return i->second; - } - - public: - - /// Constructor. - /// @param theSite the local LHCb Production Site (<i>SITE</i>.<i>country</i>) - Comparator(std::string theSite): - site(std::move(theSite)), - gen(// this is the rather longish Boost way of getting the current number of - // seconds since the beginning of the day... that I want to use as seed - // for the local random number generator (I do not use "seconds since epoch" - // because the boosted way of getting it is too long). - boost::posix_time::second_clock::universal_time().time_of_day().total_seconds()) - {} - - /// Main function - result_type operator() (first_argument_type a, second_argument_type b) const - { - return getWeight(a->serviceParameter(a->serverNameParam())) - < - getWeight(b->serviceParameter(b->serverNameParam())); - } - - }; - - std::string localSite; - MsgStream log; - - public: - - /// Constructor. - /// @param theSite the local LHCb Production Site (LCG.<i>SITE</i>.<i>country</i>) - ReplicaSortAlg(std::string theSite, IMessageSvc *msgSvc): - localSite(std::move(theSite)), - log(msgSvc,"ReplicaSortAlg") - { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Constructor" << endmsg; - } - - /// Destructor. - virtual ~ReplicaSortAlg() - { - // log << MSG::VERBOSE << "ReplicaSortAlg --> destructor" <<std::endl; - } - - /// Main function - virtual void sort (std::vector< const coral::IDatabaseServiceDescription * > &replicaSet) - { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { - log << MSG::VERBOSE << "Original list" << endmsg; - replicaSet_t::iterator i; - for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { - log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; - } - - log << MSG::VERBOSE << "Sorting..." << endmsg; - } - std::sort(replicaSet.begin(),replicaSet.end(),Comparator(localSite)); - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) { - log << MSG::VERBOSE << "Sorted list" << endmsg; - replicaSet_t::iterator i; - for ( i = replicaSet.begin(); i != replicaSet.end(); ++i ) { - log << MSG::VERBOSE << " " << (*i)->serviceParameter((*i)->serverNameParam()) << endmsg; - } - } - } - - }; - -} - -// Factory implementation -DECLARE_SERVICE_FACTORY(COOLConfSvc) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -COOLConfSvc::COOLConfSvc(const std::string& name, ISvcLocator* svcloc): - base_class(name,svcloc) -{ - declareProperty("UseLFCReplicaSvc", m_useLFCReplicaSvc = false ); - declareProperty("LocalSite", m_localSite = "", - "The name of the site we are running on, used to order the " - "list of replicas in LFC."); - declareProperty("EnableCoralConnectionCleanUp", m_coralConnCleanUp = false ); - declareProperty("CoralConnectionRetrialPeriod", m_retrialPeriod = 60, - "Time between two connection trials (in seconds)."); - declareProperty("CoralConnectionRetrialTimeOut", m_retrialTimeOut = 15*60, - "How long to keep retrying before giving up (in seconds)."); -} -//============================================================================= -// Destructor -//============================================================================= -COOLConfSvc::~COOLConfSvc() {} - -//============================================================================= -// Access to COOL DatabaseSvc -//============================================================================= -cool::IDatabaseSvc& COOLConfSvc::databaseSvc() { - return coolApplication()->databaseService(); -} - -//============================================================================= -// Access to SEAL Context -//============================================================================= -coral::IConnectionService& COOLConfSvc::connectionSvc() { - return coolApplication()->connectionSvc(); -} - -//============================================================================= -// initialize -//============================================================================= -StatusCode COOLConfSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if ( ! m_coolApplication.get() ) { - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initializing COOL Application" << endmsg; - m_coolApplication.reset(new cool::Application); - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Getting CORAL Connection Service configurator" << endmsg; - coral::IConnectionServiceConfiguration &connSvcConf = - m_coolApplication->connectionSvc().configuration(); - - if ( m_useLFCReplicaSvc ) { - - log << MSG::INFO << "Using CORAL LFCReplicaService" << endmsg; - connSvcConf.setLookupService( "CORAL/Services/LFCReplicaService" ); - connSvcConf.setAuthenticationService( "CORAL/Services/LFCReplicaService" ); - - if ( m_localSite.empty() ) { - // if we didn't get a site from options, we try the environment var DIRACSITE - m_localSite = System::getEnv("DIRACSITE"); - if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { - // if DIRACSITE is not defined, we try, for backward compatibility, LHCBPRODSITE - m_localSite = System::getEnv("LHCBPRODSITE"); - if ( m_localSite.empty() || m_localSite == "UNKNOWN" ) { - // if none of the env. vars is set, let's stick to a "sensible" default - m_localSite = "CERN.ch"; - } - } - } - log << MSG::INFO << "Using '" << m_localSite << "' as preferred site" << endmsg; - - m_replicaSortAlg.reset(new ReplicaSortAlg(m_localSite,msgSvc())); - connSvcConf.setReplicaSortingAlgorithm(*m_replicaSortAlg); - } - - if ( ! m_coralConnCleanUp ) { - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Disabling CORAL connection automatic clean up" << endmsg; - connSvcConf.disablePoolAutomaticCleanUp(); - connSvcConf.setConnectionTimeOut( 0 ); - - } - - connSvcConf.setConnectionRetrialPeriod(m_retrialPeriod); - log << MSG::INFO << "CORAL Connection Retrial Period set to " - << connSvcConf.connectionRetrialPeriod() << "s" << endmsg; - - connSvcConf.setConnectionRetrialTimeOut(m_retrialTimeOut); - log << MSG::INFO << "CORAL Connection Retrial Time-Out set to " - << connSvcConf.connectionRetrialTimeOut() << "s" << endmsg; - - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode COOLConfSvc::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - m_coolApplication.reset(); - m_replicaSortAlg.reset(); - return base_class::finalize(); -} diff --git a/Det/DetCond/src/component/COOLConfSvc.h b/Det/DetCond/src/component/COOLConfSvc.h deleted file mode 100755 index 6de60e7cb..000000000 --- a/Det/DetCond/src/component/COOLConfSvc.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef COMPONENT_COOLCONFSVC_H -#define COMPONENT_COOLCONFSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "GaudiKernel/GaudiException.h" -#include "DetCond/ICOOLConfSvc.h" - -// Forward declarations -template <class TYPE> class SvcFactory; - -namespace cool { - class Application; - class RecordSpecification; -} -namespace coral { - class IReplicaSortingAlgorithm; -} - -/** @class COOLConfSvc COOLConfSvc.h - * - * Class used as interface to LCG COOL library API. It should expose as less as - * possible COOL internal details. - * - * @author Marco Clemencic - * @date 2005-01-11 - */ - -class COOLConfSvc: public extends1<Service, ICOOLConfSvc> { -public: - /// Initialize COOL (CondDB) Configuration Service - virtual StatusCode initialize(); - - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICOOLConfSvc implementation - /// Access to the CORAL connection service used by COOL (if needed). - virtual coral::IConnectionService& connectionSvc(); - - /// Get the COOL Database service (used to connect to the databases). - virtual cool::IDatabaseSvc& databaseSvc(); - -protected: - /// Standard constructor - COOLConfSvc(const std::string& name, ISvcLocator* svcloc); - - virtual ~COOLConfSvc( ); ///< Destructor - -private: - - inline cool::Application *coolApplication(){ - if (!m_coolApplication.get()) - throw GaudiException("Attempt to access COOL instance before initialization", - "(COOLConfSvc)" + name() + "::coolApplication", - StatusCode::FAILURE); - return m_coolApplication.get(); - } - - /// Pointer to a shared instance of the COOL Application - std::unique_ptr<cool::Application> m_coolApplication; - - std::unique_ptr<coral::IReplicaSortingAlgorithm> m_replicaSortAlg; - - /// Flag to turn off/on the CORAL LFCReplicaService (option UseLFCReplicaSvc, default = false). - /// Setting this option works only if it is set for the first COOLConfSvc initialized - /// because of a "feature" of CORAL. - bool m_useLFCReplicaSvc; - - /// Name of the grid site the application is running on. It is meaningful only - /// if m_useLFCReplicaSvc (option UseLFCReplicaSvc) is set to true. If not - /// specified the value of the environment variables "DIRACSITE" or - /// "LHCBPRODSITE" is used. If even the environment variables are not set, - /// then it is assumed to be "CERN.ch". (Note: the value is case insensitive) - std::string m_localSite; - - /// Flag to turn off/on the CORAL Automatinc connection clean up - /// (option EnableCoralConnectionCleanUp, default = false). - /// Setting this option works only if it is set for the first COOLConfSvc initialized. - bool m_coralConnCleanUp; - - /// Time between two connection trials (in seconds). - /// Passed to CORAL when loaded. - int m_retrialPeriod; - - /// How long to keep retrying before giving up (in seconds). - /// Passed to CORAL when loaded. - int m_retrialTimeOut; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<COOLConfSvc>; - -}; -#endif // COMPONENT_COOLCONFSVC_H diff --git a/Det/DetCond/src/component/CondDBAccessSvc.cpp b/Det/DetCond/src/component/CondDBAccessSvc.cpp deleted file mode 100755 index d8d75e653..000000000 --- a/Det/DetCond/src/component/CondDBAccessSvc.cpp +++ /dev/null @@ -1,1492 +0,0 @@ -// Include files -#include <sstream> -//#include <cstdlib> -//#include <ctime> - - -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -#include "GaudiKernel/IRndmGenSvc.h" -#include "GaudiKernel/IRndmEngine.h" - -#include "CoolKernel/DatabaseId.h" -#include "CoolKernel/IDatabaseSvc.h" -#include "CoolKernel/IFolder.h" -#include "CoolKernel/IFolderSet.h" -#include "CoolKernel/IObject.h" -#include "CoolKernel/IObjectIterator.h" -#include "CoolKernel/Exception.h" -#include "CoolKernel/RecordSpecification.h" -#include "CoolKernel/FolderSpecification.h" -#include "CoolKernel/StorageType.h" -#include "CoolKernel/Record.h" - -#include "CoralBase/AttributeList.h" -#include "CoralBase/Exception.h" -// FIXME: Needed because of COOL bug #38422 -#include "CoralBase/AttributeException.h" - -#include "DetCond/ICOOLConfSvc.h" - -// local -#include "CondDBAccessSvc.h" -#include "CondDBCache.h" - -#include "CondDBCommon.h" -#include "IOVListHelpers.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBAccessSvc) - -// Utility function -namespace { - template <class EXC> - inline void report_exception(MsgStream &log, const std::string &msg, const EXC& e){ - log << MSG::ERROR << msg << endmsg; - log << MSG::ERROR << System::typeinfoName(typeid(e)) << ": " - << e.what() << endmsg; - } -} - -#include "GaudiKernel/Sleep.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBAccessSvc -// -// 2005-01-11 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBAccessSvc::CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc): - base_class(name,svcloc), - m_coolConfSvc(0), - m_cache(0), - m_rndmSvc(0), - m_latestHeartBeat(0) -{ - declareProperty("ConnectionString", m_connectionString = "" ); - declareProperty("DefaultTAG", m_dbTAG = "" ); - declareProperty("NoDB", m_noDB = false ); - declareProperty("UseCache", m_useCache = true ); - declareProperty("CacheLowLevel", m_cacheLL = 10 ); - declareProperty("CacheHighLevel", m_cacheHL = 100 ); - //declareProperty("CachePreload", m_cachePreload=3600*1E9); // ns - declareProperty("CheckTAGTrials", m_checkTagTrials = 1 ); - declareProperty("CheckTAGTimeOut", m_checkTagTimeOut = 60 ); - declareProperty("ReadOnly", m_readonly = true ); - - declareProperty("ConnectionTimeOut", m_connectionTimeOutProp = 120 ); - - declareProperty("LazyConnect", m_lazyConnect = true ); - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); - declareProperty("HeartBeatCondition", m_heartBeatCondition = ""); - - declareProperty("QueryGranularity", m_queryGranularity = 0, - "Granularity of the query in the database (in time units), " - "to allow bulk retrievals."); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBAccessSvc::~CondDBAccessSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBAccessSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if (m_connectionTimeOutProp) { - m_connectionTimeOut = boost::posix_time::seconds(m_connectionTimeOutProp); - } else { - m_connectionTimeOut = boost::posix_time::pos_infin; - } - - if ( m_noDB && !m_useCache ) { - log << MSG::ERROR << "Database access disabled and cache off: I cannot work like that. Ciao!" << endmsg; - return StatusCode::FAILURE; - } - - if ( !m_noDB ) { - if ( connectionString() == "" ) { - // we need a connection string to connect to the DB - log << MSG::ERROR << "Connection to database requested and no connection string provided." << endmsg; - log << MSG::ERROR << "Set the option \"" << name() << ".ConnectionString\"." << endmsg; - return StatusCode::FAILURE; - } - - if ( ! m_lazyConnect ) { - sc = i_initializeConnection(); - if (!sc.isSuccess()) return sc; - } - - } - else { - log << MSG::INFO << "Database not requested: I'm not trying to connect" << endmsg; - } - - // set up cache if needed - if (m_useCache) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize CondDB cache." << endmsg; - m_cache = new CondDBCache(MsgStream(msgSvc(), name() + ".Cache"), - m_cacheHL, m_cacheLL); - if (m_cache == NULL) { - log << MSG::ERROR << "Unable to initialize CondDB cache." << endmsg; - return StatusCode::FAILURE; - } - // when we do bulk retrievals it is normal to have overlaps when inserting objects - // into the cache - m_cache->setSilentConflicts(m_queryGranularity > 0); - - } else { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "CondDB cache not needed" << endmsg; - m_cache = NULL; - } - if ( m_xmlDirectMapping && ! m_useCache ) { - // @todo: make it possible to use the direct mapping without cache - log << MSG::FATAL << "Cannot use direct XML mapping without cache (YET)" << endmsg; - return StatusCode::FAILURE; - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { - if (!m_heartBeatCondition.empty()) { - log << MSG::DEBUG << "Using heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; - } - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBAccessSvc::finalize(){ - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(), name() ); - log << MSG::DEBUG << "Finalize" << endmsg; - } - - // stop TimeOut thread - i_stopTimeoutChecker(); - - // release the database - m_db.reset(); - if (m_useCache) { - // dump the content of the cache - m_cache->dump(); - // dispose of the cache manager - delete m_cache; - } - if ( m_rndmSvc ) m_rndmSvc->release(); - - return base_class::finalize(); -} - -//============================================================================= -// Connect to the database -//============================================================================= -StatusCode CondDBAccessSvc::i_initializeConnection(){ - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(), name() ); - log << MSG::DEBUG << "Connection string = \"" << connectionString() << "\"" << endmsg; - } - - StatusCode sc = i_openConnection(); - if (!sc.isSuccess()) return sc; - - // start TimeOut thread - i_startTimeoutChecker(); - - return i_validateDefaultTag(); -} - -//============================================================================= -// Connect to the database -//============================================================================= -StatusCode CondDBAccessSvc::i_openConnection(){ - MsgStream log(msgSvc(), name() ); - - try { - if (! m_db) { // The database is not yet opened - - if ( !m_coolConfSvc ) { - StatusCode sc = service("COOLConfSvc",m_coolConfSvc,true); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot get COOLConfSvc" << endmsg; - return sc; - } - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Get cool::DatabaseSvc" << endmsg; - cool::IDatabaseSvc &dbSvc = m_coolConfSvc->databaseSvc(); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { - log << MSG::DEBUG << "cool::DatabaseSvc got" << endmsg; - log << MSG::DEBUG << "Opening connection" << endmsg; - } - m_db = dbSvc.openDatabase(connectionString(),m_readonly); - - } - else { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Database connection already established!" << endmsg; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieve the root folderset." << endmsg; - m_rootFolderSet = m_db->getFolderSet("/"); - } - // catch ( cool::DatabaseDoesNotExist &e ) { - catch ( coral::Exception &e ) { - report_exception(log,"Problems opening database",e); - m_db.reset(); - return StatusCode::FAILURE; - } - catch ( cool::Exception &e ) { - report_exception(log,"Problems opening database",e); - m_db.reset(); - return StatusCode::FAILURE; - } - - touchLastAccess(); - log << MSG::INFO << "Connected to database \"" << connectionString() << "\"" << endmsg; - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::i_validateDefaultTag() { - MsgStream log(msgSvc(), name() ); - - // Check the existence of the provided tag. - StatusCode sc = i_checkTag(); - - // Try again if requested - int trials_to_go = m_checkTagTrials - 1; // take into account the trial just done - while (!sc.isSuccess() && (trials_to_go > 0)){ - log << MSG::INFO << "TAG \"" << tag() << "\" not ready, I try again in " << m_checkTagTimeOut << "s. " - << trials_to_go << " trials left." << endmsg; - Gaudi::Sleep(m_checkTagTimeOut); - sc = i_checkTag(); - --trials_to_go; - } - - // Fail if the tag is not found - if (!sc.isSuccess()){ - log << MSG::ERROR << "Bad TAG given: \"" << tag() << "\" not in the database" << endmsg; - return sc; - } - log << MSG::INFO << "Using TAG \"" << tag() << "\"" << endmsg; - return StatusCode::SUCCESS; -} -//============================================================================= -// TAG handling -//============================================================================= -const std::string &CondDBAccessSvc::tag() const { return m_dbTAG; } -StatusCode CondDBAccessSvc::setTag(const std::string &_tag){ - - if (m_dbTAG == _tag) return StatusCode::SUCCESS; // no need to change - - StatusCode sc = i_checkTag(_tag); - if ( sc.isSuccess() ) { - m_dbTAG = _tag; - // the cache must be cleared if the tag is changed - clearCache(); - MsgStream log(msgSvc(), name() ); - log << MSG::WARNING << "TAG changed to \"" << _tag << "\"" << endmsg; - } else { - MsgStream log(msgSvc(), name() ); - log << MSG::WARNING << "Unable to set TAG \"" << _tag - << "\": not in the DB. (Still using \"" << tag() << "\")" << endmsg; - } - return sc; -} -StatusCode CondDBAccessSvc::i_checkTag(const std::string &tag) const { - - MsgStream log(msgSvc(), name() ); - if ( !m_db ) { - log << MSG::ERROR << "Check tag \"" << tag - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Check availability of tag \"" << tag << "\"" << endmsg; - /// @TODO: check all sub-nodes to validate the tag and not only the root - if (m_rootFolderSet) { - // HEAD tags are always good - //if ( (tag.empty()) || (tag == "HEAD") ) return StatusCode::SUCCESS; - if ( cool::IHvsNode::isHeadTag(tag) ) { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "\"" << tag << "\" is a HEAD tag: OK" << endmsg; - return StatusCode::SUCCESS; - } - // try to resolve the tag (it cannot be checked) - try { - try { - m_rootFolderSet->resolveTag(tag); - } catch (cool::NodeRelationNotFound) { - // to be ignored: it means that the tag exists, but somewhere else. - } catch (coral::AttributeException) { // FIXME: COOL bug #38422 - // to be ignored: it means that the tag exists, but somewhere else. - } - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "\"" << tag << "\" found: OK" << endmsg; - return StatusCode::SUCCESS; - } catch (cool::TagNotFound &) { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "\"" << tag << "\" NOT found" << endmsg; - return StatusCode::FAILURE; - } - catch (cool::TagRelationNotFound &e) { - log << MSG::ERROR << "got a cool::TagRelationNotFound : " << e.what() << endmsg; - return StatusCode::FAILURE; - } - catch (std::exception &e) { - report_exception(log,"got exception",e); - return StatusCode::FAILURE; - } - - } - return StatusCode::FAILURE; -} - - -//============================================================================= -// Return the connection string used to connect to the database. -//============================================================================= -const std::string &CondDBAccessSvc::connectionString() const{ - return m_connectionString; -} - -//============================================================================= -// Utilities -//============================================================================= -StatusCode CondDBAccessSvc::createNode(const std::string &path, - const std::string &descr, - StorageType storage, - VersionMode vers) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot create node in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - try { - switch (storage) { - case FOLDERSET: - m_db->createFolderSet(path,descr,true); - break; - case XML: - { - cool::FolderSpecification spec((vers == SINGLE) - ?cool::FolderVersioning::SINGLE_VERSION - :cool::FolderVersioning::MULTI_VERSION, - CondDB::getXMLStorageSpec()); - - // append to the description the storage type - std::ostringstream _descr; - _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - m_db->createFolder(path, - spec, - _descr.str(), - true); - } - break; - default: - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": unknown StorageType" << endmsg; - return StatusCode::FAILURE; - } - } catch(cool::NodeExists &){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the node already exists" << endmsg; - return StatusCode::FAILURE; - } catch(cool::Exception &e){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::createNode(const std::string &path, - const std::string &descr, - const std::set<std::string> &fields, - StorageType storage, - VersionMode vers) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot create node in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - try { - switch (storage) { - case FOLDERSET: - m_db->createFolderSet(path,descr,true); - break; - case XML: - { - cool::RecordSpecification recSpec; - for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ - recSpec.extend(*f, cool::StorageType::String16M); - } - cool::FolderSpecification spec((vers == SINGLE) - ?cool::FolderVersioning::SINGLE_VERSION - :cool::FolderVersioning::MULTI_VERSION, - recSpec); - - // append to the description the storage type - std::ostringstream _descr; - _descr << descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - m_db->createFolder(path, - spec, - _descr.str(), - true); - } - break; - default: - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": unknown StorageType" << endmsg; - return StatusCode::FAILURE; - } - } catch(cool::NodeExists &){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\": the node already exists" << endmsg; - return StatusCode::FAILURE; - } catch(cool::Exception &e){ - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to create the folder \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot store in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the object \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - try { - // retrieve folder pointer - cool::IFolderPtr folder = m_db->getFolder(path); - cool::Record payload(folder->payloadSpecification()); - payload["data"].setValue<cool::String16M>(data); - folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); - - } catch (cool::FolderNotFound &) { - - MsgStream log(msgSvc(), name() ); - if (m_db->existsFolderSet(path)) - log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << - path << '\"' << endmsg; - else - log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - - } catch (cool::Exception &e){ - - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the XML string into \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel) const { - if ( m_readonly ) { - MsgStream log(msgSvc(), name() ); - log << "Cannot store in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the object \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - try { - // retrieve folder pointer - cool::IFolderPtr folder = m_db->getFolder(path); - cool::Record payload(folder->payloadSpecification()); - for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ - payload[d->first].setValue<cool::String16M>(d->second); - } - - folder->storeObject(timeToValKey(since),timeToValKey(until),payload,channel); - - } catch (cool::FolderNotFound &) { - - MsgStream log(msgSvc(), name() ); - if (m_db->existsFolderSet(path)) - log << MSG::ERROR << "Trying to store data into the non-leaf folder \"" << - path << '\"' << endmsg; - else - log << MSG::ERROR << "Cannot find folder \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - - } catch (cool::Exception &e){ - - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Unable to store the XML string into \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - - } - return StatusCode::SUCCESS; -} - -cool::ValidityKey CondDBAccessSvc::timeToValKey(const Gaudi::Time &time) const { - // ValidityKey is an uInt64 of which only 63 bits used (0 -> 9223372036854775807), - // while time.ns() is a positive signed Int64! (the same thing) - return time.ns(); -} - -Gaudi::Time CondDBAccessSvc::valKeyToTime(const cool::ValidityKey &key) const { - return Gaudi::Time(key); -} - -StatusCode CondDBAccessSvc::tagLeafNode(const std::string &path, const std::string &tagName, - const std::string &description) { - MsgStream log(msgSvc(),name()); - - if ( m_readonly ) { - log << "Cannot tag in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - log << MSG::ERROR << "Unable to tag the leaf node \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - DataBaseOperationLock dbLock(this); - try { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering tagLeafNode: \"" << path << '"' << endmsg; - - cool::IFolderPtr folder = m_db->getFolder(path); - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION){ - log << MSG::WARNING << "Not tagging leaf node \"" << path << "\": single-version" << endmsg; - } else { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Tagging leaf node \"" << path << "\": " << tagName << endmsg; - folder->tagCurrentHead(tagName, description); - } - - } catch (cool::FolderNotFound &) { - - if (m_db->existsFolderSet(path)) - log << MSG::ERROR << "Node \"" << path << "\" is not leaf." << endmsg; - else - log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - - } catch (cool::Exception &e){ - - log << MSG::ERROR << "Unable tag leaf node \"" << path - << "\" (cool::Exception): " << e.what() << endmsg; - return StatusCode::FAILURE; - - } - - return StatusCode::SUCCESS; -} - -std::string CondDBAccessSvc::generateUniqueTagName(const std::string &base, - const std::set<std::string> &reserved) const { - - if ( !m_db->isOpen() ) { - throw GaudiException("Database not open","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); - } - if ( ! m_rndmSvc ) { - IRndmGenSvc *svc; - StatusCode sc = service("RndmGenSvc",svc,true); - const_cast<CondDBAccessSvc*>(this)->m_rndmSvc = svc; - if ( ! sc.isSuccess() ) { - throw GaudiException("Cannot get a pointer to RndmGenSvc","CondDBAccessSvc::generateUniqueTagName",sc); - } - } - - std::string tag = ""; - do { - // start with the signature - tag = "_auto_"; - // add the base, if any - if (!base.empty()) tag += base + "-"; - // append 6 randomly chosen chars in set [0-9A-Za-z] - for ( int i = 0; i<6; ++i ) { - char c=(char) ( 62.0 * m_rndmSvc->engine()->rndm() ); - if ( c > 61 ) GaudiException("Generator failure","CondDBAccessSvc::generateUniqueTagName",StatusCode::FAILURE); // c %= 62; - if ( c >= 36 ) tag += c + 61; - else if ( c >= 10 ) tag += c + 55; - else tag += c + 48; - } - // check if the random name already exists or is reserved - } while ( m_db->existsTag(tag) || (reserved.find(tag) != reserved.end()) ); - - return tag; -} - - -StatusCode CondDBAccessSvc::recursiveTag(const std::string &path, const std::string &tagName, - const std::string &description) { - std::set<std::string> reserved; - DataBaseOperationLock dbLock(this); - return i_recursiveTag(path,tagName,description,tagName,reserved); -} - -StatusCode CondDBAccessSvc::i_recursiveTag(const std::string &path, const std::string &base, - const std::string &description, - const std::string &tagName, - std::set<std::string> &reserved) { - MsgStream log(msgSvc(),name()); - - if ( m_readonly ) { - log << MSG::ERROR << "Cannot tag in read-only mode" << endmsg; - return StatusCode::FAILURE; - } - if ( !m_db ) { - log << MSG::ERROR << "Unable to tag the inner node \"" << path - << "\": the database is not opened!" << endmsg; - return StatusCode::FAILURE; - } - - try { - // start reserving the tag name we want to apply to the current folderset - reserved.insert(tagName); - - // get the list of child nodes (both types) - cool::IFolderSetPtr this_folderset = m_db->getFolderSet(path); - std::vector<std::string> folders = this_folderset->listFolders(); - std::vector<std::string> foldersets = this_folderset->listFolderSets(); - - // loop over leaf nodes and apply the tags - std::vector<std::string>::iterator f; - for ( f = folders.begin(); f != folders.end(); ++f ) { - - std::string auto_tag = generateUniqueTagName(base,reserved); - cool::IFolderPtr child_folder = m_db->getFolder(*f); - - if (child_folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION) { - // only multi-version folders can be tagged - child_folder->tagCurrentHead(auto_tag, description); - // associate the child folder tag with the parent one - child_folder->createTagRelation(tagName, auto_tag); - } - - } - - // loop over inner nodes and recurse - for ( f = foldersets.begin(); f != foldersets.end(); ++f ) { - - std::string auto_tag = generateUniqueTagName(base,reserved); - StatusCode sc = i_recursiveTag(*f,base,description,auto_tag,reserved); - if (!sc.isSuccess()) return sc; - - cool::IFolderSetPtr child_folderset = m_db->getFolderSet(*f); - child_folderset->createTagRelation(tagName, auto_tag); - - } - } - catch (cool::FolderSetNotFound &) { - if (m_db->existsFolder(path)) - log << MSG::ERROR << "Node \"" << path << "\" is a leaf." << endmsg; - else - log << MSG::ERROR << "Cannot find node \"" << path << '\"' << endmsg; - return StatusCode::FAILURE; - } - catch (cool::Exception &e) { - log << MSG::ERROR << "Problems tagging" << endmsg; - log << MSG::ERROR << e.what() << endmsg; - return StatusCode::FAILURE; - } - - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - cool::ChannelId channel){ - return i_getObject(path, when, data, descr, since, until, - true, channel, ""); -} - -StatusCode CondDBAccessSvc::getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - const std::string &channel){ - return i_getObject(path, when, data, descr, since, until, - false, 0, channel); -} -/* -namespace { - ICondDBReader::IOVList getHoles(const ICondDBReader::IOV& iov, const ICondDBReader::IOVList& data){ - typedef ICondDBReader::IOVList IOVList; - typedef ICondDBReader::IOV IOV; - IOVList result; - - Gaudi::Time last = iov.since; // keep track of the end of coverage - // loop over covering interval - for (IOVList::const_iterator covered = data.begin(); covered != data.end(); ++covered) { - if (covered->since > last) { // hole between the end of coverage and begin of next IOV - result.push_back(IOV(last, covered->since)); - } - last = covered->until; // prepare to look for the next hole - } - if (last < iov.until) { - // we didn't get anything to cover until the end of the requested IOV - result.push_back(IOV(last, iov.until)); - } - - return result; - } -} -*/ - -ICondDBReader::IOVList CondDBAccessSvc::i_getIOVsFromDB(const std::string & path, const IOV &iov, cool::ChannelId channel) { - ICondDBReader::IOVList result; - try { - DataBaseOperationLock dbLock(this); - // we want a folder, so go to the database to get it - cool::IFolderPtr folder = database()->getFolder(path); - cool::IObjectIteratorPtr objects; - - // FIXME: we need to considered the query granularity - // Note: IFolder::browseObject returns the objects valid up to the 'until' - // included, which means that asking for [1,10] will return also the - // object starting at 10, so, to exclude it we need to ask for [1,9]. - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION - || tag().empty() || tag() == "HEAD" ){ - objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel); - } else { - objects = folder->browseObjects(iov.since.ns(), iov.until.ns() - 1, channel, folder->resolveTag(tag())); - } - - if (!objects->isEmpty()) {// check if we managed to find anything - while (objects->goToNext()) { - // add data to the cache while filling the list of IOVs - const cool::IObject &obj = objects->currentRef(); - m_cache->insert(folder, obj, channel); - result.push_back(ICondDBReader::IOV(Gaudi::Time(obj.since()), Gaudi::Time(obj.until()))); - } - } - } catch(cool::FolderNotFound &/*e*/) { - // ignore - } catch (cool::TagRelationNotFound &/*e*/) { - // ignore - } catch (cool::NodeRelationNotFound &) { - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - } - return result; -} - -ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - typedef ICondDBReader::IOVList IOVList; - IOVList result; - if (m_useCache){ - /// Look for holes in the timeline of the cache - result = m_cache->getIOVs(path, iov, channel); - IOVList holes = IOVListHelpers::find_holes(result, iov); - for(IOVList::iterator hole = holes.begin(); hole != holes.end(); ++hole) { - const IOVList cover = i_getIOVsFromDB(path, *hole, channel); - result.insert(result.end(), cover.begin(), cover.end()); - } - std::sort(result.begin(), result.end()); - } else { - result = i_getIOVsFromDB(path, iov, channel); - } - return result; -} - -ICondDBReader::IOVList CondDBAccessSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - cool::ChannelId id; - if (m_useCache){ - // Check if the cache knows about the path - if (m_cache->hasPath(path)) { - // the folder is in the cache - if (m_cache->getChannelId(path, channel, id)) { - return getIOVs(path, iov, id); // we know about the folder and the channel - } else { - return ICondDBReader::IOVList(); // we know about the folder, but not about the channel - } - } - } - - // the folder is not in the cache or we do not use the cache, so we have to - // get the channel id from the DB - try { - DataBaseOperationLock dbLock(this); - cool::IFolderPtr folder = database()->getFolder(path); - id = folder->channelId(channel); - } catch(cool::FolderNotFound &/*e*/) { - return ICondDBReader::IOVList(); // unknown folder - } catch(cool::InvalidChannelName &/*e*/) { - return ICondDBReader::IOVList(); // unknown channel - } - return getIOVs(path, iov, id); -} - -StatusCode CondDBAccessSvc::i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, - DataPtr &data, - std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, - bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ - try { - - bool existsFolderSet = false; - { - DataBaseOperationLock dbLock(this); - existsFolderSet = database()->existsFolderSet(path); - } - // Check if the user asked for a folderset - if (existsFolderSet) { - if ( !m_xmlDirectMapping ) { - // with FolderSets, I put an empty entry and clear the shared_ptr - if (m_useCache) m_cache->addFolderSet(path,""); - data.reset(); - } else { - // Using XML direct mapping, foldersets are replaced in the cache - // with the XML equivalent (a catalog). - i_generateXMLCatalogFromFolderset(path); - // now get the data from the cache - m_cache->get(path,when,channel,since,until,descr,data); - } - - return StatusCode::SUCCESS; - } - else { - // Special retrieval procedure if we use "query granularity" (make sense - // only when using the cache). - if (m_useCache && m_queryGranularity > 0){ - // modify the range rounding it to the requested granularity (if needed) - // Range used for the query - cool::ValidityKey sinceWhen = when, untilWhen = when; - - sinceWhen -= when % m_queryGranularity; - untilWhen = sinceWhen + m_queryGranularity; - - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(),name()); - log << MSG::DEBUG << "Retrieving conditions in range " - << sinceWhen << " - " << untilWhen << endmsg; - } - - DataBaseOperationLock dbLock(this); - // we want a folder, so go to the database to get it - cool::IFolderPtr folder = database()->getFolder(path); - cool::IObjectIteratorPtr objects; - if ( !use_numeric_chid ) { // we need to convert from name to id - channel = folder->channelId(channelstr); - } - - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION - || tag().empty() || tag() == "HEAD" ){ - objects = folder->browseObjects(sinceWhen, untilWhen, channel); - } else { - objects = folder->browseObjects(sinceWhen, untilWhen, channel, folder->resolveTag(tag())); - } - - if (objects->isEmpty()) // check if we managed to find anything - return StatusCode::FAILURE; - - while (objects->goToNext()) { - m_cache->insert(folder, objects->currentRef(), channel); - } - // now get the data from the cache - m_cache->get(path, when, channel, since, until, descr, data); - - } else { // no-cache or no granularity are quite similar - - DataBaseOperationLock dbLock(this); - // we want a folder, so go to the database to get it - cool::IFolderPtr folder = database()->getFolder(path); - cool::IObjectPtr object; - if ( !use_numeric_chid ) { // we need to convert from name to id - channel = folder->channelId(channelstr); - } - - if (folder->versioningMode() == cool::FolderVersioning::SINGLE_VERSION - || tag().empty() || tag() == "HEAD" ){ - object = folder->findObject(when, channel); - } else { - object = folder->findObject(when, channel, folder->resolveTag(tag())); - } - - if (m_useCache) { - // add the object to the cache - m_cache->insert(folder, *object, channel); - // and get the data back - m_cache->get(path, when, channel, since, until, descr, data); - } else { - data = DataPtr(new cool::Record(object->payload())); - descr = folder->description(); - since = object->since(); - until = object->until(); - } - } - } - } catch ( cool::FolderNotFound &/*e*/) { - //log << MSG::ERROR << e << endmsg; - return StatusCode::FAILURE; - } catch (cool::TagRelationNotFound &/*e*/) { - return StatusCode::FAILURE; - } catch (cool::ObjectNotFound &/*e*/) { - //log << MSG::ERROR << "Object not found in \"" << path << - // "\" for tag \"" << (*accSvc)->tag() << "\" ("<< now << ')' << endmsg; - //log << MSG::DEBUG << e << endmsg; - return StatusCode::FAILURE; - } catch (cool::NodeRelationNotFound &) { - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - return StatusCode::FAILURE; - } catch (coral::AttributeException &) { // FIXME: COOL bug #38422 - // to be ignored: it means that the tag exists, but it is not in the - // node '/'. - return StatusCode::FAILURE; - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - return StatusCode::SUCCESS; -} - -StatusCode CondDBAccessSvc::i_getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - bool use_numeric_chid, cool::ChannelId channel, const std::string &channelstr){ - - cool::ValidityKey vk_when = timeToValKey(when); - cool::ValidityKey vk_since = 0, vk_until = 0; - - // This is not in i_getObjectFromDB because I need to ensure that m_latestHeartBeat - // is correctly set even when using the cache. - if (vk_when >= i_latestHeartBeat()) { - MsgStream log(msgSvc(), name()); - const Gaudi::Time hb = valKeyToTime(i_latestHeartBeat()); - log << MSG::ERROR << "Database not up-to-date. Latest known update is at " - << hb.format(false, "%Y-%m-%d %H:%M:%S") << "." << hb.nanoformat() - << " UTC, event time is " - << when.format(false, "%Y-%m-%d %H:%M:%S") << "." << when.nanoformat() - << " UTC" << endmsg; - return StatusCode::FAILURE; - } - - if (m_useCache) { - - // Check if the cache knows about the path - if ( m_cache->hasPath(path) ) { - - // the folder is in the cache - if ( !use_numeric_chid ) { // we need to convert from name to id - if (!m_cache->getChannelId(path,channelstr,channel)) { - // the channel name cannot be found in the cached folder - return StatusCode::FAILURE; - } - } - - if ( m_cache->get(path,vk_when,channel,vk_since,vk_until,descr,data) ) { - since = valKeyToTime(vk_since); - /// Artificially cutting the end of validity of the retrieved object to - /// the latest know heart beat guarantees that we will have to go back - /// to the database when the event time exceeds it. - /// Note that we are not calling i_latestHeartBeat() on purpose: - /// it returns +inf if called during initialize, but it sets - /// correctly the variable m_latestHeartBeat. - until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); - return StatusCode::SUCCESS; - } - } - - } - // If we get here, either we do not know about the folder, we didn't - // find the object, or we are not using the cache, so let's try the DB - if (m_noDB) { - // oops... we are not using the db: no way of getting the object from it - return StatusCode::FAILURE; - } - - StatusCode sc = i_getObjectFromDB(path,vk_when,data,descr,vk_since,vk_until,use_numeric_chid,channel,channelstr); - since = valKeyToTime(vk_since); - /// Artificially cutting the end of validity of the retrieved object to - /// the latest know heart beat guarantees that we will have to go back - /// to the database when the event time exceeds it. - /// Note that we are not calling i_latestHeartBeat() on purpose: - /// it returns +inf if called during initialize, but it sets - /// correctly the variable m_latestHeartBeat. - until = valKeyToTime(std::min(vk_until, m_latestHeartBeat)); - return sc; -} - -namespace { - // Small helper function to reduce duplications - inline void cannotGetHeartBeatError(CondDBAccessSvc *self, const std::string&path) { - MsgStream log(self->msgSvc(), self->name()); - log << MSG::ERROR << "Cannot get latest heart beat (" << path - << ") in the database" << endmsg; - } -} -const cool::ValidityKey& CondDBAccessSvc::i_latestHeartBeat() -{ - if (m_latestHeartBeat == 0) { - if (m_heartBeatCondition.empty() || - m_noDB) { // it doesn't make sense to ask for a heart beat if we do not use the DB - // no heart beat condition: the database is always valid - m_latestHeartBeat = cool::ValidityKeyMax; - } else { - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(),name()); - log << MSG::DEBUG << "Retrieving heart beat condition \"" << m_heartBeatCondition << '"' << endmsg; - } - // we do not use the normal functions to retrieve the object because - // we want to by-pass the cache - try { - DataBaseOperationLock dbLock(this); - cool::IFolderPtr folder = database()->getFolder(m_heartBeatCondition); - cool::IObjectPtr obj = folder->findObject(cool::ValidityKeyMax-1, 0); - m_latestHeartBeat = obj->since(); - } - catch (cool::Exception &) { - cannotGetHeartBeatError(this, m_heartBeatCondition); - m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database - } - catch (coral::Exception &) { - cannotGetHeartBeatError(this, m_heartBeatCondition); - m_latestHeartBeat = 1; // not set to 0 to avoid another search in the database - } - if( UNLIKELY( m_outputLevel <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(),name()); - log << MSG::DEBUG << "Latest heart beat at " << m_latestHeartBeat << endmsg; - } - } - } - if (FSMState() != Gaudi::StateMachine::RUNNING) { - // Temporarily consider the database valid if not running - // (e.g. during initialize). - // Note that the retrieve is done (and must be done) anyway, - // because it is needed by i_getObject(). - return cool::ValidityKeyMax; - } - return m_latestHeartBeat; -} - - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) { - MsgStream log(msgSvc(),name()); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Entering \"getChildNodes\"" << endmsg; - - folders.clear(); - foldersets.clear(); - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - if (database()->existsFolderSet(path)) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "FolderSet \"" << path << "\" exists" << endmsg; - - cool::IFolderSetPtr folderSet = database()->getFolderSet(path); - - std::vector<std::string> fldr_names = folderSet->listFolders(); - std::vector<std::string> fldrset_names = folderSet->listFolderSets(); - - for ( std::vector<std::string>::iterator f = fldr_names.begin(); f != fldr_names.end(); ++f ) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << *f << endmsg; - // Check if folder is tagged with a tag set to load db with. - cool::IFolderPtr folder = database()->getFolder(*f); - if (folder->versioningMode() == cool::FolderVersioning::MULTI_VERSION){ - try{ - folder->resolveTag(tag()); - folders.push_back(f->substr(f->rfind('/')+1)); - } catch (cool::TagRelationNotFound &) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Tag '" << tag() - << "' relation was not found for ': "<< *f << "' folder" << endmsg; - } catch (cool::ReservedHeadTag &) { - //to be ignored: 'HEAD' tag is in every node - folders.push_back(f->substr(f->rfind('/')+1)); - } catch (cool::NodeRelationNotFound &) { - //to be ignored: it means that the tag exists, but it is not in the node '/'. - } catch (coral::AttributeException &) { // FIXME: COOL bug #38422. To be ignored: - //it means that the tag exists, but it is not in the node '/'. - } catch (coral::Exception &e) { - report_exception(log,"got CORAL exception",e); - folders.push_back(f->substr(f->rfind('/')+1)); - } - } else { //add folder if it is single version without tag verification - folders.push_back(f->substr(f->rfind('/')+1)); - } - } - - for ( std::vector<std::string>::iterator f = fldrset_names.begin(); f != fldrset_names.end(); ++f ) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << *f << endmsg; - foldersets.push_back(f->substr(f->rfind('/')+1)); - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) { - log << MSG::DEBUG << "got " << folders.size() << " sub folders" << endmsg; - log << MSG::DEBUG << "got " << foldersets.size() << " sub foldersets" << endmsg; - } - - } else { - // cannot get the sub-nodes of a folder! - return StatusCode::FAILURE; - } - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - m_cache->getSubNodes(path,folders,foldersets); - } else { - // no cache and no db - return StatusCode::FAILURE; - } - } catch ( cool::FolderNotFound &/*e*/) { - //log << MSG::ERROR << e << endmsg; - return StatusCode::FAILURE; - } catch (coral::Exception &e) { - report_exception(log,"got CORAL exception",e); - } - return StatusCode::SUCCESS; - - -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { - - std::vector<std::string> temp; - StatusCode sc = getChildNodes(path, node_names, temp); - if (sc.isSuccess()) - node_names.insert(node_names.end(), temp.begin(), temp.end()); - return sc; - -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBAccessSvc::exists(const std::string &path) { - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - return database()->existsFolderSet(path) || database()->existsFolder(path); - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - return m_cache->hasPath(path); - } - - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - // if we do not have neither DB nor cache, or we got an exception - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBAccessSvc::isFolder(const std::string &path) { - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - return database()->existsFolder(path); - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - return m_cache->isFolder(path); - } - - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - // if we do not have neither DB nor cache, or we got an exception - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBAccessSvc::isFolderSet(const std::string &path) { - - try { - - if (!m_noDB) { // If I have the DB I always use it! - DataBaseOperationLock dbLock(this); - return database()->existsFolderSet(path); - } else if (m_useCache) { - // if no db, but cache, let's assume we know everything is in there - return m_cache->isFolderSet(path); - } - - } catch (coral::Exception &e) { - MsgStream log(msgSvc(),name()); - report_exception(log,"got CORAL exception",e); - } - // if we do not have neither DB nor cache, or we got an exception - return false; -} - -//========================================================================= -// Disconnect from the database. -//========================================================================= -void CondDBAccessSvc::disconnect() { - boost::mutex::scoped_lock busy_lock(m_busy); - if ( database() && database()->isOpen() ) { - if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { - debug() << "Forced disconnect from database (will reconnect automatically)" << endmsg; - } - database()->closeDatabase(); - } else if ( UNLIKELY( msgLevel() <= MSG::DEBUG ) ) { - debug() << "Database already disconnected" << endmsg; - } - i_stopTimeoutChecker(); -} - -//========================================================================= -// Add database name and TAG to the passed vector. -//========================================================================= -void CondDBAccessSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - /// @todo This should be something like - /// <quote> - /// tags.push_back(LHCb::CondDBNameTagPair(database()->dbName(),tag())); - /// </quote> - /// but COOL API does not provide that function yet. (Available since 2.2.0) - - std::string dbName; - // Parsing of COOL connection string to find database name - // - first type: <tech>://<server>;schema=<schema>;dbname=<dbname> - std::string::size_type pos = connectionString().find("dbname="); - if ( std::string::npos != pos ) { - pos += 7; - std::string::size_type pos2 = connectionString().find(';',pos); - if ( std::string::npos != pos2 ) - dbName = connectionString().substr(pos,pos2-pos); - else - dbName = connectionString().substr(pos); - } else { - // - second type: <alias>/<dbname> - pos = connectionString().find_last_of('/'); - if ( std::string::npos != pos ) { - dbName = connectionString().substr(pos+1); - } else { - throw GaudiException("Cannot understand COOL connection string", - "CondDBAccessSvc::defaultTags",StatusCode::FAILURE); - } - } - // If the tag is a "HEAD" tag, I want to show "HEAD" - std::string tagName = tag(); - if (cool::IHvsNode::isHeadTag(tagName)) { - tagName = "HEAD"; - } - - tags.push_back(LHCb::CondDBNameTagPair(dbName,tagName)); - -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec) { - if (!m_useCache) { - MsgStream log(msgSvc(),name()); - log << MSG::ERROR << "Cache not in use: I cannot add a folder to it." << endmsg; - return StatusCode::FAILURE; - } - return m_cache->addFolder(path,descr,spec) ? StatusCode::SUCCESS : StatusCode::FAILURE; -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddFolderSet(const std::string &path, const std::string &descr) { - if (!m_useCache) { - MsgStream log(msgSvc(),name()); - log << MSG::ERROR << "Cache not in use: I cannot add a folder-set to it." << endmsg; - return StatusCode::FAILURE; - } - return m_cache->addFolderSet(path,descr) ? StatusCode::SUCCESS : StatusCode::FAILURE; -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path) { - std::ostringstream _descr; - _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - return cacheAddFolder(path,_descr.str(),CondDB::getXMLStorageSpec()); -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields) { - std::ostringstream _descr; - _descr << " <storage_type=" << std::dec << XML_StorageType << ">"; - cool::RecordSpecification spec; - for (std::set<std::string>::const_iterator f = fields.begin(); f != fields.end(); ++f ){ - spec.extend(*f, cool::StorageType::String16M); - } - return cacheAddFolder(path,_descr.str(),spec); -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const cool::IRecord& payload, cool::ChannelId channel) { - if (!m_useCache) { - MsgStream log(msgSvc(),name()); - log << MSG::ERROR << "Cache not in use: I cannot add an object to it." << endmsg; - return StatusCode::FAILURE; - } - return m_cache->addObject(path,timeToValKey(since),timeToValKey(until),payload,channel) - ? StatusCode::SUCCESS - : StatusCode::FAILURE; -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string &data, cool::ChannelId channel) { - /// @todo this is affected by the evolution in COOL API - cool::Record payload(CondDB::getXMLStorageSpec()); - payload["data"].setValue<cool::String16M>(data); - return cacheAddObject(path,since,until,payload,channel); -} - -//========================================================================= -// -//========================================================================= -StatusCode CondDBAccessSvc::cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::map<std::string,std::string> &data, cool::ChannelId channel) { - cool::RecordSpecification spec; - for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ - spec.extend(d->first,cool::StorageType::String16M); - } - - cool::Record payload(spec); - - for (std::map<std::string,std::string>::const_iterator d = data.begin(); d != data.end(); ++d ){ - payload[d->first].setValue<cool::String16M>(d->second); - } - return cacheAddObject(path,since,until,payload,channel); -} - -//========================================================================= -// -//========================================================================= -void CondDBAccessSvc::clearCache() -{ - if (m_useCache) { - m_cache->clear(); - } -} - -//========================================================================= -// -//========================================================================= -void CondDBAccessSvc::dumpCache() const { - if (m_useCache) m_cache->dump(); -} - -//========================================================================= -// -//========================================================================= -void CondDBAccessSvc::i_generateXMLCatalogFromFolderset(const std::string &path){ - // Use the name of the folderset as catalog name. - std::string::size_type pos = path.rfind('/'); - if ( std::string::npos == pos ) { - pos = 0; // if we cannot find '/' let's take the whole string - } else { - ++pos; - } - std::string folderset_name = path.substr(pos); - - // Get the names of sub-folders and sub-foldersets - std::vector<std::string> fldr_names, fldrset_names; - getChildNodes(path, fldr_names, fldrset_names).ignore(); - - std::string xml; - CondDB::generateXMLCatalog(folderset_name,fldr_names,fldrset_names,xml); - - // Put the data in the cache - if ( ! m_cache->hasPath(path) ) - cacheAddXMLFolder(path); - - // This is needed because we cannot add objects valid for the current event - // to the cache using the ICondDBAccessSvc API. - bool check_enabled = m_cache->setIOVCheck(false); - cacheAddXMLData(path,Gaudi::Time::epoch(),Gaudi::Time::max(),xml,0).ignore(); - m_cache->setIOVCheck(check_enabled); - -} diff --git a/Det/DetCond/src/component/CondDBAccessSvc.h b/Det/DetCond/src/component/CondDBAccessSvc.h deleted file mode 100755 index 34e578470..000000000 --- a/Det/DetCond/src/component/CondDBAccessSvc.h +++ /dev/null @@ -1,506 +0,0 @@ -#ifndef COMPONENT_CONDDBACCESSSVC_H -#define COMPONENT_CONDDBACCESSSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "GaudiKernel/GaudiException.h" -#include "Kernel/ICondDBInfo.h" -#include "DetCond/ICondDBAccessSvc.h" -#include "DetCond/ICondDBReader.h" -#include "DetCond/ICondDBEditor.h" -#include <set> - -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/thread/thread.hpp> -#include <boost/thread/mutex.hpp> -#include <boost/thread/condition.hpp> -#include <boost/thread/thread_time.hpp> - -#include "CoolKernel/IDatabase.h" - -// Forward declarations -template <class TYPE> class SvcFactory; - -class CondDBCache; -class IRndmGenSvc; -class ICOOLConfSvc; - -namespace cool { - class Application; - class RecordSpecification; -} - -/** @class CondDBAccessSvc CondDBAccessSvc.h - * - * Class used as interface to LCG COOL library API. It should expose as less as - * possible COOL internal details. - * - * @author Marco Clemencic - * @date 2005-01-11 - */ - -class CondDBAccessSvc: public extends3<Service, - ICondDBAccessSvc, - ICondDBReader, - ICondDBEditor> { -public: - - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - /// (Version with alphanumeric channel id) - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags ) const; - - // --------- ICondDBEditor implementation - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - StorageType storage = XML, - VersionMode vers = MULTI) const; - - /// Create a CondDB node in the hierarchy (Folder or FolderSet). - virtual StatusCode createNode(const std::string &path, - const std::string &descr, - const std::set<std::string> &fields, - StorageType storage = XML, - VersionMode vers = MULTI) const; - - /// Utility function that simplifies the storage of an XML string. - virtual StatusCode storeXMLData(const std::string &path, const std::string &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; - - /// Utility function that simplifies the storage of a set of XML strings. - virtual StatusCode storeXMLData(const std::string &path, const std::map<std::string,std::string> &data, - const Gaudi::Time &since, const Gaudi::Time &until, cool::ChannelId channel = 0) const; - - /// Tag the given leaf node with the given tag-name. - virtual StatusCode tagLeafNode(const std::string &path, const std::string &tagName, - const std::string &description = ""); - - /// Tag the given inner node with the given tag-name, recursively tagging the head - /// of child nodes with automatically generated tag-names. - virtual StatusCode recursiveTag(const std::string &path, const std::string &tagName, - const std::string &description = ""); - - // --------- ICondDBAccessSvc implementation - - /// Used to obtain direct access to the database. - virtual cool::IDatabasePtr& database() { return m_db; } - - /// Convert from Gaudi::Time class to cool::ValidityKey. - virtual cool::ValidityKey timeToValKey(const Gaudi::Time &time) const; - - /// Convert from cool::ValidityKey to Gaudi::Time class. - virtual Gaudi::Time valKeyToTime(const cool::ValidityKey &key) const; - - /// Return the currently set TAG to use. - virtual const std::string &tag() const; - - /// Set the TAG to use. - virtual StatusCode setTag(const std::string &_tag); - - /// Return the connection string used to connect to the database. - virtual const std::string &connectionString() const; - - /// Add a folder to the cache (bypass the DB) - virtual StatusCode cacheAddFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec); - - /// Add a folder-set to the cache (bypass the DB) - virtual StatusCode cacheAddFolderSet(const std::string &path, const std::string &descr); - - /// Add a folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path); - - /// Add an XML folder to the cache (bypass the DB) - virtual StatusCode cacheAddXMLFolder(const std::string &path, const std::set<std::string> &fields); - - ///Add an object to the cache (bypass the DB) - virtual StatusCode cacheAddObject(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const cool::IRecord& payload, cool::ChannelId channel = 0); - - ///Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::string& data, cool::ChannelId channel = 0); - - /// Add an XML object to the cache (bypass the DB) - virtual StatusCode cacheAddXMLData(const std::string &path, const Gaudi::Time &since, const Gaudi::Time &until, - const std::map<std::string,std::string> &data, cool::ChannelId channel = 0); - - /// Clear the cache - virtual void clearCache(); - - /// Dump the cache (debug) - virtual void dumpCache() const; - -protected: - /// Standard constructor - CondDBAccessSvc(const std::string& name, ISvcLocator* svcloc); - - virtual ~CondDBAccessSvc( ); ///< Destructor - -protected: - // Properties - - /// Property CondDBAccessSvc.ConnectionString: full connection string to open database access. - /// Format is: "<BackEnd>://<HostName>;schema=<Schema>;dbname=<Database>;[user=<User>;][password=<Password>;]" - /// or "<HostAlias>/<Database>". - std::string m_connectionString; - -private: - /// Property CondDBAccessSvc.DefaultTAG: which tag to use if none is specified - std::string m_dbTAG; - - /** Property CondDBAccessSvc.UseCache: store the retrieved informations into a cache for faster - later access. */ - bool m_useCache; - - /// Property CondDBAccessSvc.CacheLowLevel: minimum fill of the cache. - size_t m_cacheLL; - - /// Property CondDBAccessSvc.CacheHighLevel: maximum fill of the cache. - size_t m_cacheHL; - - /// Property CondDBAccessSvc.NoDB: do not use the database (cache must be on). - bool m_noDB; - - /// Property CondDBAccessSvc.ReadOnly: open the database as read-only (default: true). - bool m_readonly; - - /// Property CondDBAccessSvc.CheckTAGTrials: Number of times to retry the check on the tag (default = 1). - int m_checkTagTrials; - - /// Property CondDBAccessSvc.CheckTAGTimeOut: Seconds to sleep between one trial and the following (default = 60). - int m_checkTagTimeOut; - - /// Pointer to the service initializing COOL/CORAL. - ICOOLConfSvc *m_coolConfSvc; - - /// Shared pointer to the COOL database instance - cool::IDatabasePtr m_db; - - /// Shared pointer to the COOL database instance - cool::IFolderSetPtr m_rootFolderSet; - - /// Pointer to the cache manager - CondDBCache *m_cache; - - /// Pointer to the random generator service - IRndmGenSvc *m_rndmSvc; - - /// Lazy connection flag. - /// If true (the default), the connection to (lazy = connect only when needed). - bool m_lazyConnect; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Path in the condition database (not in the transient store) to be used as - /// heart-beat marker. - /// The latest update of the condition specified give information about when - /// the replica was last updated: We cannot guarantee that the database is more - /// "up to date" then the "since" field of the latest object in the heart-beat - /// condition. - std::string m_heartBeatCondition; - - /// Latest know update of the database ("since" field of the latest heart-beat condition). - /// Initialized to 0, if no heart-beat condition is requested, it is set to - /// cool::ValidityKeyMax, otherwise, during the first access to the DB, the - /// object valid until ValidityKeyMax is retrieved and its "since" field is - /// recorded in this variable. - /// When disconnected from the database, it is reset to 0 to force a re-check. - cool::ValidityKey m_latestHeartBeat; - - // ---------------------------------------------- - // ---------- Private Member Functions ---------- - // ---------------------------------------------- - - /// Connect to the COOL database. It sets 'm_db'. - StatusCode i_initializeConnection(); - - /// Connect to the COOL database. It sets 'm_db'. - StatusCode i_openConnection(); - - /// Internal method to retrieve an object. - StatusCode i_getObject(const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, - bool use_numeric_chid, - cool::ChannelId channel, const std::string &channelstr); - - /// Internal method to retrieve an object from the database. - /// If the cache is activated, the result is copied there. - StatusCode i_getObjectFromDB(const std::string &path, const cool::ValidityKey &when, - DataPtr &data, - std::string &descr, cool::ValidityKey &since, cool::ValidityKey &until, - bool use_numeric_chid, - cool::ChannelId channel, const std::string &channelstr); - - /// Internal method to get the list of IOVs in a range. - /// @see ICondDBReader::getIOVs - IOVList i_getIOVsFromDB(const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - - void i_generateXMLCatalogFromFolderset(const std::string &path); - - /// Connect to the COOL database. It sets 'm_db'. - StatusCode i_validateDefaultTag(); - - /// Check if the TAG set exists in the DB. - inline StatusCode i_checkTag() const { return i_checkTag(tag()); } - - /// Check if the given TAG exists in the DB. - StatusCode i_checkTag(const std::string &tag) const; - - /// Generate a tag name that do not create conflicts in the DB. - /// Tagnames generated by this method will start with "_auto_". - /// If base value is passed to the method, the result will have - /// a "_auto_`base`-" prefix. - std::string generateUniqueTagName(const std::string &base, - const std::set<std::string> &reserved) const; - - /// Function used by recursiveTag to do the real work. - StatusCode i_recursiveTag(const std::string &path, - const std::string &base, - const std::string &description, - const std::string &tagName, - std::set<std::string> &reserved); - - - /// Return the value of m_latestHeartBeat. - /// The value is retrieved from the database when requested the first time - /// in the RUNNING state. - const cool::ValidityKey &i_latestHeartBeat(); - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBAccessSvc>; - - /// AttributeListSpecification used to sore XML strings - static std::unique_ptr<cool::RecordSpecification> s_XMLstorageSpec; - - /// Parameter controlling the granularity of the queries to the conditions database (in time units). - /// - /// When different from 0, instead of retrieving the only condition valid for the requested event time, - /// we will retrieve all the conditions valid for a range around the event time, rounded by the - /// granularity. - /// - /// For example, with granularity set to 1h and the event time 16:18:08, all the conditions valid for the - /// range 16:00:00 to 17:00:00 will be retrieved. - /// - /// \b Note: if the cache is not enabled the parameter has no effect. - cool::ValidityKey m_queryGranularity; - - // ------------------------------------- - // ---------- Time Out Thread ---------- - // ------------------------------------- - - /// Property CondDBAccessSvc.ConnectionTimeOut: How many seconds to keep the connection to the DB open after the - /// last access (default = 120, 0 means never). The connection will be started again if a new operation is performed. - int m_connectionTimeOutProp; - boost::posix_time::time_duration m_connectionTimeOut; - - /// Mutex to avoid conflicts between the main thread and the thread trying to close the connection. - boost::mutex m_busy; - - /// The time of last access. - boost::system_time m_lastAccess; - - /// Mutex to protect the last access time. - boost::mutex m_lastAccessMutex; - - /// Pointer to the second thread. - std::unique_ptr<boost::thread> m_timeOutCheckerThread; - - /// Function to set the last access time to "now". - inline void touchLastAccess() - { - boost::mutex::scoped_lock myLock(m_lastAccessMutex); - m_lastAccess = boost::get_system_time(); - } - - /// Get the last access time. - inline const boost::system_time &lastAccess() const - { - return m_lastAccess; - } - - /// Start the timeout checker thread, if requested. - inline void i_startTimeoutChecker() { - if ( UNLIKELY( (!m_timeOutCheckerThread) - && (!m_connectionTimeOut.is_pos_infinity()) ) ) { - m_timeOutCheckerThread.reset( new boost::thread(TimeOutChecker{this}) ); - } - } - - /// Stop the timeout checker thread if running. - inline void i_stopTimeoutChecker() { - if ( LIKELY( NULL != m_timeOutCheckerThread.get() ) ) { - m_timeOutCheckerThread->interrupt(); // tell the thread to stop - m_timeOutCheckerThread->join(); // wait for it - m_timeOutCheckerThread.reset(); // delete it - } - } - - /// Class executed in a separate thread to disconnect from the database if - /// a time-out is reached. - class TimeOutChecker - { - /// Pointer to the CondDBAccessSvc, used to acquire operation locks and - /// access parameters. - CondDBAccessSvc *m_owner; - /// Cached MsgStream to report messages. - MsgStream log; - - public: - TimeOutChecker(CondDBAccessSvc *owner): - m_owner(owner), - log(m_owner->msgSvc(),m_owner->name()+".TimeOutChecker") - { - } - - void operator () () - { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Starting" << endmsg; - - boost::system_time last_access = m_owner->lastAccess(); - - // set initial check time - boost::system_time next_check = last_access + m_owner->m_connectionTimeOut; - - try { - // enter infinite loop - while (true) { - // Wait until the next check point time is reached. - // An early exit must be triggered by a call to this->interrupt(), which - // will produce an exception during the sleep. - boost::thread::sleep(next_check); - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Time-out reached (" << next_check << ")" << endmsg; - - boost::mutex::scoped_lock busy_lock(m_owner->m_busy); - - if ( last_access == m_owner->lastAccess() ) { // no further accesses - - if ( m_owner->database()->isOpen() ) { // close the database - log << MSG::INFO << "Disconnect from database after being idle for " - << m_owner->m_connectionTimeOut.total_seconds() - << "s (will reconnect if needed)"<< endmsg; - m_owner->database()->closeDatabase(); - // reset the latest heart beat because it may be different the next time - // we connect to the DB - if (!m_owner->m_heartBeatCondition.empty()) m_owner->m_latestHeartBeat = 0; - } - - // schedule the next check for now + dt (seems a good estimate) - next_check = boost::get_system_time() + m_owner->m_connectionTimeOut; - - } else { - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Wait more" << endmsg; - - // schedule the next check for last_access + dt - next_check = last_access = m_owner->lastAccess(); - next_check += m_owner->m_connectionTimeOut; - } - } - } - // Ignore the exception since it is used only to exit from the loop. - catch (boost::thread_interrupted&) {} - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Stopping" << endmsg; - } - }; - - class DataBaseOperationLock - { - CondDBAccessSvc *m_owner; - MsgStream log; - boost::mutex::scoped_lock busy_lock; - public: - DataBaseOperationLock(const CondDBAccessSvc *owner): - m_owner(const_cast<CondDBAccessSvc*>(owner)), - log(m_owner->msgSvc(),m_owner->name()+".DataBaseOperationLock"), - busy_lock(m_owner->m_busy) // lock the access to the db - { - // If the database has not been instantiated yet, we may be using - // lazy connection and we have to connect now. - if (!m_owner->m_db) { - // we have to release the lock because i_initializeConnection - // needs to lock the DB - busy_lock.unlock(); - StatusCode sc = m_owner->i_initializeConnection(); - busy_lock.lock(); - if (! sc.isSuccess()) - throw GaudiException("Cannot initialize connection", - "DataBaseOperationLock::DataBaseOperationLock", - sc); - } - if (!m_owner->m_db->isOpen()){ - log << MSG::INFO << "Connecting to database" << endmsg; - m_owner->m_db->openDatabase(); // ensure that the db is open - m_owner->i_startTimeoutChecker(); // ensure that the timeout checker is running - } - } - - ~DataBaseOperationLock() - { - m_owner->touchLastAccess(); // update last access time - } - }; - - friend class TimeOutChecker; - friend class DataBaseOperationLock; - -}; -#endif // COMPONENT_CONDDBACCESSSVC_H diff --git a/Det/DetCond/src/component/CondDBCache.cpp b/Det/DetCond/src/component/CondDBCache.cpp deleted file mode 100755 index 2e6e94cc4..000000000 --- a/Det/DetCond/src/component/CondDBCache.cpp +++ /dev/null @@ -1,444 +0,0 @@ -// Include files -#include "CondDBCache.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBCache -// -// 2005-06-13 : Marco Clemencic -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBCache::CondDBCache(const MsgStream& log, size_t highLvl, size_t lowLvl): - m_highLvl(highLvl), m_lowLvl(lowLvl), - m_level(0), - m_log(log), - m_lastRequestedTime(0), m_checkLastReqTime(true), - m_silentConflicts(false) -{ - if ( highLvl == 0 ) { - m_log << MSG::WARNING << "High level == 0 : forced to 100" << endmsg; - m_highLvl = 100; - } - if ( highLvl <= lowLvl ) { - m_log << MSG::WARNING << "High level <= low level : low level forced to 0" << endmsg; - m_lowLvl = 0; - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Cache initialized with high/low levels = " << - m_highLvl << '/' << m_lowLvl << endmsg; -} -//============================================================================= -// Destructor -//============================================================================= -CondDBCache::~CondDBCache() { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Cache deleted. Level was = " << m_level << endmsg; -} - -//========================================================================= -// Add a new item to the cache -//========================================================================= -bool CondDBCache::insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel) { - // increment object count and check the limit - if ( m_level >= highLevel() ){ - // needs clean up - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Level above max threshold" << endmsg; - clean_up(); - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Insert Folder '" << folder->fullPath() - << "', IOV : " << obj.since() << " - " << obj.until() - << ", channel : " << channel << endmsg; - - FolderIdType id(folder->fullPath()); - StorageType::iterator f = m_cache.find(id); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(id, CondFolder(folder))).first; - // Fill the map of channel names. - std::map<cool::ChannelId,std::string>::const_iterator p; - std::map<cool::ChannelId,std::string> ch_names = folder->listChannelsWithNames(); - for (p = ch_names.begin(); p != ch_names.end(); ++p) { - f->second.channelNames[p->second] = p->first; - } - } else { - if (f->second.items[channel].end() != f->second.conflict(obj.since(), obj.until(), channel)) { - const MSG::Level lvl = (m_silentConflicts ? MSG::DEBUG : MSG::WARNING); - m_log << lvl << "Conflict found: item not inserted" << endmsg; - ItemListType::iterator i = f->second.conflict(obj.since(), obj.until(), channel); - m_log << lvl << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; - return false; - } - } - // for vectors - // f->second.items.push_back(CondItem(&f->second,obj)); - // for lists - ItemListType &items = f->second.items[channel]; - ItemListType::iterator pos = items.begin(); - while (pos != items.end() && pos->iov.first < obj.since()) { - ++pos; - } - items.insert(pos, CondItem(&f->second, obj)); - - ++m_level; - return true; -} - -//========================================================================= -// Add a new folder using the given specification and description. (Bypass the real DB) -//========================================================================= -bool CondDBCache::addFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec) { - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; - } - return true; -} -bool CondDBCache::addFolder(const std::string &path, const std::string &descr, - const cool::IRecordSpecification& spec, - const std::map<cool::ChannelId,std::string>& ch_names) { - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(path,CondFolder(descr,spec))).first; - // Fill the map of channel names. - std::map<cool::ChannelId,std::string>::const_iterator p; - for (p = ch_names.begin(); p != ch_names.end(); ++p) { - f->second.channelNames[p->second] = p->first; - } - } - return true; -} - -//========================================================================= -// Add a new folder using the given specification and description. (Bypass the real DB) -//========================================================================= -bool CondDBCache::addFolderSet(const std::string &path, const std::string &descr) { - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - f = m_cache.insert(StorageType::value_type(path,CondFolder(descr))).first; - } - return true; -} - -//========================================================================= -// Add a new object to a given folder -//========================================================================= -bool CondDBCache::addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before) { - // new objects cannot be already valid. check it! - if ( IOVCheck() && (m_lastRequestedTime != 0) - && ( since <= m_lastRequestedTime && m_lastRequestedTime < until ) ) { - m_log << (m_silentConflicts ? MSG::DEBUG : MSG::WARNING) - << "New item IOV is compatible with last requested time:" - << " not allowed to avoid inconsistencies" << endmsg; - return false; - } - // increment object count and check the limit - if ( m_level >= highLevel() ){ - // needs clean up - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Level above max threshold" << endmsg; - clean_up(); - } - StorageType::iterator f = m_cache.find(path); - if (f == m_cache.end()){ - m_log << MSG::WARNING << "Could not find the folder: object not added" << endmsg; - return false; - } - if (!f->second.spec) { // no specification means FolderSet - m_log << MSG::WARNING << '"' << path << '"' << " is a FolderSet: object not added" << endmsg; - return false; - } - - // when bypassing the DB, the conflicts must be solved - /* - if (f->second.conflict(since,until) != f->second.items.end()) { - m_log << MSG::WARNING << "Conflict found: item not inserted" << endmsg; - return false; - } - */ - // **** COOL single version style --> [x;+inf] + [y(>x);z] = [x;y], [y;z] - // scan for conflicting items (from the end) - ItemListType::iterator i = f->second.conflict(since,until,channel); - if ( i != f->second.items[channel].end() ) { // conflict found - if ( i->iov.second == cool::ValidityKeyMax && i->iov.first < since ) { - // solvable conflict - if (iov_before) *iov_before = i->iov; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Solvable conflict found: old until = " << i->iov.second << endmsg; - i->iov.second = since; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " new until = " << i->iov.second << endmsg; - } else { - // conflict not solvable - m_log << MSG::WARNING << "Unsolvable conflict found: item not inserted" << endmsg; - return false; - } - } - // for vectors - // f->second.items.push_back(CondItem(&f->second,since,until,rec)); - // for lists - f->second.items[channel].push_front(CondItem(&f->second,since,until,rec)); - ++m_level; - return true; -} - -//========================================================================= -// Get data from given path and valid at given time -//========================================================================= -bool CondDBCache::get(const std::string &path, const cool::ValidityKey &when, - const cool::ChannelId &channel, - cool::ValidityKey &since, cool::ValidityKey &until, - std::string &descr, ICondDBReader::DataPtr &payload ) { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Request Folder '" << path - << "' @ " << when << " channel " << channel; - m_lastRequestedTime = when; - StorageType::iterator folder = m_cache.find(path); - if (folder != m_cache.end()) { - if ( ! folder->second.spec ) { - // It's a FolderSet! no objects inside - since = cool::ValidityKeyMin; - until = cool::ValidityKeyMax; - descr = folder->second.description; - payload.reset(); - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << " FOUND (FolderSet)" << endmsg; - return true; - } - ItemListType::iterator i = folder->second.find(when,channel); - if ( i != folder->second.items[channel].end() ) { - since = i->iov.first; - until = i->iov.second; - descr = folder->second.description; - payload = i->data; - //i->score += 1.0; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << " FOUND" << endmsg; - return true; - } - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << " MISSING" << endmsg; - return false; -} -//========================================================================= -// -//========================================================================= -bool CondDBCache::getChannelId(const std::string &path,const std::string &name, - cool::ChannelId &channel) const { - StorageType::const_iterator f = m_cache.find(path); - if ( m_cache.end() != f ) { - CondFolder::ChannelNamesMapType::const_iterator id = f->second.channelNames.find(name); - if ( f->second.channelNames.end() != id ) { - channel = id->second; - return true; - } - } - channel = 0; - return false; -} -//========================================================================= -// -//========================================================================= -void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets) { - - folders.clear(); - foldersets.clear(); - - StorageType::iterator f; - for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { - const std::string &p = f->first; - if ( p.find(path) == 0 // the string must start with path - && ( p.size() > path.size() ) // it must contain something more than the path - && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name - if ( f->second.spec.get() ) { - // this is a folder - folders.push_back(p.substr(path.size())); - } else { - // this is a folderset - foldersets.push_back(p.substr(path.size())); - } - } - } -} -//========================================================================= -// -//========================================================================= -void CondDBCache::getSubNodes (const std::string &path, std::vector<std::string> &node_names) { - // @todo: could be implemented as getSubNodes(path,node_names,node_names); - - node_names.clear(); - - StorageType::iterator f; - for ( f = m_cache.begin(); f != m_cache.end(); ++f ) { - const std::string &p = f->first; - if ( p.find(path) == 0 // the string must start with path - && ( p.size() > path.size() ) // it must contain something more than the path - && ( p.find('/',path.size()+1) == p.npos ) ) { // and I should have only one extra name - node_names.push_back(p.substr(path.size())); - } - } -} -//========================================================================= -// Remove unused entries from the cache -//========================================================================= - -void CondDBCache::clean_up(){ - typedef std::vector<std::pair<float,std::pair<CondDBCache::CondFolder*,std::pair<cool::ValidityKey,cool::ChannelId> > > > - _vec_t; - _vec_t all_items; - float score = 0; - size_t old_level = level(); - - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) { - m_log << MSG::DEBUG << "Start cleaning up (level = " << level() << ")" << endmsg; - m_log << MSG::DEBUG << " Last requested time = " << m_lastRequestedTime << endmsg; - } - // collect all items info in order - StorageType::iterator folder; - for ( folder = m_cache.begin() ; folder != m_cache.end() ; ++folder ) { - - if ( ! folder->second.spec ) continue; // It's a FolderSet! no objects inside: skip it - - CondFolder::StorageType::iterator ch; - ItemListType::iterator i; - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Folder " << folder->first << endmsg; - for ( ch = folder->second.items.begin(); ch != folder->second.items.end() ; ++ch ){ - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " channel : " << ch->first << endmsg; - for ( i = ch->second.begin(); i != ch->second.end() ; ++i ){ - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " IOV : " << i->iov.first << " - " << i->iov.second << endmsg; - if ( ! (i->iov.first <= m_lastRequestedTime && i->iov.second > m_lastRequestedTime) ) { - if ( m_lastRequestedTime < i->iov.first ) { - score = (float)m_lastRequestedTime - i->iov.first; - } else { - score = (float)i->iov.second - m_lastRequestedTime; - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " score = " << score << endmsg; - all_items.push_back( - std::make_pair(score, - std::make_pair(&folder->second, - std::make_pair(i->iov.first,ch->first)))); - // i->score = 0; - } - } - } - } - std::sort(all_items.begin(),all_items.end()); - - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Remove items" << endmsg; - // remove items - _vec_t::iterator it = all_items.begin(); - while ( m_level > m_lowLvl && it != all_items.end()) { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Remove item since " << it->second.second.first << - " channel " << it->second.second.second << - // " from '" << it->second.first->path << "'" << - " (score =" << it->first << ")" << endmsg; - // folder when - it->second.first->erase(it->second.second.first,it->second.second.second); - --m_level; - ++it; - } - - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Remove empty folders:" << endmsg; - // remove empty folders - std::vector<FolderIdType> to_remove; - for ( StorageType::iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { - if (!i->second.sticky && i->second.empty()) { // delete folders which are empty but not sticky - to_remove.push_back(i->first); - } - } - for ( std::vector<FolderIdType>::iterator i = to_remove.begin(); i != to_remove.end(); ++i ) { - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << " " << *i << endmsg; - m_cache.erase(m_cache.find(*i)); - } - if( UNLIKELY( m_log.level() <= MSG::DEBUG ) ) - m_log << MSG::DEBUG << "Clean up finished (level = " << level() << ")" << endmsg; - if ( UNLIKELY(old_level == level()) ) { - m_log << MSG::WARNING << "No item removed: I increase high threshold" << endmsg; - setHighLevel(highLevel()+(highLevel()-lowLevel())/10+1); - m_log << MSG::WARNING << "New threshold = " << highLevel() << endmsg; - } -} - -//========================================================================= -// Check if an entry for the give path+time is in the cache -//========================================================================= -bool CondDBCache::hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel) const { - StorageType::const_iterator folder = m_cache.find(path); - if (folder != m_cache.end()) { - - if ( !folder->second.spec ) return true; // It's a FolderSet! They ignore time - - ItemListType::const_iterator i = folder->second.find(when,channel); - const ItemListType &lst = (*const_cast<CondFolder::StorageType *>(&folder->second.items))[channel]; - return i != lst.end(); - } - return false; -} - -ICondDBReader::IOVList CondDBCache::getIOVs(const std::string & path, const ICondDBReader::IOV & iov, cool::ChannelId channel) -{ - ICondDBReader::IOVList result; - StorageType::const_iterator folder = m_cache.find(path); - if (folder != m_cache.end()) { - if (folder->second.spec) { - // find the first recorded interval which overlaps with requested IOV - ItemListType::const_iterator i = folder->second.conflict(iov.since.ns(), iov.until.ns(), channel); - // marker for the end of IOVs in the cache for the channel - const ItemListType::const_iterator end = folder->second.end(channel); - // we add all the IOVs in the cache starting from the one found until - // we are in the list and the IOV is in the requested range. - for(; i != end && (i->iov.first < static_cast<cool::ValidityKey>(iov.until.ns())); ++i) { - result.push_back(ICondDBReader::IOV(i->iov.first, i->iov.second)); - } - } else { - // it's a FolderSet: IOV is infinite - result.push_back(ICondDBReader::IOV(Gaudi::Time::epoch(), Gaudi::Time::max())); - } - } - return result; -} - -//========================================================================= -// Dump the content of the cache to the message service. -//========================================================================= -void CondDBCache::dump() { - if (m_log.level() > MSG::DEBUG) return; // do not dump outside for non debug - m_log << MSG::DEBUG << "Cache content dump --------------------- BEGIN" << endmsg; - m_log << MSG::DEBUG << " Thresholds (high/low) -> " << m_highLvl << '/' << m_lowLvl << endmsg; - m_log << MSG::DEBUG << " Level = " << level() << endmsg; - for(StorageType::const_iterator i = m_cache.begin(); i != m_cache.end(); ++i ) { - if ( !i->second.spec ) { // It's a FolderSet! They ignore time - m_log << MSG::DEBUG << "FolderSet '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; - continue; - } else { - m_log << MSG::DEBUG << "Folder '" << i->first << "' " << ((i->second.sticky)?"(sticky)":"") << endmsg; - } - - for(CondFolder::StorageType::const_iterator ch = i->second.items.begin(); ch != i->second.items.end(); ++ch) { - m_log << MSG::DEBUG << " Channel " << ch->first << endmsg; - size_t cnt = 0; - for(ItemListType::const_iterator j = ch->second.begin(); j != ch->second.end(); ++j) { - m_log << MSG::DEBUG << " Object " << cnt++ << endmsg; - m_log << MSG::DEBUG << " Score: " << j->score << endmsg; - m_log << MSG::DEBUG << " Validity: " << j->iov.first << " - " << j->iov.second << endmsg; - m_log << MSG::DEBUG << " Data: " << *(j->data)<< endmsg; - } - } - } - m_log << MSG::DEBUG << "Cache content dump --------------------- END" << endmsg; -} -//============================================================================= - diff --git a/Det/DetCond/src/component/CondDBCache.h b/Det/DetCond/src/component/CondDBCache.h deleted file mode 100755 index 0f8ab7994..000000000 --- a/Det/DetCond/src/component/CondDBCache.h +++ /dev/null @@ -1,279 +0,0 @@ -#ifndef COMPONENT_CONDDBCACHE_H -#define COMPONENT_CONDDBCACHE_H 1 - -// Include files -#include <string> -#include <vector> -#include <list> - -#include "GaudiKernel/MsgStream.h" - -#include "GaudiKernel/HashMap.h" - -#include "CoolKernel/types.h" -#include "CoolKernel/pointers.h" -#include "CoolKernel/ValidityKey.h" -#include "CoolKernel/IObject.h" -#include "CoolKernel/IFolder.h" -#include "CoolKernel/IRecord.h" -#include "CoolKernel/Record.h" -#include "CoolKernel/IRecordSpecification.h" -#include "CoolKernel/RecordSpecification.h" - -#include "DetCond/ICondDBReader.h" - -#include <boost/shared_ptr.hpp> - -/** @class CondDBCache CondDBCache.h component/CondDBCache.h - * - * Class used to manage in memory conditions. - * - * @author Marco Clemencic - * @date 2005-06-13 - */ -class CondDBCache { - -public: - - typedef std::pair<cool::ValidityKey,cool::ValidityKey> IOVType; - - //-------------------------------------------------------------------------------- - /// Standard constructor - CondDBCache(const MsgStream& log, size_t highLevel = 100, size_t lowLevel = 10); - - virtual ~CondDBCache( ); ///< Destructor - - /// Add a new data object to the cache. - /// \warning {no check performed} - bool insert(const cool::IFolderPtr &folder,const cool::IObject &obj, const cool::ChannelId &channel = 0); - - /// Shortcut for the regular implementations (for backward compatibility). - inline bool insert(const cool::IFolderPtr &folder,const cool::IObjectPtr &obj, const cool::ChannelId &channel = 0) { - return insert(folder, *obj.get(), channel); - } - - bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec); - bool addFolder(const std::string &path, const std::string &descr, const cool::IRecordSpecification& spec, - const std::map<cool::ChannelId,std::string>& ch_names); - bool addFolderSet(const std::string &path, const std::string &descr); - bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord& rec, const cool::ChannelId &channel, IOVType *iov_before = NULL); - /// (version kept for backward compatibility) - inline bool addObject(const std::string &path, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord& rec, IOVType *iov_before = NULL) - { - return addObject(path,since,until,rec,0,iov_before); - } - - - /// Search an entry in the cache and returns the data string or an empty string if no object is found. - bool get(const std::string &path, const cool::ValidityKey &when, - const cool::ChannelId &channel, - cool::ValidityKey &since, cool::ValidityKey &until, - std::string &descr, ICondDBReader::DataPtr &payload); - - /// Search an entry in the cache and returns the data string or an empty string if no object is found. - /// (version kept for backward compatibility) - inline bool get(const std::string &path, const cool::ValidityKey &when, - cool::ValidityKey &since, cool::ValidityKey &until, - std::string &descr, ICondDBReader::DataPtr &payload) { - return get(path,when,0,since,until,descr,payload); - } - - /// Find the value of the channel id for the given channel name in a folder - /// (if present in the cache). - /// Returns true if the channel name in the folder was found - bool getChannelId(const std::string &path,const std::string &name, - cool::ChannelId &channel) const; - - void getSubNodes(const std::string &path, std::vector<std::string> &node_names); - - void getSubNodes(const std::string &path, std::vector<std::string> &folders, std::vector<std::string> &foldersets); - - /// Remove all entries from the cache; - inline void clear() {m_cache.clear();} - - /// Get the number of items cached. - inline size_t size() const; - - inline void setHighLevel(size_t lvl) { m_highLvl = lvl; } - inline void setLowLevel(size_t lvl) { m_lowLvl = lvl; } - inline size_t highLevel() const { return m_highLvl; } - inline size_t lowLevel() const { return m_lowLvl; } - - inline size_t level() const { return m_level; } - - void clean_up(); - - /// Check if the given path is present in the cache. - inline bool hasPath(const std::string &path) const { return m_cache.count(path) != 0; } - - /// Check if the path is a folderset. - inline bool isFolderSet(const std::string &path) const { - return hasPath(path) && (m_cache.find(path)->second.spec.get() == 0); - } - - /// Check if the path is a folderset. - inline bool isFolder(const std::string &path) const { - return hasPath(path) && (m_cache.find(path)->second.spec.get() != 0); - } - - /// Check if the given path,time pair is present in the cache. - bool hasTime(const std::string &path, const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const; - - /// Return the list of IOVs known for the given path, IOV, channel. - /// @see ICondDBReader::getIOVs - ICondDBReader::IOVList getIOVs(const std::string &path, const ICondDBReader::IOV &iov, cool::ChannelId channel = 0); - - void dump(); - - /// Set the flag to enable the check that the inserted IOVs are not compatible with the latest - /// requested time (needed to avoid that the cache is modified for the current event). - /// @return previous value - bool setIOVCheck(bool enable) - { - bool old = m_checkLastReqTime; - m_checkLastReqTime = enable; - return old; - } - - /// Tell if the check on inserted IOVs is enabled. - bool IOVCheck() { return m_checkLastReqTime; } - - /// Getter for the data member m_silentConflicts. - bool silentConflicts() const { return m_silentConflicts; } - - /// Getter for the data member m_silentConflicts. - void setSilentConflicts(bool value) { m_silentConflicts = value; } - -protected: - -private: - - struct CondFolder; - struct CondItem; - - typedef std::string FolderIdType; - //typedef std::vector<CondItem> ItemListType; - typedef std::list<CondItem> ItemListType; - // typedef std::map<FolderIdType,CondFolder> FolderListType; - typedef GaudiUtils::HashMap<FolderIdType,CondFolder> StorageType; - - /// Internal class used to record IOV+data pairs - struct CondItem { - /// Constructor. - CondItem(CondFolder *myFolder, const cool::IObject &obj): - folder(myFolder),iov(obj.since(),obj.until()), - data(new cool::Record(obj.payload())),score(1.0) {} - CondItem(CondFolder *myFolder, const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::IRecord &rec): - folder(myFolder),iov(since,until), data(new cool::Record(rec)),score(1.0) {} - CondFolder *folder; - IOVType iov; - ICondDBReader::DataPtr data; - float score; - /// Check if the CondItem is valid at the given time. - inline bool valid(const cool::ValidityKey &when) const { - return iov.first <= when && when < iov.second; - } - }; - - /// Internal class used to keep the items common to a given path. - struct CondFolder { - - typedef GaudiUtils::Map<cool::ChannelId,ItemListType> StorageType; - typedef GaudiUtils::HashMap<std::string,cool::ChannelId> ChannelNamesMapType; - - CondFolder(const cool::IFolderPtr &fld): - description(fld->description()), - spec(new cool::RecordSpecification(fld->payloadSpecification())), - sticky(false) {} - CondFolder(const std::string &descr, const cool::IRecordSpecification& new_spec): - description(descr),spec(new cool::RecordSpecification(new_spec)),sticky(true) {} - // for a folderset (FolderSets are identified by missing spec) - CondFolder(const std::string &descr): - description(descr),sticky(true) {} - std::string description; - boost::shared_ptr<cool::IRecordSpecification> spec; - StorageType items; - ChannelNamesMapType channelNames; - bool sticky; - /// Search for the first item in the storage valid at the given time. - inline ItemListType::iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { - ItemListType &lst = items[channel]; - ItemListType::iterator i; - for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} - return i; - } - /// Const version of the search method. - inline ItemListType::const_iterator find(const cool::ValidityKey &when, const cool::ChannelId &channel = 0) const { - const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; - ItemListType::const_iterator i; - for ( i = lst.begin(); i != lst.end() && !i->valid(when) ; ++i ){} - return i; - } - inline ItemListType::iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::ChannelId &channel = 0) { - ItemListType &lst = items[channel]; - ItemListType::iterator i; - for ( i = lst.begin(); i != lst.end() ; ++i ){ - // Given two IOVs a and b, they conflict if the intersection is not empty: - // max(a.s,b.s) < min(a.u,b.u) - if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; - } - return i; - } - inline ItemListType::const_iterator conflict(const cool::ValidityKey &since, const cool::ValidityKey &until, - const cool::ChannelId &channel = 0) const { - const ItemListType &lst = (*const_cast<StorageType *>(&items))[channel]; - ItemListType::const_iterator i; - for ( i = lst.begin(); i != lst.end() ; ++i ){ - if ( std::max(i->iov.first, since) < std::min(i->iov.second, until) ) return i; - } - return i; - } - inline ItemListType::iterator end(const cool::ChannelId &channel = 0) { - return items[channel].end(); - } - inline ItemListType::const_iterator end(const cool::ChannelId &channel = 0) const { - return (*const_cast<StorageType *>(&items))[channel].end(); - } - inline void erase (const cool::ValidityKey &when, const cool::ChannelId &channel = 0) { - items[channel].erase(find(when,channel)); - } - inline bool empty() const { - for (StorageType::const_iterator ch = items.begin(); ch != items.end(); ++ch ) { - if (! ch->second.empty()) return false; - } - return true; - } - - }; - - /// Actual storage - StorageType m_cache; - - size_t m_highLvl; - size_t m_lowLvl; - size_t m_level; - - MsgStream m_log; - - cool::ValidityKey m_lastRequestedTime; - bool m_checkLastReqTime; - - // Do not print warning messages in case of conflicts during the insertion - bool m_silentConflicts; -}; - -inline size_t CondDBCache::size() const { - size_t count = 0; - StorageType::const_iterator folder; - for (folder = m_cache.begin(); folder != m_cache.end(); ++folder) { - for (CondFolder::StorageType::const_iterator ch = folder->second.items.begin(); ch != folder->second.items.end(); ++ch) - count += ch->second.size(); - } - return count; -} - -#endif // COMPONENT_CONDDBCACHE_H diff --git a/Det/DetCond/src/component/CondDBCnvSvc.cpp b/Det/DetCond/src/component/CondDBCnvSvc.cpp deleted file mode 100755 index a192987ee..000000000 --- a/Det/DetCond/src/component/CondDBCnvSvc.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include <string> - -#include "CondDBCnvSvc.h" -#include "DetCond/ICondDBReader.h" - -#include "GaudiKernel/GenericAddress.h" -#include "GaudiKernel/IDetDataSvc.h" -#include "GaudiKernel/IDataProviderSvc.h" -#include "GaudiKernel/MsgStream.h" - -/// Instantiation of a static factory to create instances of this service -DECLARE_SERVICE_FACTORY(CondDBCnvSvc) - -//---------------------------------------------------------------------------- - -/// Constructor -CondDBCnvSvc::CondDBCnvSvc( const std::string& name, ISvcLocator* svc) - : base_class ( name, svc, CONDDB_StorageType ), - m_dbReader(0) -{ - declareProperty( "CondDBReader", m_dbReaderName = "CondDBAccessSvc" ); -} - -//---------------------------------------------------------------------------- - -/// Destructor -CondDBCnvSvc::~CondDBCnvSvc() {} - -//---------------------------------------------------------------------------- - -/// Initialize the service. -StatusCode CondDBCnvSvc::initialize() -{ - - // Before anything else, we need to initialise the base class - StatusCode sc = base_class::initialize(); - if ( !sc.isSuccess() ) return sc; - - // Now we can get a handle to the MessageSvc - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Specific initialization starting" << endmsg; - - // Locate the Database Access Service - sc = service(m_dbReaderName,m_dbReader,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << m_dbReaderName << endmsg; - return sc; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved " << m_dbReaderName << endmsg; - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Specific initialization completed" << endmsg; - return sc; -} - -//---------------------------------------------------------------------------- - -/// Finalize the service. -StatusCode CondDBCnvSvc::finalize() -{ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalizing" << endmsg; - if (m_dbReader) m_dbReader->release(); - return base_class::finalize(); -} - -//---------------------------------------------------------------------------- - -/// Create an address using explicit arguments to identify a single object. -/// Par[0] is folder name in the CondDB. -/// Par[1] is entry name in the string (which may contain many conditions, -/// for instance in the case of XML files with more than one element). -StatusCode CondDBCnvSvc::createAddress( long svc_type, - const CLID& clid, - const std::string* par, - const unsigned long* ipar, - IOpaqueAddress*& refpAddress ) { - - // First check that requested address is of type CONDDB_StorageType - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering createAddress" << endmsg; - if ( svc_type!= CONDDB_StorageType ) { - log << MSG::ERROR - << "Cannot create addresses of type " << (int)svc_type - << " which is different from " << (int)CONDDB_StorageType - << endmsg; - return StatusCode::FAILURE; - } - - // Par[0] is folder name in the CondDB. - std::string folderName = par[0]; - - // Par[1] is entry name in the string (which may contain many conditions, - // for instance in the case of XML files with more than one element). - std::string entryName = par[1]; - - // iPar[0] is the cool::ChannelId - unsigned long channelId = ipar[0]; - - // Now create the address - refpAddress = new GenericAddress( CONDDB_StorageType, - clid, - folderName, - entryName, - channelId ); - return StatusCode::SUCCESS; - -} - -//---------------------------------------------------------------------------- - -/// Retrieve converter from list -IConverter* CondDBCnvSvc::converter(const CLID& clid) { - IConverter* cnv = 0; - cnv = ConversionSvc::converter(clid); - if ( cnv ) { - return cnv; - } - else { - return ConversionSvc::converter(CLID_Any); - } -} - -//---------------------------------------------------------------------------- -// Implementation of ICondDBReader -StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) -{ - return m_dbReader->getObject(path,when,data,descr,since,until,channel); -} - -StatusCode CondDBCnvSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) -{ - return m_dbReader->getObject(path,when,data,descr,since,until,channel); -} - -StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) -{ - return m_dbReader->getChildNodes(path,node_names); -} - -StatusCode CondDBCnvSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) -{ - return m_dbReader->getChildNodes(path,folders,foldersets); -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBCnvSvc::exists(const std::string &path) { - return m_dbReader->exists(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBCnvSvc::isFolder(const std::string &path) { - return m_dbReader->isFolder(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBCnvSvc::isFolderSet(const std::string &path) { - return m_dbReader->isFolder(path); -} - -void CondDBCnvSvc::disconnect() { - if(m_dbReader) - m_dbReader->disconnect(); -} - -ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return m_dbReader->getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBCnvSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return m_dbReader->getIOVs(path, iov, channel); -} - -void CondDBCnvSvc::defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const -{ - tags.clear(); - m_dbReader->defaultTags(tags); -} - diff --git a/Det/DetCond/src/component/CondDBCnvSvc.h b/Det/DetCond/src/component/CondDBCnvSvc.h deleted file mode 100755 index 88430fd0a..000000000 --- a/Det/DetCond/src/component/CondDBCnvSvc.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef DETCOND_CONDDBCNVSVC_H -#define DETCOND_CONDDBCNVSVC_H 1 - -/// Include files -#include "GaudiKernel/ConversionSvc.h" - -#include "DetCond/ICondDBReader.h" - -/// Forward and external declarations -template <class TYPE> class SvcFactory; -class IDetDataSvc; -class IOpaqueAddress; - -///--------------------------------------------------------------------------- -/** @class CondDBCnvSvc CondDBCnvSvc.h - - A conversion service for CERN-IT COOL (ex. CondDB) persistency. - Allows to create and update condition data objects (i.e. DataObjects - implementing IValidity). - - @author Marco Clemencic - @date November 2004 -*///-------------------------------------------------------------------------- - -class CondDBCnvSvc : public extends1<ConversionSvc, ICondDBReader> { - - /// Only factories can access protected constructors - friend class SvcFactory<CondDBCnvSvc>; - -protected: - - /// Constructor - CondDBCnvSvc( const std::string& name, ISvcLocator* svc ); - - /// Destructor - virtual ~CondDBCnvSvc(); - -public: - - // Overloaded from ConversionSvc - - /// Initialize the service - virtual StatusCode initialize(); - - /// Finalize the service - virtual StatusCode finalize(); - - using ConversionSvc::createAddress; - /// Create an address using explicit arguments to identify a single object. - virtual StatusCode createAddress (long svc_type, - const CLID& clid, - const std::string* par, - const unsigned long* ip, - IOpaqueAddress*& refpAddress ); - -public: - - /// Retrieve converter from list - virtual IConverter* converter(const CLID& clid); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - -private: - - /// List of all the names of the known databases. It is filled via the option - /// CondDBCnvSvc.CondDBReader. If none is given, "CondDBAccessSvc" is used. - std::string m_dbReaderName; - - /// Handles to the database Access services - ICondDBReader* m_dbReader; - -protected: - -}; - -#endif // DETCOND_CONDITIONSDBCNVSVC_H - - diff --git a/Det/DetCond/src/component/CondDBCommon.cpp b/Det/DetCond/src/component/CondDBCommon.cpp deleted file mode 100755 index c0fbf40bb..000000000 --- a/Det/DetCond/src/component/CondDBCommon.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "CondDBCommon.h" - -#include <sstream> - -#include "CoolKernel/RecordSpecification.h" -#include "CoolKernel/Record.h" -#include "CoolKernel/StorageType.h" - -static std::unique_ptr<cool::RecordSpecification> s_XMLStorageSpec{}; - -namespace CondDB { - -const cool::RecordSpecification& getXMLStorageSpec() { - if ( s_XMLStorageSpec.get() == NULL){ - // attribute list spec template - s_XMLStorageSpec = std::unique_ptr<cool::RecordSpecification>(new cool::RecordSpecification()); - s_XMLStorageSpec->extend("data", cool::StorageType::String16M); - } - return *s_XMLStorageSpec; -} - -namespace { - inline bool ends_with(const std::string& s, const std::string &suff) { - const auto count = suff.size(); - const auto size = s.size(); - return (size >= count) && - (s.compare(size - count, count, suff) == 0); - } -} - -void generateXMLCatalog(const std::string &name, - const std::vector<std::string> &fldrs, - const std::vector<std::string> &fldrsets, - std::string &data) { - std::ostringstream xml; // buffer for the XML - - // XML header, root element and catalog initial tag - xml << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" - << "<!DOCTYPE DDDB SYSTEM \"conddb:/DTD/structure.dtd\">" - << "<DDDB><catalog name=\"" << name << "\">"; - - // sub-folders are considered as container of conditions - std::vector<std::string>::const_iterator f; - for (const auto& f: fldrs) { - // Ignore folders with the .xml extension. - // We never used .xml for Online conditions and after the Hlt1/Hlt2 split - // we need to avoid automatic mapping for the .xml files. - if (!ends_with(f, ".xml")) { - xml << "<conditionref href=\"" << name << '/' << f << "\"/>"; - } - } - // sub-foldersets are considered as catalogs - for (const auto& f: fldrsets) { - xml << "<catalogref href=\"" << name << '/' << f << "\"/>"; - } - // catalog and root element final tag - xml << "</catalog></DDDB>"; - - data = xml.str(); -} - -StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, - ICondDBReader::DataPtr &payload){ - // get the list of subnodes - std::vector<std::string> folders, foldersets; - StatusCode sc = reader->getChildNodes(path,folders,foldersets); - if (sc.isFailure()) return sc; - - // extract the name of the folderset - std::string::size_type pos = path.rfind('/'); - std::string name; - if ( std::string::npos != pos ) { - name = path.substr(pos+1); - } else { - name = path; - } - - // generate the XML catalog - std::string xml; - generateXMLCatalog(name,folders,foldersets,xml); - - // prepare new payload - cool::Record *rec = new cool::Record(getXMLStorageSpec()); - (*rec)["data"].setValue<cool::String16M>(xml); - payload.reset(rec); - - return sc; -} - -} diff --git a/Det/DetCond/src/component/CondDBCommon.h b/Det/DetCond/src/component/CondDBCommon.h deleted file mode 100755 index 476f26811..000000000 --- a/Det/DetCond/src/component/CondDBCommon.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CONDDBCOMMON_H_ -#define CONDDBCOMMON_H_ - -#include <string> -#include <vector> -#include "DetCond/ICondDBReader.h" - -// forward declaration -namespace cool{ - class RecordSpecification; -} - -/** @file Utility functions shared among DetCond components. - * - * @author Marco Clemencic - */ -namespace CondDB { - void generateXMLCatalog(const std::string &name, - const std::vector<std::string> &fldrs, - const std::vector<std::string> &fldrsets, - std::string &data); - - StatusCode generateXMLCatalog(ICondDBReader *reader, const std::string &path, - ICondDBReader::DataPtr &data); - - const cool::RecordSpecification& getXMLStorageSpec(); -} - -#endif /*CONDDBCOMMON_H_*/ diff --git a/Det/DetCond/src/component/CondDBDQScanner.cpp b/Det/DetCond/src/component/CondDBDQScanner.cpp deleted file mode 100644 index 48cdd8556..000000000 --- a/Det/DetCond/src/component/CondDBDQScanner.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// Include files - -// From Gaudi -#include "GaudiKernel/IConverter.h" -#include "GaudiKernel/IAddressCreator.h" -#include "GaudiKernel/IOpaqueAddress.h" - -#include "CoolKernel/IRecord.h" -#include "CoolKernel/RecordException.h" - -// From LHCb -#include "DetCond/ICondDBReader.h" -#include "DetDesc/Condition.h" - -// local -#include "CondDBDQScanner.h" -#include "RelyConverter.h" - -// ---------------------------------------------------------------------------- -// Implementation file for class: CondDBDQScanner -// -// 04/11/2011: Marco Clemencic -// ---------------------------------------------------------------------------- -DECLARE_TOOL_FACTORY(CondDBDQScanner) - -// ============================================================================ -// Standard constructor, initializes variables -// ============================================================================ -CondDBDQScanner::CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent) - : base_class(type, name, parent) -{ - - declareProperty("ConditionPath", - m_condPath = "/Conditions/DQ/Flags", - "Path in the Conditions Database where to find the Data " - "Quality condition."); - - declareProperty("CondDBReader", - m_condDBReaderName = "CondDBCnvSvc", - "Service implementing the ICondDBReader interface to be used " - "to access the CondDB."); - - declareProperty("Converter", - m_converterName = "DetectorPersistencySvc", - "Service implementing the IConverter interface."); -} - -CondDBDQScanner::~CondDBDQScanner() {} - -IDQFilter::FlagsType CondDBDQScanner::scan(const Gaudi::Time & since, const Gaudi::Time & until) const -{ - typedef ICondDBReader::IOVList IOVList; - typedef ICondDBReader::IOV IOV; - IDQFilter::FlagsType flags; - - ICondDBReader::DataPtr data; - Gaudi::Time dataSince, dataUntil; - std::string desc; - - // Loop over the list of conditions in the folder - IOVList iovs = m_condDB->getIOVs(m_condPath, IOV(since, until)); - for(IOVList::iterator iov = iovs.begin(); iov != iovs.end(); ++iov) { - // get the condition data (XML) - StatusCode sc = m_condDB->getObject(m_condPath, iov->since, data, desc, dataSince, dataUntil); - if (sc.isFailure()){ - Exception("Problems retrieving data from the database"); - return flags; // never reached, but helps Coverity - } - - try { - // prepare the IOpaqueAddress to be given to the PersistencySvc - const long storageType = RelyConverter::getStorageType(m_condPath, desc); - const std::string xml_data = (*data.get())["data"].data<std::string>(); - IOpaqueAddress *addr = RelyConverter::createTmpAddress("conddb:" + m_condPath, - storageType, - "Flags", - Condition::classID(), - xml_data, - info(), - m_converter->addressCreator()); - if (!addr){ - Exception("Failed to create temporary IOpaqueAddress"); - return flags; // never reached, but helps Coverity - } - - // Retrieve the condition data - DataObject *obj = 0; - Condition *cond = 0; - if (m_converter->createObj(addr, obj).isFailure() - || m_converter->fillObjRefs(addr, obj).isFailure() - || (cond = dynamic_cast<Condition*>(obj)) == 0) { //assignment intended - delete addr; - if (obj) delete obj; - Exception("Conversion of Condition failed"); - return flags; // never reached, but helps Coverity - } - delete addr; - - // Merge the condition map with the collected one. - const IDQFilter::FlagsType &condFlags = cond->param<IDQFilter::FlagsType>("map"); - flags.insert(condFlags.begin(), condFlags.end()); - - delete obj; - - } catch (cool::RecordSpecificationUnknownField &e) { - Exception(std::string("I cannot find the data inside COOL object: ") + e.what()); - } - } - - return flags; -} - - - - -StatusCode CondDBDQScanner::initialize() -{ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - m_condDB = service(m_condDBReaderName); - if (UNLIKELY(!m_condDB.isValid())) { - error() << "Cannot get the ICondDBReader implementation " << m_condDBReaderName << endmsg; - return StatusCode::FAILURE; - } - - m_converter = service(m_converterName); - if (UNLIKELY(!m_converter.isValid())) { - error() << "Cannot get the IConverter implementation " << m_converterName << endmsg; - return StatusCode::FAILURE; - } - - return sc; -} - - - -StatusCode CondDBDQScanner::finalize() -{ - m_condDB.reset(); // release the ICondDBReader service - - return base_class::finalize(); -} - - - -// ============================================================================ diff --git a/Det/DetCond/src/component/CondDBDQScanner.h b/Det/DetCond/src/component/CondDBDQScanner.h deleted file mode 100644 index c686a8fd4..000000000 --- a/Det/DetCond/src/component/CondDBDQScanner.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SRC_CONDDBDQSCANNER_H -#define SRC_CONDDBDQSCANNER_H 1 -// Include files -// from Gaudi -#include "GaudiAlg/GaudiTool.h" -#include "GaudiKernel/SmartIF.h" - -// Implemented interfaces -#include "Kernel/IDQScanner.h" // IDQScanner - -class ICondDBReader; -class IConverter; - -/** Basic implementation of an IDQScanner based on the Conditions Database. - * - * @author Marco Clemencic - * @date 04/11/2011 - */ -class CondDBDQScanner: public extends1<GaudiTool, IDQScanner> { -public: - /// Standard constructor - CondDBDQScanner(const std::string& type, const std::string& name, const IInterface* parent); - virtual ~CondDBDQScanner(); ///< Destructor - - /// Scan all the Data Quality flags in the give time range in the CondDB. - /// @return merged list of DQ flags - virtual IDQFilter::FlagsType scan(const Gaudi::Time& since, const Gaudi::Time& until) const; - - virtual StatusCode initialize(); ///< Initialize the instance. - virtual StatusCode finalize(); ///< Finalize the instance. - -protected: -private: - - /// Path to the condition object containing the Data Quality flags. - /// (property ConditionPath) - std::string m_condPath; - - /// ICondDBReader implementation to use to access the Conditions Database. - /// (property CondDBReader) - std::string m_condDBReaderName; - - /// IConverter implementation (e.g. the persistency service) to use to convert - /// the data to a Condition. - /// (property Converter) - std::string m_converterName; - - /// ICondDBReader instance. - SmartIF<ICondDBReader> m_condDB; - - /// ICondDBReader instance. - SmartIF<IConverter> m_converter; - -}; - -#endif // SRC_CONDDBDQSCANNER_H diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.cpp b/Det/DetCond/src/component/CondDBDispatcherSvc.cpp deleted file mode 100755 index 624638275..000000000 --- a/Det/DetCond/src/component/CondDBDispatcherSvc.cpp +++ /dev/null @@ -1,294 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -// local -#include "CondDBDispatcherSvc.h" -#include "CondDBCommon.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBDispatcherSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBDispatcherSvc -// -// 2006-07-10 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBDispatcherSvc::CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc), - m_mainDB(0), - m_alternatives() -{ - declareProperty("MainAccessSvc", m_mainAccessSvcName = "CondDBAccessSvc" ); - declareProperty("Alternatives", m_alternativesDeclarationMap ); - - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBDispatcherSvc::~CondDBDispatcherSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBDispatcherSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - // locate the main access service - sc = service(m_mainAccessSvcName,m_mainDB,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << m_mainAccessSvcName << endmsg; - return sc; - } - - // locate all the alternative AccessSvcs - std::map<std::string,std::string>::iterator decl; - for ( decl = m_alternativesDeclarationMap.begin(); decl != m_alternativesDeclarationMap.end(); ++decl ) { - const std::string &altPath = decl->first; - const std::string &svcName = decl->second; - - if ( m_alternatives.find(altPath) != m_alternatives.end() ) { - log << MSG::ERROR << "More than one alternative for path " << altPath << endmsg; - return StatusCode::FAILURE; - } - - ICondDBReader *svcPtr; - sc = service(svcName,svcPtr,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << svcName << endmsg; - return sc; - } - - m_alternatives[altPath] = svcPtr; - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved '" << svcName << "' (for path '" << altPath << "')" << endmsg; - - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBDispatcherSvc::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - - if (m_mainDB) { - m_mainDB->release(); - m_mainDB = 0; - } - - std::map<std::string,ICondDBReader*>::iterator alt; - for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { - if (alt->second) alt->second->release(); - } - m_alternatives.clear(); - - return base_class::finalize(); -} - -ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return alternativeFor(path)->getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBDispatcherSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return alternativeFor(path)->getIOVs(path, iov, channel); -} - -//========================================================================= -// find the appropriate alternative -//========================================================================= -ICondDBReader *CondDBDispatcherSvc::alternativeFor(const std::string &path) const { - MsgStream log(msgSvc(), name() ); - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Get alternative DB for '" << path << "'" << endmsg; - if ( path.empty() || (path == "/") ) { - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Root node: using '" << m_mainAccessSvcName << "'" << endmsg; - return m_mainDB; - } - - // loop over alternatives - std::map<std::string,ICondDBReader*>::const_reverse_iterator alt; - for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { - if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { - log << MSG::VERBOSE << "Comparing with " << alt->first << endmsg; - } - // FIXME: (MCl) wrong logic - // path=/Conditions/Velo/AlignmentCatalog.xml - // alt.=/Conditions/Velo/Alignment - // Should not match - if ( ( path.size() >= alt->first.size() ) && - ( path.substr(0,alt->first.size()) == alt->first ) ){ - if( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) ) { - IService *svc = dynamic_cast<IService*>(alt->second); - log << MSG::VERBOSE << "Using '" ; - if (svc) log << svc->name(); - else log << "unknown"; - log << "'" << endmsg; - } - - return alt->second; - } - } - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Not found: using '" << m_mainAccessSvcName << "'" << endmsg; - return m_mainDB; -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) { - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); - } - return sc; -} -StatusCode CondDBDispatcherSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) { - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = alternativeFor(path)->getObject(path,when,data,descr,since,until,channel); - } - return sc; -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { - return getChildNodes(path,node_names,node_names); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBDispatcherSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) { - // clear the destination vectors - folders.clear(); - foldersets.clear(); - - // Get the folders and foldersets from the dedicated alternative - std::vector<std::string> tmpv1,tmpv2; - StatusCode sc = alternativeFor(path)->getChildNodes(path,tmpv1,tmpv2); - if (sc.isFailure()) return sc; - - // Find alternatives for subfolders of the path. - std::map<std::string,ICondDBReader*>::reverse_iterator alt; - std::string::size_type path_size = path.size(); - for ( alt = m_alternatives.rbegin(); alt != m_alternatives.rend(); ++alt ) { - // check if the path for the alternative is a subfolder of the required path - // i.e. alt->first should be = path + '/' + extra - if ( ( alt->first.size() > (path_size+1) ) && // it must be long enough - ( alt->first[path_size] == '/' ) && - ( alt->first.substr(0,path_size) == path ) ){ - // take the name of the child folder[set] implied by the alternative - // i.e. substring from after (path+'/') to the next '/' - std::string sub = alt->first.substr(path_size+1, - alt->first.find('/',path_size+1)-(path_size+1)); - if (std::find(tmpv1.begin(),tmpv1.end(),sub) == tmpv1.end() && - std::find(tmpv2.begin(),tmpv2.end(),sub) == tmpv2.end()){ - // this subnode is an addition due to the alternative - // let's check the type - if (alt->second->isFolder(path+'/'+sub)) - tmpv1.push_back(sub); // folder - else - tmpv2.push_back(sub); // folderset - } - } - } - - // copy the temporary vectors to the output ones - folders = tmpv1; - foldersets = tmpv2; - return sc; -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBDispatcherSvc::exists(const std::string &path) { - return alternativeFor(path)->exists(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBDispatcherSvc::isFolder(const std::string &path) { - return alternativeFor(path)->isFolder(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBDispatcherSvc::isFolderSet(const std::string &path) { - return alternativeFor(path)->isFolderSet(path); -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBDispatcherSvc::disconnect() { - // loop over alternatives - std::map<std::string,ICondDBReader*>::const_iterator alt; - for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { - alt->second->disconnect(); - } - if (m_mainDB) - m_mainDB->disconnect(); -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBDispatcherSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - // first add the main db - m_mainDB->defaultTags(tags); - - // loop over alternatives - std::map<std::string,ICondDBReader*>::const_iterator alt; - for ( alt = m_alternatives.begin(); alt != m_alternatives.end(); ++alt ) { - alt->second->defaultTags(tags); - } -} - - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBDispatcherSvc.h b/Det/DetCond/src/component/CondDBDispatcherSvc.h deleted file mode 100755 index 2e3819280..000000000 --- a/Det/DetCond/src/component/CondDBDispatcherSvc.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef COMPONENT_CONDDBDISPATCHERSVC_H -#define COMPONENT_CONDDBDISPATCHERSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "DetCond/ICondDBReader.h" -#include <vector> -#include <map> - -template <class TYPE> class SvcFactory; - -/** @class CondDBDispatcherSvc CondDBDispatcherSvc.h component/CondDBDispatcherSvc.h - * - * - * - * @author Marco Clemencic - * @date 2006-07-10 - */ -class CondDBDispatcherSvc: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - - -protected: - /// Standard constructor - CondDBDispatcherSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBDispatcherSvc( ); ///< Destructor - - -private: - - ICondDBReader *alternativeFor(const std::string &path) const; - - // -------------------- Data Members - - /// Property CondDBDispatcherSvc.MainAccessSvc: the AccessSvc instance to use to retrieve all the - /// objects for which an alternative is not specified (default to "CondDBAccessSvc"). - std::string m_mainAccessSvcName; - - /// Property CondDBDispatcherSvc.Alternatives: list of alternative Access Services in the form of - /// "/path/for/alternative":"ServiceType/ServiceName". - std::map<std::string,std::string> m_alternativesDeclarationMap; - - /// Pointer to the main access service. - ICondDBReader* m_mainDB; - - /// Container fo the alternatives. - std::map<std::string,ICondDBReader*> m_alternatives; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBDispatcherSvc>; - -}; -#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.cpp b/Det/DetCond/src/component/CondDBLayeringSvc.cpp deleted file mode 100755 index d78161e24..000000000 --- a/Det/DetCond/src/component/CondDBLayeringSvc.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -// local -#include "CondDBLayeringSvc.h" -#include "CondDBCommon.h" -#include "IOVListHelpers.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBLayeringSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBLayeringSvc -// -// 2006-07-14 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -// This is needed otherwise the implementation of std::map does -// not find operator<(Gaudi::Time,Gaudi::Time). -namespace Gaudi { using ::operator<; } - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBLayeringSvc::CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc) { - - declareProperty("Layers", m_layersNames ); - - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); - -} -//============================================================================= -// Destructor -//============================================================================= -CondDBLayeringSvc::~CondDBLayeringSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBLayeringSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - // locate all the AccessSvcs layers - std::vector<std::string>::iterator lname; - for ( lname = m_layersNames.begin(); lname != m_layersNames.end(); ++lname ) { - - ICondDBReader *svcPtr; - sc = service(*lname,svcPtr,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << *lname << endmsg; - return sc; - } - - m_layers.push_back(svcPtr); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved '" << *lname << "'" << endmsg; - - } - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBLayeringSvc::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - - std::vector<ICondDBReader*>::iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ( *layer ) (*layer)->release(); - } - m_layers.clear(); - - return base_class::finalize(); -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) -{ - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - std::vector<ICondDBReader*>::iterator layer; - sc = StatusCode::FAILURE; - for ( layer = m_layers.begin(); - layer != m_layers.end() && sc.isFailure(); - ++layer ) { - sc = (*layer)->getObject(path,when,data,descr,since,until,channel); - } - } - return sc; -} -StatusCode CondDBLayeringSvc::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) -{ - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - std::vector<ICondDBReader*>::iterator layer; - sc = StatusCode::FAILURE; - for ( layer = m_layers.begin(); - layer != m_layers.end() && sc.isFailure(); - ++layer ) { - sc = (*layer)->getObject(path,when,data,descr,since,until,channel); - } - } - return sc; -} - -template <typename Channel> -ICondDBReader::IOVList CondDBLayeringSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) -{ - IOVList iovs; - - IOVList missing; // IOVs not found - missing.push_back(iov); - - std::vector<ICondDBReader*>::iterator layer; - // for each layer - for ( layer = m_layers.begin(); - layer != m_layers.end() && !missing.empty(); - ++layer ) { - - IOVList layer_iovs; - - // look for the missing IOVs in this layer - for ( IOVList::iterator m = missing.begin(); - m != missing.end(); - ++m ) { - IOVList missing_iovs = (*layer)->getIOVs(path, *m, channel); - // if we found something merge with the others in the layer - if (!missing_iovs.empty()) { - // ensure that the found IOVs do not overlap with the already available ones - missing_iovs.front().since = std::max(missing_iovs.front().since, m->since); - missing_iovs.back().until = std::min(missing_iovs.back().until, m->until); - layer_iovs.insert(layer_iovs.end(), missing_iovs.begin(), missing_iovs.end()); - } - else continue; - } - - // if we got IOVs in this layer, we add them to the results list - if (!layer_iovs.empty()) { - iovs.insert(iovs.end(), layer_iovs.begin(), layer_iovs.end()); - std::sort(iovs.begin(), iovs.end()); - // regenerate the list of holes - missing = IOVListHelpers::find_holes(iovs, iov); - } - } - - return iovs; -} - -ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return i_getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBLayeringSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return i_getIOVs(path, iov, channel); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) -{ - return getChildNodes(path,node_names,node_names); -} - -namespace { - // helper function - template <class Input, class Output> - void merge(const Input &i, Output &o){ - typename Input::const_iterator it; - for (it = i.begin(); it != i.end(); ++it){ - if (std::find(o.begin(),o.end(),*it)==o.end()) { - o.push_back(*it); - } - } - } -} -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLayeringSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) -{ - // clear the destination vectors - folders.clear(); - foldersets.clear(); - - // Get the folders and foldersets from the dedicated alternative - std::vector<std::string> tmpv1,tmpv2; - StatusCode sc = StatusCode::FAILURE; - std::vector<ICondDBReader*>::iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->getChildNodes(path,tmpv1,tmpv2).isSuccess()){ - // we consider it a success if it worked at least for one of the layers - sc = StatusCode::SUCCESS; - merge(tmpv1,folders); - merge(tmpv2,foldersets); - } - } - return sc; -} -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBLayeringSvc::exists(const std::string &path) { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->exists(path)) return true; - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBLayeringSvc::isFolder(const std::string &path) { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->exists(path)) return (*layer)->isFolder(path); - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBLayeringSvc::isFolderSet(const std::string &path) { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - if ((*layer)->exists(path)) return (*layer)->isFolderSet(path); - } - return false; -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBLayeringSvc::disconnect() { - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - (*layer)->disconnect(); - } -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBLayeringSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - // loop over layers - std::vector<ICondDBReader*>::const_iterator layer; - for ( layer = m_layers.begin(); layer != m_layers.end(); ++layer ) { - (*layer)->defaultTags(tags); - } -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLayeringSvc.h b/Det/DetCond/src/component/CondDBLayeringSvc.h deleted file mode 100755 index c821688ef..000000000 --- a/Det/DetCond/src/component/CondDBLayeringSvc.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef COMPONENT_CONDDBLAYERINGSVC_H -#define COMPONENT_CONDDBLAYERINGSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "DetCond/ICondDBReader.h" -#include <vector> - -template <class TYPE> class SvcFactory; - -/** @class CondDBLayeringSvc CondDBLayeringSvc.h component/CondDBLayeringSvc.h - * - * - * @author Marco CLEMENCIC - * @date 2006-07-14 - */ -class CondDBLayeringSvc: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - -protected: - - /// Standard constructor - CondDBLayeringSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBLayeringSvc( ); ///< Destructor - -protected: - -private: - - // -------------------- Data Members - - /// Property CondDBLayeringSvc.Layers: list of Access Service layers. - /// They will be searched from the first to the last. - std::vector<std::string> m_layersNames; - - /// Container fo the alternatives. - std::vector<ICondDBReader*> m_layers; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBLayeringSvc>; - - /// Internal implementation helper to generalize the channel type. - template <typename Channel> - IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); - -}; -#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBLogger.cpp b/Det/DetCond/src/component/CondDBLogger.cpp deleted file mode 100755 index 9ec6bc57f..000000000 --- a/Det/DetCond/src/component/CondDBLogger.cpp +++ /dev/null @@ -1,250 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" - -#include <fstream> - -// local -#include "CondDBLogger.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBLogger) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBLogger -// -// 2008-01-24 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBLogger::CondDBLogger( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc), m_loggedReader(nullptr) { - - declareProperty("LoggedReader", m_loggedReaderName = "", - "Fully qualified name of the ICondDBReader to which the calls" - " have to be forwarded."); - declareProperty("LogFile", m_logFileName = "", - "Path to the log file (it is overwritten if it exists). " - "If not specified or set to empty, the file name is set from " - "the name of the instance plus '.log'." ); - -} -//============================================================================= -// Destructor -//============================================================================= -CondDBLogger::~CondDBLogger() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBLogger::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if ( m_loggedReaderName.empty() ){ - log << MSG::ERROR << "Property LoggedReader is not set." << endmsg; - return StatusCode::FAILURE; - } - - // locate the CondDBReader - sc = service(m_loggedReaderName,m_loggedReader,true); - if ( !sc.isSuccess() ) { - log << MSG::ERROR << "Could not locate " << m_loggedReaderName << endmsg; - return sc; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved '" << m_loggedReaderName << "'" << endmsg; - - // Set the default value of the file name if not specified. - if ( m_logFileName.empty() ){ - m_logFileName = name() + ".log"; - log << MSG::INFO << "Property LogFile not specified, using '" - << m_logFileName << "'" << endmsg; - } - - // Open the output file and start writing. - m_logFile = std::unique_ptr<std::ostream>(new std::ofstream(m_logFileName.c_str())); - if ( ! m_logFile->good() ) { - log << MSG::ERROR << "Problems opening " << m_logFileName << endmsg; - return StatusCode::FAILURE; - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "File '" << m_logFileName << "' opened for writing." << endmsg; - - (*m_logFile) << "INI: " << Gaudi::Time::current().ns() << " " << name() << " logging " << m_loggedReaderName << std::endl; - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBLogger::finalize(){ - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Finalize" << endmsg; - - if ( m_loggedReader ) { - m_loggedReader->release(); - m_loggedReader = 0; - } - - if (m_logFile.get()) { - (*m_logFile) << "FIN: " << Gaudi::Time::current().ns() << " " << name() << std::endl; - m_logFile.reset(0); - } - - return base_class::finalize(); -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GET: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << when.ns() << " " << std::flush; - StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} -StatusCode CondDBLogger::getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GCN: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << when.ns() << " " << std::flush; - StatusCode sc = m_loggedReader->getObject(path,when,data,descr,since,until,channel); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} - -ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "IOV: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << iov.since.ns() << " " << iov.until.ns() << std::endl; - return m_loggedReader->getIOVs(path, iov, channel); - } - return ICondDBReader::IOVList(); -} - -ICondDBReader::IOVList CondDBLogger::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - if ( m_loggedReader ) { - (*m_logFile) << "ICN: " << Gaudi::Time::current().ns() << " " - << path << " " << channel << " " - << iov.since.ns() << " " << iov.until.ns() << std::endl; - return m_loggedReader->getIOVs(path, iov, channel); - } - return ICondDBReader::IOVList(); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLogger::getChildNodes (const std::string &path, std::vector<std::string> &node_names) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - StatusCode sc = m_loggedReader->getChildNodes(path,node_names); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBLogger::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) -{ - if ( m_loggedReader ) { - (*m_logFile) << "GCH: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - StatusCode sc = m_loggedReader->getChildNodes(path,folders,foldersets); - (*m_logFile) << sc << std::endl; - return sc; - } - return StatusCode::FAILURE; -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBLogger::exists(const std::string &path) { - if ( m_loggedReader ) { - (*m_logFile) << "XST: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - bool out = m_loggedReader->exists(path); - (*m_logFile) << out << std::endl; - return out; - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBLogger::isFolder(const std::string &path) { - if ( m_loggedReader ) { - (*m_logFile) << "IFL: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - bool out = m_loggedReader->isFolder(path); - (*m_logFile) << out << std::endl; - return out; - } - return false; -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBLogger::isFolderSet(const std::string &path) { - if ( m_loggedReader ) { - (*m_logFile) << "IFS: " << Gaudi::Time::current().ns() << " " << path << " " << std::flush; - bool out = m_loggedReader->isFolderSet(path); - (*m_logFile) << out << std::endl; - return out; - } - return false; -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBLogger::disconnect() { - if ( m_loggedReader ) { - (*m_logFile) << "DIS: " << Gaudi::Time::current().ns() << std::endl; - m_loggedReader->disconnect(); - } -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBLogger::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - if ( m_loggedReader ) { - (*m_logFile) << "TAG: " << Gaudi::Time::current().ns() << std::endl; - m_loggedReader->defaultTags(tags); - } -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBLogger.h b/Det/DetCond/src/component/CondDBLogger.h deleted file mode 100755 index d05fc8fd1..000000000 --- a/Det/DetCond/src/component/CondDBLogger.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef COMPONENT_CONDDBLOGGER_H -#define COMPONENT_CONDDBLOGGER_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "DetCond/ICondDBReader.h" - -template <class TYPE> class SvcFactory; - -/** @class CondDBLogger CondDBLogger.h component/CondDBLogger.h - * - * Logger of acesses to CondDB. - * - * CondDBLogger is a simple class that allow to store in a file all the - * requests made to a ICondDBReader instance. It has to be used as a front-end - * to the instance we want to monitor. - * - * Given the following option snippet - * @code - * MyCondDBUser.Reader = "ACondDBReader"; - * @endcode - * the CondDBLogger can be enabled with - * @code - * CondDBLogger.LoggedReader = "ACondDBReader"; - * MyCondDBUser.Reader = "CondDBLogger"; - * @endcode - * or in python options - * @code - * user = MyCondDBUser() - * user.Reader = CondDBLogger(LoggedReader = user.Reader) - * @endcode - * - * The format of the log file is very simple. Each line starts with an - * operation code then the time of the operation in ns (as returned by - * Gaudi::Time::ns()). The rest of the line depend on the operation: - * - "INI:" - * - Initialization of the logger - * - "TAG:" - * - Request of the used tag - * - "GCH:" - * - Retrieve the child nodes of a folderset. - * - "GET:" - * - Request of an object from the database, the format is<br> - * <path> <channel id> <path> <evt.time> <status> - * - "GCN:" - * - Request of an object from the database using the channel name, the format is<br> - * <path> <channel name> <path> <evt.time> <status> - * - "FIN:" - * - Finalization of the logger - * - "IOV:" - * - Request list of IOVs (using numeric channel) - * - "ICN:" - * - Request list of IOVs (using channel name) - * - * @param LoggedReader - * Fully qualified name of the ICondDBReader to which the calls have to - * be forwarded. - * @param LogFile - * Path to the log file (it is overwritten if it exists). If not - * specified or set to empty, the file name is set from the name of the - * instance plus '.log'. - * - * @author Marco CLEMENCIC - * @date 2008-01-24 - */ -class CondDBLogger: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - -protected: - - /// Standard constructor - CondDBLogger( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBLogger( ); ///< Destructor - -private: - - // -------------------- Data Members - - /// Pointer to the CondDBReader whose activity has to be logged. - ICondDBReader *m_loggedReader; - - /// Name of the CondDBReader whose activity has to be logged. - std::string m_loggedReaderName; - - /// Path to the file that will contain the log. - std::unique_ptr<std::ostream> m_logFile; - - /// Path to the file that will contain the log. - std::string m_logFileName; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBLogger>; - -}; -#endif // COMPONENT_CONDDBLAYERINGSVC_H diff --git a/Det/DetCond/src/component/CondDBReplayAlg.cpp b/Det/DetCond/src/component/CondDBReplayAlg.cpp deleted file mode 100755 index 101826444..000000000 --- a/Det/DetCond/src/component/CondDBReplayAlg.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Include files - -// from Gaudi -// needed to sleep between two operations -#include "GaudiKernel/Sleep.h" - -#include "DetCond/ICondDBReader.h" -#include <fstream> - -// local -#include "CondDBReplayAlg.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBReplayAlg -// -// Jan 25, 2008 : Marco Clemencic -//----------------------------------------------------------------------------- - -// Declaration of the Algorithm Factory -DECLARE_ALGORITHM_FACTORY( CondDBReplayAlg ) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBReplayAlg::CondDBReplayAlg( const std::string& name, - ISvcLocator* pSvcLocator) - : GaudiAlgorithm ( name , pSvcLocator ) - , m_reader(NULL) -{ - declareProperty("Reader", m_readerName = "CondDBCnvSvc", - "Name of the reader to use to replay the requests."); - declareProperty("LogFile", m_logFileName = "", - "Path to the log file to re-play. " - "If not specified or set to empty, the file name is set from " - "the name of the instance plus '.log'." ); -} -//============================================================================= -// Destructor -//============================================================================= -CondDBReplayAlg::~CondDBReplayAlg() {} - -//============================================================================= -// Initialization -//============================================================================= -StatusCode CondDBReplayAlg::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Initialize" << endmsg; - - const bool create = true; - m_reader = svc<ICondDBReader>(m_readerName,create); - - // Open the input file. - std::unique_ptr<std::istream> logFile(new std::ifstream(m_logFileName.c_str())); - if ( ! logFile->good() ) { - error() << "Problems opening " << m_logFileName << endmsg; - return StatusCode::FAILURE; - } - info() << "File '" << m_logFileName << "' opened for reading." << endmsg; - - // Parse the input file - std::string opcode, tmp; - operation_t operation; - Gaudi::Time last_time; - Gaudi::Time::ValueType tmptime; - while ( ! logFile->eof() ) { - - (*logFile) >> opcode; - if ("GET:" == opcode || "GCN:" == opcode) { // we use this operation... - - operation.use_numeric_channel = ("GET:" == opcode); - - (*logFile) >> tmptime; operation.time = Gaudi::Time(tmptime); - (*logFile) >> operation.node; - (*logFile) >> tmptime; operation.evttime = Gaudi::Time(tmptime); - - if (operation.use_numeric_channel) { - (*logFile) >> operation.channel; - } - else { - (*logFile) >> operation.chn_name; - } - - if ( last_time > operation.time ) { - error() << "Error in the log file: the operation time is not strictly increasing"; - return StatusCode::FAILURE; - } - - //info() << operation.time.ns() << " " << operation.node << " " << operation.evttime.ns() << " " << operation.channel << endmsg; - last_time = operation.time; - m_operations.push_back(operation); - } - // skip the rest of the line - std::getline(*logFile,tmp); - } - info() << "Found " << m_operations.size() << " operations to replay." << endmsg; - - return StatusCode::SUCCESS; -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode CondDBReplayAlg::execute() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Execute" << endmsg; - - info() << "Replaying database operations ..." << endmsg; - ICondDBReader::DataPtr data; - std::string descr; - Gaudi::Time since, until; - // replay the operations - Gaudi::Time last_optime, last_time; - bool first = true; - for(list_t::iterator op = m_operations.begin(); op != m_operations.end(); ++op) { - - if ( first ) { - // we do not have to wait for the first operation - first = false; - } else { - // calculate how much we have to sleep - Gaudi::Time::ValueType ns_to_sleep = (op->time.ns() - last_optime.ns()) // time between operations - - (Gaudi::Time::current().ns() - last_time.ns()); // time wasted - - if ( ns_to_sleep > 0 ) Gaudi::NanoSleep(ns_to_sleep); - } - - last_optime = op->time; - - // I have to store the current time before the operation otherwise - // we to not count the time that the operation takes as already elapsed. - last_time = Gaudi::Time::current(); - - // Get the object - if (op->use_numeric_channel) { - m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->channel).ignore(); - } - else { - m_reader->getObject(op->node,op->evttime,data,descr,since,until,op->chn_name).ignore(); - } - - } - info() << "Replay completed." << endmsg; - - return StatusCode::SUCCESS; -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode CondDBReplayAlg::finalize() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Finalize" << endmsg; - - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBReplayAlg.h b/Det/DetCond/src/component/CondDBReplayAlg.h deleted file mode 100755 index 9eff90934..000000000 --- a/Det/DetCond/src/component/CondDBReplayAlg.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef CONDDBREPLAYALG_H_ -#define CONDDBREPLAYALG_H_ - -// Include files -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" -#include "GaudiKernel/Time.h" -#include <list> - -class ICondDBReader; - -/** @class CondDBReplayAlg CondDBReplayAlg.h - * - * Simple algorithm that reads a file in the format produced by CondDBLogger - * and re-play the request to the database with the same timing written in the - * log file. - * - * @author Marco Clemencic <marco.clemencic@cern.ch> - * @date 2008-01-25 - */ -class CondDBReplayAlg : public GaudiAlgorithm { -public: - /// Standard constructor - CondDBReplayAlg( const std::string& name, ISvcLocator* pSvcLocator ); - - virtual ~CondDBReplayAlg( ); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization - -protected: - -private: - - /// Path to the file containing the log. - std::string m_logFileName; - - /// Name of the reader to use to replay the requests. - std::string m_readerName; - - /// Pointer to the ICondDBReader service. - ICondDBReader *m_reader; - - struct operation_t { - Gaudi::Time time; - std::string node; - Gaudi::Time evttime; - bool use_numeric_channel; - cool::ChannelId channel; - std::string chn_name; - }; - typedef std::list<operation_t> list_t; - - /// List of operations to perform - list_t m_operations; - -}; - -#endif /*CONDDBREPLAYALG_H_*/ diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp deleted file mode 100755 index f4701c43f..000000000 --- a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// Include files -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/Property.h" -#include "GaudiKernel/IJobOptionsSvc.h" -#include "GaudiKernel/ThreadGaudi.h" - -#include "boost/filesystem/path.hpp" -#include "boost/filesystem/operations.hpp" -#include "boost/filesystem/exception.hpp" - -// local -#include "CondDBSQLiteCopyAccSvc.h" - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBSQLiteCopyAccSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBSQLiteCopyAccSvc -// -// 2007-03-22 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBSQLiteCopyAccSvc::CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ): - CondDBAccessSvc(name,svcloc) -{ - declareProperty("OriginalFile", m_source_path = "" ); - declareProperty("DestinationFile", m_dest_path = "" ); - declareProperty("DBName", m_dbname = "" ); - declareProperty("ForceCopy", m_force_copy = false ); - declareProperty("IgnoreCopyError", m_ignore_copy_error = false ); -} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBSQLiteCopyAccSvc::initialize(){ - //before initializing the parent, I have to copy the file - StatusCode sc = setProperties(); - if ( ! sc.isSuccess() ) { - MsgStream log(msgSvc(), name() ); - log << MSG::ERROR << "Failed to set properties" << endmsg; - return sc; - } - - // this should be done after getting the properties - MsgStream log(msgSvc(), name() ); - - // preliminary checks on the options - if ( m_source_path.empty() ) { - log << MSG::ERROR << "You must provide the source file path via the option '" - << name() << ".OriginalFile'" << endmsg; - return StatusCode::FAILURE; - } - if ( m_dest_path.empty() ) { - log << MSG::ERROR << "You must provide the destination file path via the option '" - << name() << ".DestinationFile'" << endmsg; - return StatusCode::FAILURE; - } - if ( m_dbname.empty() ) { - log << MSG::ERROR << "You must provide the database name via the option '" - << name() << ".DBName'" << endmsg; - return StatusCode::FAILURE; - } - - try { - - // if "force" mode is selected: remove the destination file if it exists - if ( m_force_copy ) { - bool file_existed = boost::filesystem::remove( m_dest_path ); - if ( file_existed ) { - log << MSG::WARNING << "Removed file '" << m_dest_path << "' to replace it" << endmsg; - } - } - - // copy the source file - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Copying " - << m_source_path << " -> " - << m_dest_path << endmsg; - boost::filesystem::copy_file(m_source_path,m_dest_path); - - } - catch (boost::filesystem::filesystem_error &e){ - - MSG::Level lvl = MSG::ERROR; - if ( m_ignore_copy_error ) lvl = MSG::WARNING; - - log << lvl << "Problems occurred copying the file" << endmsg; - log << lvl << e.what() << endmsg; - if ( ! m_ignore_copy_error ) - return StatusCode::FAILURE; - } - - /* - // I need to override the connection string property - IJobOptionsSvc* jos; - const bool CREATEIF(true); - sc = serviceLocator()->service( "JobOptionsSvc", jos, CREATEIF ); - if( sc.isFailure() ) { - log << MSG::ERROR << "Service JobOptionsSvc not found" << endmsg; - } - - sc = jos->addPropertyToCatalogue( getGaudiThreadGenericName(name()), - StringProperty( "ConnectionString", - "sqlite_file:" + m_dest_path + "/" + m_dbname) ); - jos->release(); - if ( ! sc.isSuccess() ) { - log << MSG::ERROR << "Failed to override the property '" << name() << ".ConnectionString'"<< endmsg; - return sc; - } - */ - - // Set the connection string to be used (the one from the base class will be ignored). - m_sqlite_connstring = "sqlite_file:" + m_dest_path + "/" + m_dbname; - - // Initialize the base class. - return CondDBAccessSvc::initialize(); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBSQLiteCopyAccSvc::~CondDBSQLiteCopyAccSvc() {} - -//============================================================================= -// Return the connection string used to connect to the database. -//============================================================================= -const std::string &CondDBSQLiteCopyAccSvc::connectionString() const { - return m_sqlite_connstring; -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h b/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h deleted file mode 100755 index 1daecf30c..000000000 --- a/Det/DetCond/src/component/CondDBSQLiteCopyAccSvc.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef COMPONENT_CONDDBSQLITECOPYACCSVC_H -#define COMPONENT_CONDDBSQLITECOPYACCSVC_H 1 - -// Include files -#include "CondDBAccessSvc.h" - -/** @class CondDBSQLiteCopyAccSvc CondDBSQLiteCopyAccSvc.h component/CondDBSQLiteCopyAccSvc.h - * - * Extension to CondDBAccessSvc SQLite specific. The original SQLite file is copied to - * a different direcory before being used. This is particularily helpful when the original - * file is accessible only via NFS (see http://www.sqlite.org/faq.html#q7 for details). - * - * @author Marco Clemencic - * @date 2007-03-22 - */ -class CondDBSQLiteCopyAccSvc: public CondDBAccessSvc { - -public: - - /// Initilize the service - virtual StatusCode initialize(); - - /// Return the connection string used to connect to the database. - virtual const std::string &connectionString() const; - - -protected: - /// Standard constructor - CondDBSQLiteCopyAccSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBSQLiteCopyAccSvc( ); ///< Destructor - -private: - - /// Path to the original file - std::string m_source_path; - /// Path to destination file - std::string m_dest_path; - /// COOL database name - std::string m_dbname; - - /// Whether to overwrite the destination file. - bool m_force_copy; - /// Whether ingore copy error (e.g. if the destination file exists, try to use it) - bool m_ignore_copy_error; - - /// Needed to avoid interference with the connection string set by CondDBAccessSvc - /// standard options (we need to overwrite it). - std::string m_sqlite_connstring; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBSQLiteCopyAccSvc>; - -}; -#endif // COMPONENT_CONDDBSQLITECOPYACCSVC_H diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp b/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp deleted file mode 100755 index 7df80596a..000000000 --- a/Det/DetCond/src/component/CondDBTimeSwitchSvc.cpp +++ /dev/null @@ -1,363 +0,0 @@ -// Include files -#ifdef WIN32 // Hacks to compile on Windows... -#define NOMSG -#define NOGDI -#define max max -#endif - -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/ClassID.h" -#include "GaudiKernel/Time.h" -#include "GaudiKernel/SystemOfUnits.h" -#include "GaudiKernel/IDetDataSvc.h" - -// local -#include "CondDBTimeSwitchSvc.h" -#include "CondDBCommon.h" - - -// Factory implementation -DECLARE_SERVICE_FACTORY(CondDBTimeSwitchSvc) - -//----------------------------------------------------------------------------- -// Implementation file for class : CondDBTimeSwitchSvc -// -// 2006-07-10 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -// This is needed otherwise the implementation of std::map does -// not find operator<(Gaudi::Time,Gaudi::Time). -namespace Gaudi { using ::operator<; } -//============================================================================= -// Code copied from GaudiKernel Parsers, to have a parser for -// pair<long long,long long>. -// ============================================================================ -// GaudiKernel -// ============================================================================ -// 2011-08-26 : alexander.mazurov@gmail.com -#include "GaudiKernel/ParsersFactory.h" -namespace { - StatusCode parse(std::pair<long long,long long>& result, - const std::string& input){ - return Gaudi::Parsers::parse_(result, input); - } -} -//============================================================================= - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -CondDBTimeSwitchSvc::CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ): - base_class(name,svcloc), - m_readersDeclatations(), - m_readers(), - m_latestReaderRequested(0), - m_dds(0) -{ - - // "'CondDBReader':(since, until)", with since and until doubles - declareProperty("Readers", m_readersDeclatations); - - declareProperty("EnableXMLDirectMapping", m_xmlDirectMapping = true, - "Allow direct mapping from CondDB structure to" - " transient store."); -} - -//============================================================================= -// Destructor -//============================================================================= -CondDBTimeSwitchSvc::~CondDBTimeSwitchSvc() {} - -//============================================================================= -// initialize -//============================================================================= -StatusCode CondDBTimeSwitchSvc::initialize(){ - StatusCode sc = base_class::initialize(); - if (sc.isFailure()) return sc; - - MsgStream log(msgSvc(), name() ); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Initialize" << endmsg; - - if (m_readersDeclatations.empty()) { - log << MSG::ERROR << "No CondDBReader has been specified" - " (property 'Readers')." << endmsg; - return StatusCode::FAILURE; - } - - // decoding the property "Readers" - std::string reader_name, reader_siov; - std::pair<long long,long long> reader_iov; - for (ReadersDeclatationsType::iterator rd = m_readersDeclatations.begin(); - rd != m_readersDeclatations.end(); ++rd){ - // first step of parsing (split "'name':value" -> "name","value") - sc = Gaudi::Parsers::parse(reader_name,reader_siov,*rd); - if (sc.isSuccess()) { - // second step (only if first passed) - sc = ::parse(reader_iov,reader_siov); - } - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot decode string '" << *rd << "'" << endmsg; - return sc; - } - // Check for overlaps - const bool quiet = true; - ReaderInfo *old = readerFor(reader_iov.first,quiet); - if (!old) old = readerFor(reader_iov.second,quiet); - if (old) { - log << MSG::ERROR << "Conflicting IOVs between '" << old->name << "':(" - << old->since.ns() << "," << old->until.ns() << ") and " - << *rd << endmsg; - return StatusCode::FAILURE; - } - // use "until" as key to be able to search with "upper_bound" - ReaderInfo ri(reader_name, reader_iov.first, reader_iov.second); - m_readers.insert(std::make_pair(ri.until,ri)); - } - if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { - log << MSG::DEBUG << "Configured CondDBReaders:" << endmsg; - ReadersType::iterator r; - for (r = m_readers.begin(); r != m_readers.end(); ++r) { - log << MSG::DEBUG << " " << r->second.since << " - " << r->second.until - << ": " << r->second.name << endmsg; - } - } - // we need to reset it because it got corrupted during the - // check for overlaps - m_latestReaderRequested = 0; - - return sc; -} - -//============================================================================= -// finalize -//============================================================================= -StatusCode CondDBTimeSwitchSvc::finalize(){ - if( UNLIKELY( outputLevel() <= MSG::DEBUG ) ) { - MsgStream log(msgSvc(), name()); - log << MSG::DEBUG << "Finalize" << endmsg; - } - - // release all the loaded CondDBReader services - m_readers.clear(); - if(m_dds) { - m_dds->release(); - m_dds = 0; - } - m_readersDeclatations.clear(); - m_latestReaderRequested = 0; - - return base_class::finalize(); -} - -//========================================================================= -// find the appropriate reader -//========================================================================= -CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::readerFor(const Gaudi::Time &when, bool quiet) { - MsgStream log(msgSvc(), name()); - - if (!quiet) log << MSG::VERBOSE << "Get CondDBReader for event time " << when << endmsg; - - // TODO: (MCl) if we change service, we may clear the cache of the one - // that is not needed. - if ((!m_latestReaderRequested) || !m_latestReaderRequested->isValidAt(when)){ - // service not valid: search for the correct one - - // Find the element with key ("until") greater that the requested one - ReadersType::iterator reader = m_readers.upper_bound(when); - if (reader != m_readers.end() && reader->second.isValidAt(when)){ - m_latestReaderRequested = &(reader->second); - } else { - m_latestReaderRequested = 0; // reader not found - if (!quiet) log << MSG::WARNING << "No reader configured for requested event time" << endmsg; - } - } - - return m_latestReaderRequested; -} - -//========================================================================= -// get the current time -//========================================================================= -Gaudi::Time CondDBTimeSwitchSvc::getTime() { - if (!m_dds) { - StatusCode sc = service("DetectorDataSvc",m_dds,false); - if (sc.isFailure()) { - MsgStream log(msgSvc(), name()); - log << MSG::WARNING << "Cannot find the DetectorDataSvc," - " using a default event time (0)" << endmsg; - return Gaudi::Time(); - } - } - return m_dds->eventTime(); -} - -//========================================================================= -// get the current reader -//========================================================================= -CondDBTimeSwitchSvc::ReaderInfo *CondDBTimeSwitchSvc::currentReader() { - if (!m_latestReaderRequested) { - // Let's stay on the safe side if we don't find a reader - if (readerFor(getTime()) == 0) { - throw GaudiException("No reader configured for current event time", - "CondDBTimeSwitchSvc::currentReader",StatusCode::FAILURE); - } - } - return m_latestReaderRequested; -} - -//========================================================================= -// retrieve an object -//========================================================================= -StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, - const Gaudi::Time &when, - DataPtr &data, - std::string &descr, - Gaudi::Time &since, - Gaudi::Time &until, - cool::ChannelId channel) { - // get the reader for the requested time - ReaderInfo *ri = readerFor(when); - if (!ri) return StatusCode::FAILURE; - - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); - if (sc.isSuccess()) ri->cutIOV(since,until); - } - return sc; -} -StatusCode CondDBTimeSwitchSvc::getObject (const std::string &path, - const Gaudi::Time &when, - DataPtr &data, - std::string &descr, - Gaudi::Time &since, - Gaudi::Time &until, - const std::string &channel) { - // get the reader for the requested time - ReaderInfo *ri = readerFor(when); - if (!ri) return StatusCode::FAILURE; - - StatusCode sc; - if (m_xmlDirectMapping && isFolderSet(path)) { - descr = "Catalog generated automatically by " + name(); - since = Gaudi::Time::epoch(); - until = Gaudi::Time::max(); - sc = CondDB::generateXMLCatalog(this,path,data); - } else { - sc = ri->reader(serviceLocator())->getObject(path,when,data,descr,since,until,channel); - if (sc.isSuccess()) ri->cutIOV(since,until); - } - return sc; - -} - -template <typename Channel> -ICondDBReader::IOVList CondDBTimeSwitchSvc::i_getIOVs(const std::string & path, const IOV &iov, const Channel &channel) -{ - IOVList iovs; - - IOV tmp; - - // get the list of readers valid in the given time IOV - ReadersType::iterator r; - for(r = m_readers.begin(); r != m_readers.end(); ++r) { - if (r->second.until <= iov.since) continue; // ignore readers before... - if (r->second.since >= iov.until) break; // ...and after the request - - tmp.since = std::max(iov.since, r->second.since); - tmp.until = std::min(iov.until, r->second.until); - - IOVList new_iovs = r->second.reader(serviceLocator())->getIOVs(path, tmp, channel); - if (!new_iovs.empty()) { - // trim the IOVs found - new_iovs.front().since = std::max(tmp.since, new_iovs.front().since); - new_iovs.back().until = std::min(tmp.until, new_iovs.back().until); - - iovs.insert(iovs.end(), new_iovs.begin(), new_iovs.end()); - } - } - return iovs; -} - -ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, cool::ChannelId channel) -{ - return i_getIOVs(path, iov, channel); -} - -ICondDBReader::IOVList CondDBTimeSwitchSvc::getIOVs(const std::string & path, const IOV &iov, const std::string & channel) -{ - return i_getIOVs(path, iov, channel); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, std::vector<std::string> &node_names) { - return getChildNodes(path,node_names,node_names); -} - -//========================================================================= -// get the list of child nodes of a folderset -//========================================================================= -StatusCode CondDBTimeSwitchSvc::getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets) { - // clear the destination vectors - folders.clear(); - foldersets.clear(); - - // delegate to the current Reader (hoping that is good enough) - return currentReader()->reader(serviceLocator())->getChildNodes(path,folders,foldersets); -} - -//========================================================================= -// Tells if the path is available in the database. -//========================================================================= -bool CondDBTimeSwitchSvc::exists(const std::string &path) { - return currentReader()->reader(serviceLocator())->exists(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folder. -//========================================================================= -bool CondDBTimeSwitchSvc::isFolder(const std::string &path) { - return currentReader()->reader(serviceLocator())->isFolder(path); -} - -//========================================================================= -// Tells if the path (if it exists) is a folderset. -//========================================================================= -bool CondDBTimeSwitchSvc::isFolderSet(const std::string &path) { - return currentReader()->reader(serviceLocator())->isFolderSet(path); -} - -//========================================================================= -// Force disconnection from database. -//========================================================================= -void CondDBTimeSwitchSvc::disconnect() { - // loop over all readers - ReadersType::const_iterator reader; - for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { - if (reader->second.loaded()) - reader->second.reader(serviceLocator())->disconnect(); - } -} - -//========================================================================= -// Collect the list of used tags and databases -//========================================================================= -void CondDBTimeSwitchSvc::defaultTags ( std::vector<LHCb::CondDBNameTagPair>& tags ) const { - // loop over all readers - ReadersType::const_iterator reader; - for ( reader = m_readers.begin(); reader != m_readers.end(); ++reader ) { - reader->second.reader(serviceLocator())->defaultTags(tags); - } -} - -//============================================================================= diff --git a/Det/DetCond/src/component/CondDBTimeSwitchSvc.h b/Det/DetCond/src/component/CondDBTimeSwitchSvc.h deleted file mode 100755 index c1eecb386..000000000 --- a/Det/DetCond/src/component/CondDBTimeSwitchSvc.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef COMPONENT_CONDDBTIMESWITCHSVC_H -#define COMPONENT_CONDDBTIMESWITCHSVC_H 1 - -// Include files -#include "GaudiKernel/Service.h" -#include "GaudiKernel/Map.h" -#include "DetCond/ICondDBReader.h" -#include <vector> -#include <map> - -template <class TYPE> class SvcFactory; -class IDetDataSvc; - -/** @class CondDBTimeSwitchSvc CondDBTimeSwitchSvc.h component/CondDBTimeSwitchSvc.h - * - * - * - * @author Marco Clemencic - * @date 2006-07-10 - */ -class CondDBTimeSwitchSvc: public extends1<Service, ICondDBReader> { -public: - /// Initialize COOL (CondDB) Access Layer Service - virtual StatusCode initialize(); - /// Finalize Service - virtual StatusCode finalize(); - - // --------- ICondDBReader implementation - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, cool::ChannelId channel = 0); - - /// Try to retrieve an object from the Condition DataBase. If path points to a FolderSet, - /// channel and when are ignored and data is set ot NULL. - virtual StatusCode getObject (const std::string &path, const Gaudi::Time &when, - DataPtr &data, - std::string &descr, Gaudi::Time &since, Gaudi::Time &until, const std::string &channel); - - /// @{ - /// @see ICondDBReader::getIOVs - virtual IOVList getIOVs (const std::string &path, const IOV &iov, cool::ChannelId channel = 0); - virtual IOVList getIOVs (const std::string &path, const IOV &iov, const std::string &channel); - /// @} - - /// Retrieve the names of the children nodes of a FolderSet. - virtual StatusCode getChildNodes (const std::string &path, std::vector<std::string> &node_names); - - /// Retrieve the names of the children nodes of a FolderSet divided in folders and foldersets. - virtual StatusCode getChildNodes (const std::string &path, - std::vector<std::string> &folders, - std::vector<std::string> &foldersets); - - /// Tells if the path is available in the database. - virtual bool exists(const std::string &path); - - /// Tells if the path (if it exists) is a folder. - virtual bool isFolder(const std::string &path); - - /// Tells if the path (if it exists) is a folderset. - virtual bool isFolderSet(const std::string &path); - - /// Disconnect from the database. - virtual void disconnect(); - - // --------- ICondDBInfo implementation - - /** Get the current default database tags - * @param tags vector of DB name, tag pairs. Empty if DB not available - */ - virtual void defaultTags( std::vector<LHCb::CondDBNameTagPair>& tags) const; - - -protected: - /// Standard constructor - CondDBTimeSwitchSvc( const std::string& name, ISvcLocator* svcloc ); - - virtual ~CondDBTimeSwitchSvc( ); ///< Destructor - - -private: - - /// Internal class to record the readers - struct ReaderInfo { - /// CondDBReader instance name ("type/name") - std::string name; - /// Boundaries of the Interval Of Validity - Gaudi::Time since, until; - /// Default Constructor - ReaderInfo(const std::string &_n, - Gaudi::Time _s = Gaudi::Time::epoch(), - Gaudi::Time _u = Gaudi::Time::max()): - name(_n), - since(_s), - until(_u), - m_reader(0) - {} - /// Default Constructor - ReaderInfo(const std::string &_n, Gaudi::Time::ValueType _s, Gaudi::Time::ValueType _u): - name(_n), - since(_s), - until(_u), - m_reader(0) - {} - /// Copy constructor (for a correct reference counting). - ReaderInfo(const ReaderInfo &_ri): - name(_ri.name), - since(_ri.since), - until(_ri.until), - m_reader(_ri.m_reader) - { - if (m_reader) m_reader->addRef(); - } - /// Destructor (releases the CondDBReader service). - ~ReaderInfo(){ - if (m_reader) m_reader->release(); - } - /// Shortcut to check the validity of the reader - bool isValidAt(const Gaudi::Time &when) const { - return since <= when && until > when; - } - /// Shortcut to retrieve the pointer to the reader service. - ICondDBReader *reader(ISvcLocator *svcloc) const { - if (!m_reader) { - if (!svcloc) - throw GaudiException("ServiceLocator pointer is NULL", - "CondDBTimeSwitchSvc::ReaderInfo::get",StatusCode::FAILURE); - StatusCode sc = svcloc->service(name,m_reader,true); - if (sc.isFailure()) - throw GaudiException("Cannot get ICondDBReader '"+name+"'", - "CondDBTimeSwitchSvc::ReaderInfo::get",sc); - } - return m_reader; - } - /// Shortcut to restrict and IOV to the boundaries defined for the reader - void cutIOV(Gaudi::Time &_since, Gaudi::Time &_until) const { - if ( since > _since ) _since = since; - if ( until < _until ) _until = until; - } - /// convert to a string - std::string toString() const; - /// tell if the reader has already been instantiated - bool loaded() const { - return m_reader; - } - private: - /// Pointer to the CondDBReader instance - mutable ICondDBReader *m_reader; - }; - - /// Get the the CondDBReader valid for a given point in time. - /// Returns 0 if no service is available. - /// The boolean flag is used to avoid messages (during initialization). - ReaderInfo *readerFor(const Gaudi::Time &when, bool quiet = false); - - /// Get the the CondDBReader valid for a given point in time. - /// Returns 0 if no service is available - ReaderInfo *currentReader(); - - /// Get current event time from the detector data svc. - Gaudi::Time getTime(); - - // -------------------- Data Members - typedef std::vector<std::string> ReadersDeclatationsType; - typedef GaudiUtils::Map<Gaudi::Time,ReaderInfo> ReadersType; - - /// Property CondDBTimeSwitchSvc.Readers: list of ICondDBReaders to be used - /// for given intervals of validity. The format is "'Reader': (since, until)", - /// where since and until are doubles defining the time in standard units. - ReadersDeclatationsType m_readersDeclatations; - - /// Container for the alternatives. The ReaderInfo objects are indexed by - /// "until" to allow efficient search with map::upper_bound. - ReadersType m_readers; - - /// Pointer used to cache the latest requested reader. - /// It allows to avoid the search. - ReaderInfo *m_latestReaderRequested; - - /// Pointer to the detector data service, used to get the event time in - /// the methods that do not require it as argument. - /// It used only if there was not a previous request with the time. - IDetDataSvc *m_dds; - - /// Enable/disable direct mapping from the database structure to the transient - /// store using XML persistency format (enabled by default). - bool m_xmlDirectMapping; - - /// Allow SvcFactory to instantiate the service. - friend class SvcFactory<CondDBTimeSwitchSvc>; - - /// Internal implementation helper to generalize the channel type. - template <typename Channel> - IOVList i_getIOVs (const std::string &path, const IOV &iov, const Channel &channel); -}; -#endif // COMPONENT_CONDDBDISPATCHERSVC_H diff --git a/Det/DetCond/src/component/IOVListHelpers.cpp b/Det/DetCond/src/component/IOVListHelpers.cpp deleted file mode 100644 index 62ede6d93..000000000 --- a/Det/DetCond/src/component/IOVListHelpers.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "IOVListHelpers.h" - -namespace IOVListHelpers { - ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov) { - - ICondDBReader::IOVList result; - - Gaudi::Time last = iov.since; // keep track of the end of coverage - // loop over covering interval - for (const auto& covered : data ) { - if (covered.since > last) { // hole between the end of coverage and begin of next IOV - result.emplace_back(last, covered.since); - } - last = covered.until; // prepare to look for the next hole - } - if (last < iov.until) { - // we didn't get anything to cover until the end of the requested IOV - result.emplace_back(last, iov.until); - } - - return result; - } -} diff --git a/Det/DetCond/src/component/IOVListHelpers.h b/Det/DetCond/src/component/IOVListHelpers.h deleted file mode 100644 index d660cf962..000000000 --- a/Det/DetCond/src/component/IOVListHelpers.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef IOVLISTHELPERS_H -#define IOVLISTHELPERS_H -#include "DetCond/ICondDBReader.h" - -namespace IOVListHelpers { - /// Find the intervals in passed interval that are not covered by the provided. - ICondDBReader::IOVList find_holes(const ICondDBReader::IOVList& data, const ICondDBReader::IOV& iov); -} - -#endif diff --git a/Det/DetCond/src/component/LoadDDDB.cpp b/Det/DetCond/src/component/LoadDDDB.cpp deleted file mode 100755 index 08beaac28..000000000 --- a/Det/DetCond/src/component/LoadDDDB.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Include files - -// from Gaudi -#include "GaudiKernel/DataStoreItem.h" -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/GaudiException.h" - -// from LHCb -#include "Kernel/ICondDBInfo.h" - -// local -#include "LoadDDDB.h" - -//----------------------------------------------------------------------------- -// Implementation file for class : LoadDDDB -// -// 2005-10-14 : Marco Clemencic -//----------------------------------------------------------------------------- - -// Declaration of the Algorithm Factory -DECLARE_ALGORITHM_FACTORY( LoadDDDB ) - - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -LoadDDDB::LoadDDDB( const std::string& name, - ISvcLocator* pSvcLocator) - : GaudiAlgorithm ( name , pSvcLocator ) -{ - declareProperty("Node", m_treeToLoad = "/dd*"); -} -//============================================================================= -// Destructor -//============================================================================= -LoadDDDB::~LoadDDDB() {} - -//============================================================================= -// Initialization -//============================================================================= -StatusCode LoadDDDB::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) - debug() << "==> Initialize" << endmsg; - - std::vector<LHCb::CondDBNameTagPair> tmp; - svc<ICondDBInfo>("CondDBCnvSvc",true)->defaultTags(tmp); - - std::vector<LHCb::CondDBNameTagPair>::iterator db; - for ( db = tmp.begin(); db != tmp.end(); ++db ) { - info() << "Database " << db->first << " tag " << db->second << endmsg; - } - - updMgrSvc(); // trigger the initialization of the Condition Update sub-system - return StatusCode::SUCCESS; -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode LoadDDDB::execute() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Execute" << endmsg; - - info() << "Loading the DDDB" << endmsg; - - try { - detSvc()->addPreLoadItem(m_treeToLoad); - detSvc()->preLoad(); - } catch (GaudiException &x) { - fatal() << "Gaught GaudiException" << endmsg; - int i = 0; - for ( GaudiException *ex = &x; 0 != ex; ex = ex->previous() ) { - fatal() << std::string(i++,' ') << " ==> " << ex->what() << endmsg; - } - return StatusCode::FAILURE; - } catch (std::exception &x) { - fatal() << "Gaught exception '" << System::typeinfoName(typeid(x)) << "'" - << endmsg; - fatal() << " ==> " << x.what() << endmsg; - return StatusCode::FAILURE; - } catch (...) { - fatal() << "Gaught unknown exception!!" << endmsg; - return StatusCode::FAILURE; - } - info() << "done." << endmsg; - return StatusCode::SUCCESS; -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode LoadDDDB::finalize() { - - if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) debug() << "==> Finalize" << endmsg; - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -//============================================================================= diff --git a/Det/DetCond/src/component/LoadDDDB.h b/Det/DetCond/src/component/LoadDDDB.h deleted file mode 100755 index 584e4f0ac..000000000 --- a/Det/DetCond/src/component/LoadDDDB.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef LOADDDDB_H -#define LOADDDDB_H 1 - -// Include files -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" - - -/** @class LoadDDDB LoadDDDB.h - * - * Load entries in the detector transient store using IDataSvc::preLoad(). - * The node to be loaded is set with the option LoadDDDB.Node. - * - * @author Marco Clemencic - * @date 2005-10-14 - */ -class LoadDDDB : public GaudiAlgorithm { -public: - /// Standard constructor - LoadDDDB( const std::string& name, ISvcLocator* pSvcLocator ); - - virtual ~LoadDDDB( ); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization - -protected: - -private: - - std::string m_treeToLoad; - -}; -#endif // LOADDDDB_H diff --git a/Det/DetCond/src/component/RelyConverter.cpp b/Det/DetCond/src/component/RelyConverter.cpp deleted file mode 100755 index f9b5b8a11..000000000 --- a/Det/DetCond/src/component/RelyConverter.cpp +++ /dev/null @@ -1,479 +0,0 @@ -// Include files -#include "RelyConverter.h" - -#include "GaudiKernel/IConversionSvc.h" -#include "GaudiKernel/MsgStream.h" -#include "GaudiKernel/IOpaqueAddress.h" -#include "GaudiKernel/IRegistry.h" -#include "GaudiKernel/ISvcLocator.h" -#include "GaudiKernel/DataObject.h" -#include "GaudiKernel/Time.h" -#include "GaudiKernel/IDataManagerSvc.h" - -#include "DetDesc/ValidDataObject.h" - -#include "CoolKernel/IObject.h" -#include "CoolKernel/IRecord.h" -#include "CoolKernel/RecordException.h" - -#include <string> -#include <sstream> - -// local - -//----------------------------------------------------------------------------- -// Implementation file for class : RelyConverter -// -// 2004-12-03 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------- -// Instantiation of a static factory class used by clients to create -// instances of this service -// ----------------------------------------------------------------------- -DECLARE_CONVERTER_FACTORY(RelyConverter) - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -RelyConverter::RelyConverter(ISvcLocator* svc): - CondDBGenericCnv(svc,RelyConverter::classID()), - m_detPersSvc(NULL) -{} -//============================================================================= -// Destructor -//============================================================================= -RelyConverter::~RelyConverter() {} - -//========================================================================= -// Initialization -//========================================================================= -StatusCode RelyConverter::initialize() { - // Initializes the grand father - StatusCode sc = CondDBGenericCnv::initialize(); - - sc = serviceLocator()->service("DetectorPersistencySvc", m_detPersSvc, true); - if ( !sc.isSuccess() ) { - MsgStream log(msgSvc(),"RelyConverter"); - log << MSG::ERROR << "Cannot locate IConversionSvc interface of DetectorPersistencySvc" << endmsg; - return sc; - } else { - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Retrieved IConversionSvc interface of DetectorPersistencySvc" << endmsg; - } - return sc; -} - -//========================================================================= -// Finalization -//========================================================================= -StatusCode RelyConverter::finalize() { - m_detPersSvc->release(); - return CondDBGenericCnv::finalize(); -} - -//========================================================================= -// Create the transient representation -//========================================================================= -StatusCode RelyConverter::createObj (IOpaqueAddress* pAddress, DataObject *&pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering createObj" << endmsg; - - StatusCode sc = i_delegatedCreation(pAddress,pObject,CreateObject); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot create the object " << pAddress->registry()->identifier() << endmsg; - return sc; - } - - return StatusCode::SUCCESS; -} - -//========================================================================= -// Fill references of the transient representation -//========================================================================= -StatusCode RelyConverter::fillObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering fillObjRefs" << endmsg; - - StatusCode sc = i_delegatedCreation(pAddress,pObject,FillObjectRefs); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot fill object's refs" << endmsg; - return sc; - } - - return StatusCode::SUCCESS; -} - -//========================================================================= -// Update transient representation from persistent one -//========================================================================= -StatusCode RelyConverter::updateObj (IOpaqueAddress* pAddress, DataObject* pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Method updateObj starting" << endmsg; - - DataObject* pNewObject; // create a new object and copy it to the old version - StatusCode sc = i_delegatedCreation(pAddress,pNewObject,CreateObject); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot create the new object" << endmsg; - return sc; - } - - // do the real update - // - // Since DataObject::operator= operator is not virtual, dynamic cast first! - // Overloaded virtual method Condition::update() must be properly defined! - // The memory pointed to by the old pointer must contain the new object - // Andrea Valassi - - ValidDataObject* pVDO = dynamic_cast<ValidDataObject*>(pObject); - ValidDataObject* pNewVDO = dynamic_cast<ValidDataObject*>(pNewObject); - if ( 0 == pVDO || 0 == pNewVDO ) { - log << MSG::ERROR - << "Cannot update objects other than ValidDataObject: " - << "update() must be defined!" - << endmsg; - return StatusCode::FAILURE; - } - // Deep copy the new Condition into the old DataObject - pVDO->update( *pNewVDO ); - - // Delete the useless Condition - delete pNewVDO; - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Object successfully updated" << endmsg; - return StatusCode::SUCCESS; -} - -//========================================================================= -// Update references of the transient representation -//========================================================================= -StatusCode RelyConverter::updateObjRefs (IOpaqueAddress* pAddress, DataObject *pObject) -{ - MsgStream log(msgSvc(),"RelyConverter"); - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "entering updateObjRefs" << endmsg; - - StatusCode sc = i_delegatedCreation(pAddress,pObject,UpdateObjectRefs); - if (sc.isFailure()){ - log << MSG::ERROR << "Cannot update object's refs" << endmsg; - return sc; - } - - return StatusCode::SUCCESS; -} - -//========================================================================= -// Create the persistent representation -//========================================================================= -StatusCode RelyConverter::createRep (DataObject* /*pObject*/, IOpaqueAddress*& /*pAddress*/) -{ - MsgStream log(msgSvc(),"RelyConverter"); - log << MSG::WARNING << "createRep() not implemented" << endmsg; - return StatusCode::SUCCESS; -} - -//========================================================================= -// Update the persistent representation -//========================================================================= -StatusCode RelyConverter::updateRep (IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) -{ - MsgStream log(msgSvc(),"RelyConverter"); - log << MSG::WARNING << "updateRep() not implemented" << endmsg; - return StatusCode::SUCCESS; -} - -//========================================================================= -// Create an object by delegation -//========================================================================= -StatusCode RelyConverter::i_delegatedCreation(IOpaqueAddress* pAddress, DataObject *&pObject, Operation op){ - StatusCode sc; - - MsgStream log(msgSvc(),"RelyConverter"); - - ICondDBReader::DataPtr data; - std::string description; - Gaudi::Time since,until; - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Entering \"i_delegatedCreation\"" << endmsg; - - std::string path = pAddress->par()[0]; - std::string data_field_name = "data"; - - // Extract the COOL field name from the condition path - std::string::size_type at_pos = path.find('@'); - if ( at_pos != path.npos ) { - std::string::size_type slash_pos = path.rfind('/',at_pos); - if ( slash_pos+1 < at_pos ) { // item name is not null - data_field_name = path.substr(slash_pos+1,at_pos - (slash_pos +1)); - } // if I have "/@", I should use the default ("data") - // always remove '@' from the path - path = path.substr(0,slash_pos+1) + path.substr(at_pos+1); - } - - sc = getObject(path, pAddress->ipar()[0], data, description, since, until); - if ( !sc.isSuccess() ) return sc; - - if ( !data ) { - switch (op) { - case CreateObject: - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Path points to a FolderSet: create a directory" << endmsg; - - // I hit a FolderSet!!! I handle it here (at least for the moment, since it's the only CondDB real converter) - pObject = new DataObject(); - - break; - - case FillObjectRefs: - { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Create addresses for sub-folders" << endmsg; - - // find subnodes - std::vector<std::string> children; - - sc = getChildNodes(path,children); - if ( !sc.isSuccess() ) return sc; - - // add registries for the sub folders - for ( std::vector<std::string>::iterator c = children.begin(); c != children.end(); ++c ) { - - IOpaqueAddress *childAddress; - std::string par[2]; - // in current implementation, the child folders have a '/' in front. - // So I need to treat in a different way the case of a parent COOL root folderset - // to avoid thing like "//folder" - if ( path == "/" ) { - par[0] = *c; - } else { - par[0] = path + *c; - } - par[1] = *c; - unsigned long ipar[2] = { 0,0 }; - - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Create address for " << par[0] << endmsg; - sc = conversionSvc()->addressCreator()->createAddress(CONDDB_StorageType, - CLID_Catalog, - par, - ipar, - childAddress); - if ( !sc.isSuccess() ) return sc; - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Address created" << endmsg; - - sc = dataManager()->registerAddress(pAddress->registry(), *c, childAddress); - if ( !sc.isSuccess() ) return sc; - if( UNLIKELY( log.level() <= MSG::VERBOSE ) ) - log << MSG::VERBOSE << "Address registered" << endmsg; - } - } - break; - - case UpdateObjectRefs: - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Update references not supported for FolderSet" << endmsg; - break; - } - - return StatusCode::SUCCESS; - } - - long storage_type = getStorageType(path,description); - if (storage_type <= 0) { - log << MSG::ERROR << - "Folder description does not contain a valid storage type: " << endmsg; - log << MSG::ERROR << "desc = \"" << description << "\"" << endmsg; - return StatusCode::FAILURE; - } - - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "delegate to DetectorPersistencySvc" << endmsg; - - std::string xml_data; - try { - xml_data = (*data.get())[data_field_name].data<std::string>(); - } catch (cool::RecordSpecificationUnknownField &e) { - log << MSG::ERROR << "I cannot find the data inside COOL object: " << e.what() << endmsg; - return StatusCode::FAILURE; - } - - // for XML string temporary address, I need a way to know which is the originating href - std::ostringstream src_href; - src_href << "conddb:" << pAddress->par()[0] << ":" << pAddress->ipar()[0]; - - // Create temporary address for the relevant type and classID - IOpaqueAddress *tmpAddress = createTmpAddress(src_href.str(), - storage_type, - pAddress->par()[1], - pAddress->clID(), - xml_data, - log, - conversionSvc()->addressCreator()); - if (!tmpAddress) return StatusCode::FAILURE; - - tmpAddress->addRef(); - if ( pAddress->registry() ){ - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "register tmpAddress to registry " << pAddress->registry()->identifier() - << endmsg; - } else { - log << MSG::WARNING << "the address does not have a registry" << endmsg; - } - tmpAddress->setRegistry(pAddress->registry()); - if (tmpAddress->registry()) { - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "tmpAddress registered to registry " << tmpAddress->registry()->identifier() - << endmsg; - } else { - log << MSG::WARNING << "tmpAddress not registered!" << endmsg; - } - - switch (op) { - case CreateObject: - sc = m_detPersSvc->createObj ( tmpAddress, pObject ); - break; - case FillObjectRefs: - sc = m_detPersSvc->fillObjRefs ( tmpAddress, pObject ); - break; - case UpdateObjectRefs: - sc = m_detPersSvc->updateObjRefs ( tmpAddress, pObject ); - break; - } - - tmpAddress->release(); - if ( sc.isFailure() ) { - log << MSG::ERROR - << "Persistency service could not create a new object" << endmsg; - return sc; - } - - if (op == CreateObject){ - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "Setting object validity" << endmsg; - setObjValidity(since,until,pObject); - - } - if( UNLIKELY( log.level() <= MSG::DEBUG ) ) - log << MSG::DEBUG << "New object successfully created" << endmsg; - - return StatusCode::SUCCESS; -} - -//============================================================================= - -long RelyConverter::getStorageType(const std::string &path, const std::string &desc){ - // the description string should contain a substring of the form (regexp) - // "< *storage_type *= *[0-9]+ *>" - - if ( path.rfind(".xml") != path.npos ) return XML_StorageType; - - const char delimiter_begin = '<'; - const char delimiter_end = '>'; - const char delimiter_sep = '='; - const std::string delimiter_keyword = "storage_type"; - - std::string::size_type pos_start; - std::string::size_type pos_end; - std::string::size_type pos_max; - - pos_start = pos_end = pos_max = desc.size(); - - std::string::size_type tmp_pos = 0; - - while ( pos_start == pos_max || pos_end <= pos_start ){ - // find the next occurrence of '<' - tmp_pos = desc.find(delimiter_begin,tmp_pos); - if (tmp_pos >= pos_max) break; // not found - - // skip spaces - ++tmp_pos; - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // check for the keyword - if (desc.compare(tmp_pos, delimiter_keyword.size(), delimiter_keyword) != 0) continue; - - // skip spaces - tmp_pos += delimiter_keyword.size(); - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // check for the separator - if ( desc[tmp_pos] != delimiter_sep ) continue; - - // skip spaces - ++tmp_pos; - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // here should start the "int" - pos_start = tmp_pos; - - // "count" the digits - while ( desc[tmp_pos] >= '0' && desc[tmp_pos] <= '9' ) ++tmp_pos; - - // here should be just after the "int" - pos_end = tmp_pos; - - if ( pos_start == pos_end ) continue; // no number found - - // skip spaces - while ( desc[tmp_pos] == ' ' || desc[tmp_pos] == '\t' || desc[tmp_pos] == '\n' ) ++tmp_pos; - - // check for the delimiter_end - if ( desc[tmp_pos] != delimiter_end ) { - // force another loop even if the number was found; - pos_start = pos_end = pos_max; - continue; - } - } - - if ( pos_start == pos_max || pos_end <= pos_start ) { // not found - return -1; - } - - std::istringstream i(desc.substr(pos_start, pos_end-pos_start)); - - long st; - i >> st; - - return st; -} - -IOpaqueAddress *RelyConverter::createTmpAddress(const std::string &src, - long storageType, - const std::string &name, - const CLID &clId, - const std::string &data, - MsgStream &log, - SmartIF<IAddressCreator>& creator) { - - if (storageType <= 0) { - log << MSG::ERROR << "invalid storage type " << storageType << endmsg; - return 0; - } - - // Create temporary address for the relevant type and classID - IOpaqueAddress *tmpAddress; - - // for XML string temporary address, I need a way to know which is the originating href - const std::string par[3] = { data, - name, - src }; - unsigned long ipar[2] = { 1,0 }; - StatusCode sc = creator->createAddress(storageType, clId , par, ipar, tmpAddress); - if (sc.isFailure()){ - log << MSG::ERROR - << "Persistency service could not create a new address" << endmsg; - return 0; - } - - return tmpAddress; -} diff --git a/Det/DetCond/src/component/RelyConverter.h b/Det/DetCond/src/component/RelyConverter.h deleted file mode 100755 index 0af71524c..000000000 --- a/Det/DetCond/src/component/RelyConverter.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef COMPONENT_RELYCONVERTER_H -#define COMPONENT_RELYCONVERTER_H 1 - -// Include files -#include "DetCond/CondDBGenericCnv.h" - -// Forward and external declarations -class ISvcLocator; -template <class TYPE> class CnvFactory; - -/** @class RelyConverter RelyConverter.h component/RelyConverter.cpp - * - * ConditionsDBCnvSvc rely on the functionalities provided by the XmlCnvSvc. - * RelyConverter delegate the creation of the object to the XmlCnvSvc - * (via DetectorPersistencySvc). - * - * @author Marco CLEMENCIC - * @date 2004-12-03 - */ -class RelyConverter: public CondDBGenericCnv { - - /// Friend needed for instantiation - friend class CnvFactory<RelyConverter>; - -public: - - /// Operations that can be performed by delegation - enum Operation { - CreateObject, - FillObjectRefs, - UpdateObjectRefs - }; - - /** - * Initializes the converter - * @return status depending on the completion of the call - */ - virtual StatusCode initialize(); - - /** - * Finalizes the converter - * @return status depending on the completion of the call - */ - virtual StatusCode finalize(); - - /** - * Creates the transient representation of an object. - * @param pAddress the address of the object representation - * @param pObject the object created - * @return status depending on the completion of the call - */ - virtual StatusCode createObj (IOpaqueAddress *pAddress, - DataObject *&pObject); - /** - * Resolve the references of the created transient object. - * @param pAddress the address of the object representation - * @param pObject the object created - * @return status depending on the completion of the call - */ - virtual StatusCode fillObjRefs (IOpaqueAddress *pAddress, - DataObject *pObject); - /** - * Resolve the references of the just updated transient object. - * @param pAddress the address of the object representation - * @param pObject the object created - * @return status depending on the completion of the call - */ - virtual StatusCode updateObjRefs (IOpaqueAddress *pAddress, - DataObject *pObject); - /** - * Updates the transient object from the other representation (not implemented). - * @param pAddress the address of the object representation - * @param pObject the object updated - * @return status depending on the completion of the call - */ - virtual StatusCode updateObj (IOpaqueAddress *pAddress, - DataObject *pObject); - - /** - * Converts the transient object to the requested representation (not implemented). - * @param refpAddress the address of the object representation - * @param pObject the object to convert - * @return status depending on the completion of the call - */ - virtual StatusCode createRep (DataObject* pObject, - IOpaqueAddress*& refpAddress); - - /** - * Updates the converted representation of a transient object. - * @param pAddress the address of the object representation - * @param pObject the object whose representation has to be updated - * @return status depending on the completion of the call - */ - virtual StatusCode updateRep (IOpaqueAddress* pAddress, - DataObject* pObject); - - /** - * Accessor to the type of elements that this converter converts. - * @return the classID for this type - */ - static const CLID& classID () { return CLID_Any; } - -protected: - /// Standard constructor - RelyConverter(ISvcLocator* svc); - virtual ~RelyConverter( ); ///< Destructor - -private: - - /** - * Do the needed steps to perform a creation by delegation. - */ - StatusCode i_delegatedCreation(IOpaqueAddress* pAddress, - DataObject *&pObject, - Operation op = CreateObject); - -public: - /** - * Extract the storage_type from the folder or description. - */ - static long getStorageType(const std::string &path, const std::string &desc); - - /** Generate a temporary IOpaqueAddress to be passed to a PersistencySvc for - * the actual conversion. - * - * @param src originating URL (required by the XML format) - * @param storageType storage type ID (@see getStorageType) - * @param name name of the object inside the storage container - * @param data data to embed in the address - * @param log MsgStream instance to report errors - * @param creator IAdressCreator to use - * - * @return an IOpaqueAddress pointer in case of success, 0 in case of failure. - */ - static IOpaqueAddress *createTmpAddress(const std::string &src, - long storageType, - const std::string &name, - const CLID &clId, - const std::string &data, - MsgStream &log, - SmartIF<IAddressCreator>& creator); - -private: - /// Handle to the IConversionSvc interface of the DetectorPersistencySvc - IConversionSvc* m_detPersSvc; - -}; -#endif // COMPONENT_XMLRELYCNV_H diff --git a/Det/DetCond/src/component/RunStampCheck.cpp b/Det/DetCond/src/component/RunStampCheck.cpp deleted file mode 100644 index ee7d310d0..000000000 --- a/Det/DetCond/src/component/RunStampCheck.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "GaudiKernel/Service.h" -#include "GaudiKernel/IIncidentListener.h" -#include "GaudiKernel/IIncidentSvc.h" -#include "GaudiKernel/Kernel.h" -#include "GaudiKernel/IDetDataSvc.h" -#include "GaudiKernel/IEventProcessor.h" -#include "DetCond/ICondDBReader.h" - -/** Simple service to check if the run stamp condition exists for the current - * event. - * - * To ensure that the content of the conditions database includes alignments - * and calibrations for the event being processed, when these conditions are - * stored we also store a special condition with closed Interval Of Validity - * (IOV) covering only the run for which they are valid (RunStamp condition). - * - * The time line of the RunStamp conditions is not completely covered, and the - * holes in the time line implicitly flag the events for which the alignments - * are not available. - * - * When RunStampCheck is instantiated in a Gaudi application, it checks for - * each event time if the RunStamp condition exists or not, in which case the - * application is terminated with an error code. - * - * So, to enable the check, it is enough to add to the options: - * \code{.py} - * from Configurables import ApplicationMgr, RunStampCheck - * ApplicationMgr().ExtSvc.append(RunStampCheck()) - * \endcode - * - * \see https://its.cern.ch/jira/browse/LBCORE-831 - * \see https://its.cern.ch/jira/browse/LHCBPS-1421 - */ -class RunStampCheck: public extends1<Service, IIncidentListener> { -public: - /// Constructor. Declares properties. - RunStampCheck(const std::string& name, ISvcLocator* svcloc): - base_class(name, svcloc) { - declareProperty("RunStamp", m_runStampCondition, - "Path in the conditions database of the RunStamp condition."); - declareProperty("CondDBReader", m_condDBReaderName, - "Name of the ICondDBReader instance to query for the RunStamp."); - } - /// Connect to the required services and register as BeginEvent listener. - StatusCode start() override { - StatusCode sc = Service::start(); - if (UNLIKELY(!sc)) return sc; - - // ensure that we have the EventClocksvc (to get the current event time in - // the DetectorDataSvc). - if (UNLIKELY(!serviceLocator()->service("EventClockSvc"))) { - error() << "Cannot get EventClockSvc" << endmsg; - return StatusCode::FAILURE; - } - - m_incSvc = serviceLocator()->service("IncidentSvc"); - if (UNLIKELY(!m_incSvc)) { - error() << "Cannot get IncidentSvc" << endmsg; - return StatusCode::FAILURE; - } - m_incSvc->addListener(this, IncidentType::BeginEvent); - - m_condDBReader = serviceLocator()->service(m_condDBReaderName); - if (UNLIKELY(!m_condDBReader)) { - error() << "Cannot get " << m_condDBReaderName << endmsg; - return StatusCode::FAILURE; - } - - m_detSvc = serviceLocator()->service("DetectorDataSvc"); - if (UNLIKELY(!m_detSvc)) { - error() << "Cannot get DetectorDataSvc" << endmsg; - return StatusCode::FAILURE; - } - - m_evtProc = serviceLocator(); - if (UNLIKELY(!m_detSvc)) { - error() << "Cannot get IEventProcessor" << endmsg; - return StatusCode::FAILURE; - } - - // reset the IOV for the current run (to something not valid) - m_currentRunIOV = {Gaudi::Time::epoch(), Gaudi::Time::epoch()}; - return sc; - } - /// Deregister as BeginEvent listener and release reference to services. - StatusCode stop() override { - m_incSvc->removeListener(this, IncidentType::BeginEvent); - m_incSvc.reset(); - m_condDBReader.reset(); - m_detSvc.reset(); - m_evtProc.reset(); - return Service::stop(); - } - /// Handle the BeginEvent incident to check if the RunStamp condition exists. - void handle(const Incident&) override { - auto when = m_detSvc->eventTime(); - // run the check only if the current event time falls outside the boundaries - // of the current run - if (when < m_currentRunIOV.since || when >= m_currentRunIOV.until) { - if (UNLIKELY(msgLevel(MSG::DEBUG))) - debug() << "Checking '" << m_runStampCondition - << "' for event time " << when << endmsg; - ICondDBReader::DataPtr p; - std::string desc; - StatusCode sc = m_condDBReader->getObject(m_runStampCondition, when, - p, desc, - m_currentRunIOV.since, m_currentRunIOV.until); - if (!sc) { - // we didn't manage to get the entry from the DB: we do not have data - // for this run - error() << "Database not up-to-date. No valid data for run at " - << when.format(false, "%Y-%m-%d %H:%M:%S") - << "." << when.nanoformat() << " UTC" << endmsg; - m_evtProc->stopRun(); - } else if (UNLIKELY(msgLevel(MSG::DEBUG))) { - debug() << "Found '" << m_runStampCondition - << "' valid in [" << m_currentRunIOV.since - << ", " << m_currentRunIOV.until << ")" << endmsg; - } - } - } -private: - /// Path in the conditions database of the RunStamp condition. - std::string m_runStampCondition = "/Conditions/Online/LHCb/RunStamp.xml"; - /// Path in the conditions database of the RunStamp condition. - std::string m_condDBReaderName = "CondDBCnvSvc"; - /// reference to the incident service. - SmartIF<IIncidentSvc> m_incSvc; - /// reference to the CondDB reader. - SmartIF<ICondDBReader> m_condDBReader; - /// reference to the detector transient store. - SmartIF<IDetDataSvc> m_detSvc; - /// reference to the event processor. - SmartIF<IEventProcessor> m_evtProc; - - /// IOV of the current RunStamp. - ICondDBReader::IOV m_currentRunIOV; -}; - -DECLARE_COMPONENT(RunStampCheck) diff --git a/Det/DetCond/src/dict/DetCondDict.h b/Det/DetCond/src/dict/DetCondDict.h deleted file mode 100755 index 48ebf7619..000000000 --- a/Det/DetCond/src/dict/DetCondDict.h +++ /dev/null @@ -1,38 +0,0 @@ -// ============================================================================ -#ifndef DETCOND_DETCONDDICT_H -#define DETCOND_DETCONDDICT_H 1 -// ============================================================================ -// Hack to get round gccxml parsing problem (SEAL bug 9704) -// ============================================================================ -#ifdef _WIN32 -#define LONG_LONG_MAX 0x7fffffffffffffffLL /*maximum signed __int64 value */ -#define LONG_LONG_MIN 0x8000000000000000LL /*minimum signed __int64 value */ -#define ULONG_LONG_MAX 0xffffffffffffffffLL /*maximum unsigned __int64 value */ -#endif -// ============================================================================ -// GaudiKernel -// ============================================================================ -#include "GaudiKernel/Time.h" -// ============================================================================ -// DetCond -// ============================================================================ -#include "DetCond/ICondDBAccessSvc.h" -#include "DetCond/ICondDBEditor.h" -#include "DetCond/ICondDBReader.h" -#include "DetCond/ICOOLConfSvc.h" -// ============================================================================ -// CORAL (not available through PyCool) -// ============================================================================ -#include "RelationalAccess/ConnectionService.h" -#include "RelationalAccess/IConnectionServiceConfiguration.h" -#include "RelationalAccess/IReplicaSortingAlgorithm.h" -// ============================================================================ -namespace _instantiations { - struct Instantiations { - ICondDBReader::IOVList _i1; - }; -} -// ============================================================================ -#endif // DETCOND_DETCONDDICT_H -// ============================================================================ - diff --git a/Det/DetCond/src/dict/DetCondDict.xml b/Det/DetCond/src/dict/DetCondDict.xml deleted file mode 100755 index f77b7e2a3..000000000 --- a/Det/DetCond/src/dict/DetCondDict.xml +++ /dev/null @@ -1,14 +0,0 @@ -<lcgdict> - - <class name="ICondDBReader" /> - <class name="ICondDBReader::IOV" /> - <class name="ICondDBReader::IOVList" /> - <class name="ICondDBEditor" /> - <class name="ICondDBAccessSvc" /> - <class name="ICOOLConfSvc" /> - - <class name="coral::IReplicaSortingAlgorithm" /> - <class name="coral::IConnectionService" /> - <class name="coral::IConnectionServiceConfiguration" /> - -</lcgdict> diff --git a/Det/DetCond/tests/data/DQFLAGS.db b/Det/DetCond/tests/data/DQFLAGS.db deleted file mode 100644 index 3d22d8afaf1d4504118821a0ce9ea7e18272305a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48128 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 diff --git a/Det/DetCond/tests/data/HBTEST.db b/Det/DetCond/tests/data/HBTEST.db deleted file mode 100644 index 9f920f0ad02fe5b7fa8eb3bd9665321079dd0863..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76800 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 diff --git a/Det/DetCond/tests/data/RSTEST.db b/Det/DetCond/tests/data/RSTEST.db deleted file mode 100644 index 3515b986f69afa926d429fed453e8b8ec2bccefd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48128 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 RI0E+s0c!at2=p7{{{!*sn#TYD diff --git a/Det/DetCond/tests/data/TESTDB0.db b/Det/DetCond/tests/data/TESTDB0.db deleted file mode 100755 index 8b4accc2b6482e618dd4f1a4f2889ca964a149c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183296 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 OmqP}+Lj*P-f&UM@pb-H8 diff --git a/Det/DetCond/tests/data/TESTDB1.db b/Det/DetCond/tests/data/TESTDB1.db deleted file mode 100755 index 58d9abbd4b60ffef0f56a298db91069aaf558389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79872 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 diff --git a/Det/DetCond/tests/data/TESTDB2.db b/Det/DetCond/tests/data/TESTDB2.db deleted file mode 100755 index 85025de79ca3b6799d245910308c24dd3edbe17d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79872 zcmeHQYit|Yb-s5lC9Yqqeb}bgUa!ZrwH8;B`I1CYmh7d-k;D~6$|U8ifu>y9QnuP! zk65y?Mr)+BcY`4L5uiYT0tMQiMgR2AB52bTMX_j+^hb)KL4hpLqUZv_I!(9f0!<%D z(e1f+W;k=_LD811=NXYB&VAqSKIYtW&ONtswXm=@uYPIy_TucCnj`^2DS2I02_bFp zEyCBlhT#V_9~{4J&eG2|();mQp3q_Tm)v8D{gVAB`;7f7`-FYW{*nEN{gC|)`)l1( ziir=8g+Myk9-6v9$->gy{JX1Pz6Fh1o4vEPES_ssty0a6CThh}POH?C(&IDf_ST~& zq^QAkTkBEdQq=bQEEwwUruF#R?2TLVH<xeE-l`ep{?e~I9s}93mZ@rLH8Wb!REKBR z!kk*w-mI#{5`1S0g&uWjc5z;~^{68C#&aV~q&`4{p;U@KI3z-tWy_7$GSzB1KRUx* z4Adk?MJh|!GfY_RQp5IGwPI#U3+u(~k$tXZ3NsBab-J9N%9O9GliKwzIh;r#qDJyc zd+3WPsiC2xjPZebB@efu9NhW_;r3b*ZWnstcJ?gXPQDDcW5?lk<Otjj2H|#qiJ!`E z5%y2)&)M&@d#ud5*-7P*@;l&&7b5VK5jcL3MM9PAgf^9_UDL{ye5shY7`qrN9tfPP zAIe^<)W9!0nJ=Et&kd>N*;~0;7_hUe^A~Tftn}Pf;}-||2h>C?p6HFGdSip|b10S= zN+#9WyR)}uS63HQ?cEjieC!$4S!yI#nyH>I!Xz=IE-kOAt9MpbmT#}k==sW<Pg zCRXn*spmU_>{O_%6|_u6OG1$no$V~%n=f6fRVFfJEmzU5ieYWe0N_)pfn#SI1gmDo zeS(3H2zEZe;@$9&;6cU2CZ%ThoMtT2=^LVQMq%9-_@wTUf|%>iP}YAsr;TN13RNS_ zbXgnAziF2GAhhp6c8Rbe`&D=+{|3B|m)RxuhwQi6Up(ce$K(-#-HgBsEJEd(>tF{v zM;nt&zIfm{)@eP%r1Q)nc8VHvO7J*~Q}=Yz&Yk&)muHza!`U%i1b89j`GLL2x~XGM zP)@LZ>NO2e{{C-c=Lq`=`!n`Ub{&4=g$N)576N^3fsXNb%zR^x#bU9(nt0o1Co;vN zR;Z0lx;^^>u2{)tv2@RF7U;Ot-B@KAR6s4uhq#rC;oPn8z>Rg48F<<=@G%<b=;)3$ zs$ql{<DYz=u-{|7${*41!p~iK)mPe%QhF*IrJ+)ZMmV1$9#5qMO6kTs^EcNL(F`nx zr)F28W6QVZ=5JT#*OF1gOC4TagXQPj^R=~mEAu0%%al`~aiA&tdt=Go_+Txb9O_RE z^(BGU?28S=ld+gOK2=>e0G$I`b*Qp-dtvGA_`no#cM{nJnxwJjZ1gfd;mg5{URSBF z1iY%uj4H?ds~mrfDktLUcz=AbFYZ@mDL}I->pk3Fmn4v+a+O6GXO)w%1`q?Sa-Tts z&nAgz<OVZJp|(bKw=)q73a{2mKo5xxCSpndy4eDJPL>r8_-RM>l$d!M|C?plpNypk zQYrroZ2>+fZ_%UBlRF$4lBj<Uu~-6<kHh-Mr-w=bJ|~?1Z(|=5_6znO?BCcU_=y)H zfC%gv1lky-fi`|;0e)8)zf*<Z3Dw8{xA^$~l>I&XHv86|sW?^y5!jswoMBn&PrW7D zn)}BCA(r%t&knQG4R;v-9W-i;|Bnd!ACSuZg#9!7Xm>(}rA7o00UH9r0KDV_N}Kr4 zlz{lJP$vFUqO=F#?N0>%k16+wa-R*bx^h`z^!s#|@&IhL-*-QErTl*{3E@4oE$kWq zm0E*OCpoii)`Q^uzW`YzWRaEF*V$i@SK-ffWe&85W}=ePfk%CH?Gi2*ZPc~lbeQM! zek~9TUAREMeqU0$5P?j-ka%eGR<aO&Lb-zfs^xQGb*5O!j~BIEzF1Xz!oqnPq_f4U zkEf)FA%c&A%E)x4I?+(i5U!vnlP%|`t00e-J@OTh2#<x;(NYP16wOR!L69R#u~N<3 z^gjxjN_DD~tK~qar4e$hRLE&%QwE+dj)zsfPKL*H=6a!&$yKJctTT?`Rm&F(`68rf zVp5qXl{qSM3N_G`0THk>5tGH{k-o|1_Kpaga3Q{ykTtU8yi2aL<K+kO1f$Q--^kS! zU)GT^J3^!fs-3?&qjA+6N4vWHpmVr73xpagl{M&1y7rAoq|uimDqyBT$I5CI(BrYG zQ+4UtL6V@IvjK&uji_Ngx$+ku|CD`?zy~ix01?=o2&8BrN=wqb#C4GZUQ!Q9h{gGT zl>G~V4_=4>BCux>IL4yXH9?5=e>-`Hkay^-bV2D;>g;<!3-po?;m>t-91hmg&jdr! zD1C6&O~dmk$Cbq)gO-2dh=KxC8=BUfE)yD*Vj%!I&Tyhk*09dbl=&K<W++#i1hGy~ zdy(HVQ7I=1WZfpLf9ewlgQ0YqKIoQk<8uC(5QE#nlU<+nUJc2Cwh)cUL+znjdcD=4 zTs&(@D7$w&$Q}-cIy>omc?lQ0VgUdBoHqvCtJ#7O{5_V5+*MkVaEC%EJ6Wq#Gu0VL z(d;qi5{d`#S`t>SS76yCE$`&6WUfzo!bVY~#fVi9&(()mQ?#`1NF8YpO?Ix=B#@nr z55b?F*XjQc3G*23uHlakhyWt6!w?vzfwV>X%d;!-qW@#D<X}ABr>h9*^#6|u`|%E| z78VB)Km;}ifs-uVApPYDLeT#p0Kf|oKm_(70{s1t<9{DEJXRSI00eOSV>dtq_AdgQ z|A+7Y{oDRn^Zkv0?fw7a{zd|8j|l8P1o->EjbsUYepC4q<-gc>NQytMb6q*n9;)=} z^2XG&Ez2J5h7Bq&yqA7a*ns<5#3}l<?*IoeC4YR;R{+d?g$!6%))YqWoZ7z)!*4xd zBNRkx5-2;7FXYxsNe|?aP)~SWxv*STN2z+kQvOcau;kf@$|cP$3XGk)ug(mb7S2-> z7C@+2im-NJx1>|+D7hWL$4XX>j2vwbUF~i`;LUr7rF;Mn+~H{b%CTT5nWPUoy}F)V z6~l<ZosKu{f;_|)Dq(2H+e6ortpWgLbAiAM9Ma|gpAh!RIwKyv5dlPCw;~Xt0k8&Y z>gL(zG+qAxh_FYywQ5*yL;w+34*_lxz+?E^<^Lf_gPRA&>%A&0Oh!iN*DmSQ;nZ~P zn#Wc3ad$3Ne1hSc#av){(*8ov+rFj{s<isjgs*cP+x2$AnxzD5mYXBKB)d;H0lMAC z=O~QSz{m?5SqOz}{68G`hyWt6&k*42|90|KLcU7x(mz)IKzYPIApP*y?3#R~)eRtt z#?}^#{lGO4Eq4_%3e*=v!BB56eR#yljuAV3Y=nz=KH<xVu{H*o8!sALIrPmx8{8RW zrs{nAG~8R;CT?e+`k&ST%QR6R3p&%~rTXGaUVsU!w7}Le0W+UZc>`v8H`_t8LjXHz z@tgetGwWjkX1cswpE%{W{VLw*qb6*;hgz<uy}^?MZ6W7x^5s@XpH&A75xLl}p!~nt zM2CKez}`jx>HodmzF0d%pcw+X{15m4Hp2-05P_YGfP4S1MfQ8{|AkWz5`)QfUq3%0 zK$rjF{@<P3zF0CuV1o!a_y1ZGgpmJHF#dt|KQ@RlMn?p;1p)W_-(s%&y#ELL;aH<o z8sGoh(qNb=BCxdxIN$%)1R>u4ZB!vtp+8Vg!r7s3k?+9Y7GL$dXM}X-VNjC)aao0R z_?uli1Fq-VLtlvdDpMF1n)MWf6sTd7+;ZcV&I9#{(|(d63nzQtmg^aR$&eLjD<wml zDVKecHZhLr3;W|@HK)MEG%fDjiqRA1RvK%i(Kobg)x(0{M5a<JYG2?c)H8Nl>}GnB zbw3ZoeX@~0GnUvs5t&q5m9JTqk>zWa`?>n*v%yd{P3w~jOLOz@+WV0es#dJcNJofT zUgr%c4ddqdVorP0vV|!R5Rpt+EfxI&guyntSyvsQh|d4}IblEF;vtXOAp(fN_8@S8 zw!`5-<Om!9r1SrN0q6g1Pf;*eL;w-k4g{?8KPmeqfe&7Y03xt|5C||r#rdC<{WpOR zUWfo9uul*W$AC7*|IY~f**>W_Rud7}zX&|nMq%ww$X7nsFP;BSz&1dVex$sj{3)CF z1gCzY7uc9_TF);mJv<i)hT?Jh{+B(N^_<l%Gda1-#byj)9zZaIeYw3R&(h5$hPbs# z9?t)PBU=ik;yC}piI?1Y2F?I2$j&nrIAIg^(0DMEJq-2;7PRY}&Qdu)o-bw!9%*of z^n{kld3epuuFaY!Zpyr8tJ2OrMYdXdZjhCkzg-Q^uFl2IzP54sNVNV^x8Cet+-u%$ zwQQ-D0H*Yt?l$i<+T4?6EyeX>S@QsPb~RM0M-5wGsgZhDPcWoGmwelUv#zIKnW-hc z3-{{!g)<|!UOLFs=!{TQ{$O;$h<)_9gaD$bkeLsRUF(+AjN7cBzD3jdf1eTdndi7i zM??S-*h>gJ8{h;$<NdFX|4#|~bT3sB>w*X%0xkqz;9@`cI_Up)GD6_<fAnva-{t%N z=~Y)uw?lm*5v*Un7z~Za>4WF}NU%~CsFOZ#8Z2T^HqBHU1aV{~(u~BhXhWdBY_zjM zi|MNbCt+5K>J>=(RbYlM7y7*`(A{bUtVEhsz`i<xa@toDk5QwEn4dONvZj-omU#e6 z6N=k{>@}+6IB!)Bw3XUS@z(Wl%$hm%a7_0e-d%l;Url=M|F>LY&2TX-GHfL-$<}c( zi|53}bdT%r|DO`}Q}+-@7eoLN*fR(m4Z_=BaQ|%Ye|`Lm{eQhs({A{_2HyyLyWq<; zWIN%zp{suR!Uo8Mmfx~ZlT7H^0GVLESJ$O;wvbGC*bh8huyFYP{U@?;=;Y`67^p+8 zuG>zbjWT@#u5Jmqx{q%{(5e4#QG&StZ$mR1Mn(j-8v*zJKWlimd!7H?-#5^oil_R; z{y(Arul$g}2QNfmFCg&XHF{VOx}_4O4<j~im*;j^X*jGqUI-b!^6ug-_3r%b)rIAy zk#PKCEUeBi-CUkqSbBRToUfF62M7Dpz47ps%Lj+g=1SS>^=VDb<#MAc2$`$elp4Od zyfim=V<?)d=Ax@>x9{9syK{T~;@sL?7^3iymk+AyFb}n`2AQZ!vy1cU2#7y#yfc4u zEe@enxQ16|Z_h3^Jaa<CymoIz1YKBK3tv{_>Tpzq5(!2dDMB_;Js+L^NB#f3(DAVj zh(PNIaQ%OZ^ndGsVMs(^2O{7_|C{W6Pl6|rNcO>}KY{i?c3^X2kr08+M!?PgGbae~ z{>SsbHydzF4-wcM2=Mhkj{n`!R#-|zV6ze6{Qoxc79nrZbM)7g|7GLkS7>gNa!I!x zt-szUHVZxI_Sh`MsStVN2zN=Wr*9?1$`I0HpAC1FY(H@a5BpE+AJA>2A5kOO{?>QW zK&*<Fu2u5k^8>+9Dn;MVc;En9YW!4c84AO(zZn`vm?nT&T9M9!kaSyJ9vDKRkFlr9 zW8;*(!N~x!$F_OLxzouiWD}7%6bp_Rw*_?^0N7}-vNoobHP{nYQDsDV<8*}^;Uf7| zd+3X)mQBdXCy6)IBDwQGeP9qaN~LK1E8dEvBCfX{EcZ$ojqJBq%8KrzK*|H~?NUbN zTGtol;~(Gun>62HGKjz~LjdXjUDjY&Ttr|K5y0`kiC|(<h`=sGK<NL0@n5w6yUQ95 zi;D<6DFSH!_eqh%c!<CrK|r_vtMmV(ghXi<y`vms-z7hQKfkMfH|=*&M_<j@+9a{` zE!RPRMz$45aI$S%q#R7^Z9EiWsMSr^R%K*CfaRX9pT6XGD1;Ttbtr`8b;*Fze@CGe z*5^<ND}dd~mT@S=!*f|b3vYeGh=851uDj%#wJvAf<6gig+Y4wll*__fu2s2|-bBvs z$Xi9z_5acSx8H<^?ufu1MF8!8@6m?EY9RvaA%OP3*Fy;X5rI92fXn{3PXD9*-#ypT zSRq8f3jv4yU!DK=4MM&_FVMeJ7THDi0sFuev3_E_VgKK-U|xSo^Ro?a@Eg2r!|Ptd zUiyxko?xQJl{6iNaVt>j0qkrrFJtp#e#Yj_^i6y5Zr<34S8e6OnUPyBou#Ggv}x*Y zs@$lQn`toKUDC_zmeh>ftf2lyyFB4%2+ly!vf<_~-0Mc+nsGfjPpf7n(yWx0CUNW9 zvh`Bl&k&qZ0n3J)y8@Y3D_|wktOA>2FIIp5qy2B!jE4@0z+OYZ!~VBE{?Y#LUTbQs z4<g_|z|;P(uK)KTVIMj|<0B$~2<!p`-1dKrr3f79;A#Ie)i(eJK+~xKwEwdUniq?R z2y7Gqr~Mymg3#^%q5a>DB8>5O4g!y9|5th)dfES#0_*_$zlqlE|0dA>@6PF$SQ12F z2O(hD|7`;*fF7YgQaY7?XCtr!;2!)Dav8pGFd!LzDuvEpZPoaSpjLzhl(<W#!kr6H zzCeBA4Zri<ENaIUy~5AE8#Tl-)y$?OGFs5U4vSW)I;C#fRiOh9InHqFG_swd>`WPK z)>LcPGKCp_n0c|1A1`XTe6b40ne%NA&V$HhBRg`UV6<p*vi1E6LTCmlcqxc;fU@<8 zf<L&>0s=<4%BJgh16&VW%s^X-%T(*Qn8kDAV!BV%UoZL@x9Ssz3c4}LuZM@g0&?&$ z%*0(c+qf0-|DMY1hKV8qTZDiY|IeJEJnerE48#(H$$<pg|K6e&!fX(MZAHM%|1&2D zwEw-W4TG5@0^5rK*Z)ELpWE98m^&h{T?p{?KaT(HLLc)*1hy9eeE)AR{+K%=u$>6- z_kVz%BlI7Xv+UdO11~26^?|bA*$$Ry(si~&!>edWd_2x}XoRVW=sughp7?BsY^ikv zQGy}lkgsyLHy%De?RRiVqxiCz3&e@M$dk<^T}GHD!Y*rjo<kVwZygR2-FXL>2#_{( baEUHTlnyT0JlQ$E|DD4fpAmumgTVg->-`Q9 diff --git a/Det/DetCond/tests/data/TESTDB3.db b/Det/DetCond/tests/data/TESTDB3.db deleted file mode 100755 index 2c58dab3ef0a1e0c3e6e9e95300a73ab98c08d0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183296 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 diff --git a/Det/DetCond/tests/data/genDQFLAGS.py b/Det/DetCond/tests/data/genDQFLAGS.py deleted file mode 100644 index 3d343c185..000000000 --- a/Det/DetCond/tests/data/genDQFLAGS.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -""" -Small script to generate the test database for the heart beat test. -(kept for reference) -""" - -from CondDBUI import CondDB -from PyCool import cool -from datetime import datetime, timedelta - -def toTimeStamp(dt): - t = dt - datetime(1970, 1, 1, 0) - return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 - -db = CondDB("sqlite_file:DQFLAGS.db/DQFLAGS", readOnly = False, create_new_db = True) - -db.createNode("/Conditions", storageType = "NODE") -db.createNode("/Conditions/DQ", storageType = "NODE") -db.createNode("/Conditions/DQ/Flags", versionMode = "SINGLE") - -def cond(d): - data = ['<item key="%s" value="%d"/>' % i for i in d.items()] - return """<?xml version='1.0' encoding='ISO-8859-1'?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> - <condition name="Flags"> - <map keytype="string" name="map" valuetype="int"> - %s - </map> - </condition> -</DDDB> -""" % ("\n ".join(data)) - -for since, until, d in [(datetime(2012, 1, 1, 0), datetime(2012, 1, 2, 0), {"DET1": 1}), - (datetime(2012, 1, 2, 0), datetime(2012, 1, 3, 0), {"DET2": 1}), - (datetime(2012, 1, 3, 0), datetime(2012, 1, 4, 0), {}), - (datetime(2012, 1, 5, 0), datetime(2012, 1, 6, 0), {"DET3": 1})]: - since, until = map(toTimeStamp, (since, until)) - db.storeXMLString("/Conditions/DQ/Flags", cond(d), since, until) diff --git a/Det/DetCond/tests/data/genHBTEST.py b/Det/DetCond/tests/data/genHBTEST.py deleted file mode 100644 index 9544d8d17..000000000 --- a/Det/DetCond/tests/data/genHBTEST.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -""" -Small script to generate the test database for the heart beat test. -(kept for reference) -""" - -from CondDBUI import CondDB -from PyCool import cool - -base_time = 1262304000 # (2010, 1, 1, 0, 0, 0, 4, 1, 0) GMT -unit = 60 - -db = CondDB("sqlite_file:HBTEST.db/HBTEST", readOnly = False, create_new_db = True) - -db.createNode("/Conditions", storageType = "NODE") -db.createNode("/Conditions/Online", storageType = "NODE") -db.createNode("/Conditions/Online/HeartBeatTest", storageType = "NODE") -db.createNode("/Conditions/Online/HeartBeatTest/Condition1", versionMode = "SINGLE") -db.createNode("/Conditions/Online/HeartBeatTest/Condition2", versionMode = "SINGLE") -db.createNode("/Conditions/Online/HeartBeatTest/Tick", versionMode = "SINGLE") - -cond = """<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> - <condition name = "Condition%d"> - <param name = "Data" type = "int"> %d </param> - </condition> -</DDDB> -""" - -db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, 0), 0, cool.ValidityKeyMax) -for t in [20, 40]: - db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition1", cond % (1, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) - -db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, 0), 0, cool.ValidityKeyMax) -for t in [20, 40, 80]: - db.storeXMLString("/Conditions/Online/HeartBeatTest/Condition2", cond % (2, t), (base_time + t * unit) * 1000000000, cool.ValidityKeyMax) - -hb = """<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> -<condition name="Tick"> -<param name="Alive" type="int">1</param> -</condition> -</DDDB> -""" -db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, 0, cool.ValidityKeyMax) -db.storeXMLString("/Conditions/Online/HeartBeatTest/Tick", hb, (base_time + 60 * unit) * 1000000000, cool.ValidityKeyMax) diff --git a/Det/DetCond/tests/data/genRSTEST.py b/Det/DetCond/tests/data/genRSTEST.py deleted file mode 100755 index b20f67c00..000000000 --- a/Det/DetCond/tests/data/genRSTEST.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -""" -Small script to generate the test database for the run stamp test. -(kept for reference) -""" - -from CondDBUI import CondDB -from PyCool import cool - -def ts(*args): - from datetime import datetime - epoch = datetime(1970, 1, 1) - return int((datetime(*args) - epoch).total_seconds() * 1000000000) - -db = CondDB("sqlite_file:RSTEST.db/RSTEST", readOnly = False, create_new_db = True) - -db.createNode("/Conditions", storageType = "NODE") -db.createNode("/Conditions/Online", storageType = "NODE") -db.createNode("/Conditions/Online/LHCb", storageType = "NODE") -db.createNode("/Conditions/Online/LHCB/RunInfo", versionMode = "SINGLE") -db.createNode("/Conditions/Online/LHCb/RunStamp.xml", versionMode = "SINGLE") - -rs = """<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd"> -<DDDB> -<condition name="RunStamp"> -<param name="RunNumber" type="int">1</param> -</condition> -</DDDB> -""" -db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 9), ts(2015, 6, 10)) -db.storeXMLString("/Conditions/Online/LHCb/RunStamp.xml", rs, ts(2015, 6, 11), ts(2015, 6, 12)) diff --git a/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt b/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt deleted file mode 100755 index 3d63ec802..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/bug_80076.qmt +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") - -from Configurables import DetCondTest__bug_80076 -alg = DetCondTest__bug_80076("Bug80076") -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1"] -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 3) -#MessageSvc(OutputLevel = 1) - -#from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -</text></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check that we find the expected lines in the right order -expected = [ - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 0.0 -> 1262305200.0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262305200.0 -> 1262306400.0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - ] - -regexp = r"^---|^Validity" - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt b/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt deleted file mode 100755 index 3ccd88fd5..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/check_db_reading.qmt +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/check_db_reading.py</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt b/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt deleted file mode 100755 index 75e6f9405..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/configuration_module.qmt +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/configuration_module_test.py</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt b/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt deleted file mode 100644 index 1a70fb044..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/connection_timeout.qmt +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/connection_timeout.py</text></argument> -<argument name="validator"><text> -findReferenceBlock(""" -TEST ===> start -DDDB.TimeOutChe... INFO Disconnect from database after being idle for 5s (will reconnect if needed) -TEST ===> end -""") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt deleted file mode 100755 index 94bc9a6d0..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern1.qmt +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>1</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/ObjectA -/dd/AutoMap/FolderSet2/ObjectB -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt deleted file mode 100755 index fe3b24ca6..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern2.qmt +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>2</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -/dd/AutoMap/FolderSet3 -/dd/AutoMap/FolderSet3/Object1 -/dd/AutoMap/FolderSet3/Object2 -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt deleted file mode 100755 index e7c6714a0..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_altern3.qmt +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>3</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -/dd/AutoMap/FolderSet2/ObjectA -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt deleted file mode 100755 index 965dce340..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_base.qmt +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>0</text></set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt b/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt deleted file mode 100755 index ea4f3ebcf..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/direct_mapping_layers.qmt +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/direct_mapping_test.py</text></argument> -<argument name="args"><set><text>4</text></set></argument> -<argument name="prerequisites"><set> - <tuple><text>detcond.direct_mapping_base</text><enumeral>PASS</enumeral></tuple> -</set></argument> -<argument name="validator"><text> -reference_block = ''' -=== Begin Nodes === -/dd -/dd/AutoMap -/dd/AutoMap/FolderSet1 -/dd/AutoMap/FolderSet1/Object1 -/dd/AutoMap/FolderSet2 -/dd/AutoMap/FolderSet2/Object1 -/dd/AutoMap/FolderSet2/Object2 -/dd/AutoMap/FolderSet2/ObjectA -/dd/AutoMap/FolderSet2/ObjectB -/dd/AutoMap/FolderSet3 -/dd/AutoMap/FolderSet3/Object1 -/dd/AutoMap/FolderSet3/Object2 -=== End Nodes === -''' -findReferenceBlock(reference_block, stdout, result, causes) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt deleted file mode 100755 index 90cc2a5a8..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/dqscanner.qms/basic.qmt +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import DetCondTest__DQScanTest as DQScanTest -from Configurables import CondDBDQScanner, DDDBConf, CondDB, EventClockSvc, FakeEventTime - -from datetime import datetime, timedelta -def toTimeStamp(dt): - if isinstance(dt, timedelta): - t = dt - else: - t = dt - datetime(1970, 1, 1, 0) - return (t.days * 60 * 60 * 24 + t.seconds) - -def toTimeStampNS(dt): - return toTimeStamp(dt) * 1000000000 - -dddbConf = DDDBConf() - -cdb = CondDB() -cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" -cdb.Tags["DQFLAGS"] = "" - -ecs = EventClockSvc(InitialTime=toTimeStampNS(datetime(2012,1,1,12))) -ecs.addTool(FakeEventTime, "EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = ecs.InitialTime -ecs.EventTimeDecoder.TimeStep = toTimeStampNS(timedelta(days=1)) - -alg = DQScanTest() -alg.DQScanner = CondDBDQScanner() - -tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0)), - (datetime(2012,1,1,12), datetime(2012,1,3,12)), - (datetime(2012,1,2,12), datetime(2012,1,5,12)), - (datetime(2012,1,4,12), datetime(2012,1,6,12)), - (datetime(2012,1,3,12), datetime(2012,1,4,12)), - ] - -alg.IOVs = [(toTimeStamp(a), toTimeStamp(b)) for a, b in tests] - -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) -MessageSvc(OutputLevel = WARNING) - -</text></argument> -<argument name="validator"><text> -findReferenceBlock(""" -ApplicationMgr INFO Application Manager Started successfully -DetCondTest::DQ...SUCCESS Process IOV 1325376000.0 -> 1325635200.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325419200.0 -> 1325592000.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET1: 1, DET2: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325505600.0 -> 1325764800.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET2: 1, DET3: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325678400.0 -> 1325851200.0 -DetCondTest::DQ...SUCCESS -> Flags: {DET3: 1} -DetCondTest::DQ...SUCCESS Process IOV 1325592000.0 -> 1325678400.0 -DetCondTest::DQ...SUCCESS -> Flags: {} -ApplicationMgr INFO Application Manager Stopped successfully -""") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt b/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt deleted file mode 100644 index 22a8fb7c8..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/force_disconnect.qmt +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/force_disconnect.py</text></argument> -<argument name="validator"><text> -findReferenceBlock(""" -TEST ===> start -LHCBCOND DEBUG Forced disconnect from database (will reconnect automatically) -LHCBCOND.TimeOu...VERBOSE Stopping -DQFLAGS DEBUG Database already disconnected -ONLINE_2008 DEBUG Forced disconnect from database (will reconnect automatically) -ONLINE_2008.Tim...VERBOSE Stopping -DDDB DEBUG Forced disconnect from database (will reconnect automatically) -DDDB.TimeOutChe...VERBOSE Stopping -TEST ===> reconnect -ONLINE_2008.Tim...VERBOSE Starting -DDDB.TimeOutChe...VERBOSE Starting -TEST ===> end -""") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt b/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt deleted file mode 100755 index 14360891b..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/get_iovs.qms/basic.qmt +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>../scripts/getIOVs.py</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt b/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt deleted file mode 100755 index 3542de97d..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/granularity.qmt +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -import GaudiKernel.SystemOfUnits as Units -Units.hours = Units.s * 3600 -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" -HBTEST.QueryGranularity = 1 * Units.hours -HBTEST.OutputLevel = DEBUG - -MessageSvc().setDebug.append("HBTEST.Cache") - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") -CondDB().QueryGranularity = 1 * Units.hours - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] -alg.LoadDuringInitialize = True -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) -#MessageSvc(OutputLevel = 1) - -from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] -UpdateManagerSvc().OutputLevel = DEBUG -MessageSvc().setDebug += ["UpdateManagerSvc::Item"] -</text></argument> -<argument name="exit_code"><integer>0</integer></argument> -<argument name="validator"><text> -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 MISSING -HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 0 - 1262305200000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition1', IOV : 1262306400000000000 - 9223372036854775807, channel : 0 -HBTEST.Cache DEBUG Conflict found: item not inserted -HBTEST.Cache DEBUG IOV : 1262306400000000000 - 9223372036854775807 -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262304600000000000 channel 0 FOUND -''', signature_offset = 1, id = "first_cond1") - -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 MISSING -HBTEST DEBUG Retrieving conditions in range 1262304000000000000 - 1262307600000000000 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 0 - 1262305200000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262305200000000000 - 1262306400000000000, channel : 0 -HBTEST.Cache DEBUG Insert Folder '/Conditions/Online/HeartBeatTest/Condition2', IOV : 1262306400000000000 - 1262308800000000000, channel : 0 -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262304600000000000 channel 0 FOUND -''', signature_offset = 1, id = "first_cond2") - -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition1 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition1' @ 1262305800000000000 channel 0 FOUND -''', signature_offset = 1, id = "second_cond1") - -findReferenceBlock(''' -UpdateManagerSv... DEBUG Update object Conditions/Online/HeartBeatTest/Condition2 from data provider -HBTEST.Cache DEBUG Request Folder '/Conditions/Online/HeartBeatTest/Condition2' @ 1262305800000000000 channel 0 FOUND -''', signature_offset = 1, id = "second_cond2") -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt b/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt deleted file mode 100644 index f7bbfbeb5..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/heart_beat.qmt +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] -alg.LoadDuringInitialize = True -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 4) -#MessageSvc(OutputLevel = 1) - -from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -alg.ConditionsDependencies = ["/dd/Conditions/Online/HeartBeatTest/Condition1 -> /dd/Conditions/Online/HeartBeatTest/Condition2 "] -UpdateManagerSvc().OutputLevel = DEBUG -MessageSvc().setDebug += ["UpdateManagerSvc::Item"] -</text></argument> -<argument name="exit_code"><integer>4</integer></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check for bug #66497 (Velo motion system updated several times during initialization) -# 'marker1' must appear only once before 'maker2' -marker1 = "Condition2 from data provider" -marker2 = "Conditions loaded at initialize" -count = 0 -for l in outputlines: - if marker2 in l: - break - if marker1 in l: - count += 1 -if count != 1: - causes.append("bug #66497") - result["GaudiTest.marker.value"] = result.Quote(marker1) - result["GaudiTest.marker.count"] = result.Quote(str(count)) - result["GaudiTest.marker.count_expected"] = result.Quote("1") - -## Check that we find the expected lines in the right order -expected = [ - 'DetCondTest::Te... INFO Conditions loaded at initialize', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262308800.0 -> 1262307600.0', - '(int) Data = 80', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - 'HBTEST ERROR Database not up-to-date. Latest known update is at 2010-01-01 01:00:00.0 UTC, event time is 2010-01-01 01:10:00.0 UTC' - ] - -regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Conditions loaded at initialize|HBTEST.*ERROR" - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt b/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt deleted file mode 100644 index d35694016..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/missing_condition.qmt +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc() -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = 5 -ecs.EventTimeDecoder.TimeStep = 10 - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/Conditions/This/Does/Not/Exist"] -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) -#MessageSvc(OutputLevel = 1) - -</text></argument> -<argument name="exit_code"><integer>4</integer></argument> -<argument name="validator"><text> -## Find the error message about the problematic condition -import re -regexp = r"ERROR.*Conditions/This/Does/Not/Exist" -if not re.findall(regexp, stdout): - causes.append("output") - result["GaudiTest.output.expected_regexp"] = result.Quote(regexp) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt b/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt deleted file mode 100644 index f92224120..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/run_stamp.qmt +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - UpdateManagerSvc, CondDBAccessSvc, RunStampCheck) - -def ts(*args): - from datetime import datetime - epoch = datetime(1970, 1, 1) - return int((datetime(*args) - epoch).total_seconds() * 1000000000) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = ts(2015, 6, 10, 12, 00)) # no RunStamp for this time -ecs.addTool(FakeEventTime, "EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = ts(2015, 6, 9, 12, 00) -ecs.EventTimeDecoder.TimeStep = 24 * 60 * 60 * 1000000000 # 1 day - -RSTEST = CondDBAccessSvc("RSTEST", ConnectionString="sqlite_file:../data/RSTEST.db/RSTEST") - -CondDB().addAlternative(RSTEST, "/Conditions/Online/LHCb/RunStamp.xml") -CondDB().EnableRunStampCheck = True -RunStampCheck(OutputLevel=DEBUG) - -algMgr = ApplicationMgr(EvtSel = "NONE", EvtMax = 4) -#MessageSvc(OutputLevel = 1) -</text></argument> -<argument name="exit_code"><integer>4</integer></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check that we find the expected lines in the right order -expected = ''' -RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433851200.0 -RunStampCheck DEBUG Found '/Conditions/Online/LHCb/RunStamp.xml' valid in [1433808000.0, 1433894400.0) -RunStampCheck DEBUG Checking '/Conditions/Online/LHCb/RunStamp.xml' for event time 1433937600.0 -RunStampCheck ERROR Database not up-to-date. No valid data for run at 2015-06-10 12:00:00.0 UTC -EventLoopMgr SUCCESS Terminating event processing loop due to a stop scheduled by an incident listener -EventLoopMgr SUCCESS Terminating event processing loop due to scheduled stop -'''.strip().splitlines() - -regexp = '^(RunStampCheck.*(Checking|Found|Database)|.*Terminating event processing)' -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt b/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt deleted file mode 100755 index 7f49cd9bd..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/time_switch.qmt +++ /dev/null @@ -1,71 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc() -ecs.addTool(FakeEventTime, "EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = 5 -ecs.EventTimeDecoder.TimeStep = 10 - -DBs = [] -for i in [0,3]: - data = { "name": "TESTDB%d"%i } - DBs.append(CondDBAccessSvc(data["name"], - ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) -readers = [] -for i in range(len(DBs)): - readers.append("'%s':(%d,%d)"%(DBs[i].getFullName(),i*10,(i+1)*10)) - -CondDB().addLayer(CondDBTimeSwitchSvc(Readers = readers, OutputLevel = DEBUG)) - -from Configurables import DetCondTest__TestConditionAlg -alg = DetCondTest__TestConditionAlg() -alg.Conditions = ["/dd/AutoMap/FolderSet1/Object1"] -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 2) -#MessageSvc(OutputLevel = 1) - -</text></argument> -<argument name="validator"><text> -## 1st check: Find reference block -reference_block = """ -CondDBTimeSwitc... DEBUG Configured CondDBReaders: -CondDBTimeSwitc... DEBUG 0.0 - 0.00000001: CondDBAccessSvc/TESTDB0 -CondDBTimeSwitc... DEBUG 0.00000001 - 0.00000002: CondDBAccessSvc/TESTDB3 -""" -findReferenceBlock(reference_block) - -## 2nd check: find data -expected = [ - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/AutoMap/FolderSet1/Object1', - 'Validity: 0.0 -> 0.00000001', - '(int) Data = 1', - 'DetCondTest::Te... INFO Requested Conditions:', - '--- /dd/AutoMap/FolderSet1/Object1', - 'Validity: 0.00000001 -> 0.00000002', - '(int) Data = 2'] - -regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions" -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt b/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt deleted file mode 100755 index 45a455863..000000000 --- a/Det/DetCond/tests/qmtest/detcond.qms/update_in_finalize.qmt +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> -<argument name="args"><set> -<text>-v</text> -</set></argument> -<argument name="options"><text> -from Gaudi.Configuration import * -from Configurables import (DDDBConf, CondDB, EventClockSvc, FakeEventTime, - CondDBAccessSvc, CondDBTimeSwitchSvc) - -DDDBConf() - -ecs = EventClockSvc(InitialTime = (1262304000 + 120 * 60) * 1000000000) -ecs.addTool(FakeEventTime,"EventTimeDecoder") -ecs.EventTimeDecoder.StartTime = (1262304000 + 10 * 60) * 1000000000 -ecs.EventTimeDecoder.TimeStep = 20 * 60 * 1000000000 - -HBTEST = CondDBAccessSvc("HBTEST", ConnectionString="sqlite_file:../data/HBTEST.db/HBTEST") -HBTEST.HeartBeatCondition = "/Conditions/Online/HeartBeatTest/Tick" - -CondDB().addAlternative(HBTEST, "/Conditions/Online/HeartBeatTest") - -from Configurables import DetCondTest__FinalizationEvtLoop -alg = DetCondTest__FinalizationEvtLoop() -alg.Conditions = ["/dd/Conditions/Online/HeartBeatTest/Condition1","/dd/Conditions/Online/HeartBeatTest/Condition2"] -alg.InitialTime = ecs.EventTimeDecoder.StartTime -alg.Step = ecs.EventTimeDecoder.TimeStep -alg.FinalTime = alg.InitialTime + 3 * alg.Step -ApplicationMgr(TopAlg = [alg], EvtSel = "NONE", EvtMax = 1) -#MessageSvc(OutputLevel = 1) - -#from Configurables import UpdateManagerSvc -#UpdateManagerSvc(DotDumpFile = "ums.dot") - -</text></argument> -<argument name="validator"><text> -outputlines = [ l.rstrip() for l in stdout.splitlines() ] - -## Check that we find the expected lines in the right order -expected = [ - 'DetCondTest::Fi... INFO Update for event time 1262304600.0', - 'DetCondTest::Fi... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 0.0 -> 1262305200.0', - '(int) Data = 0', - 'DetCondTest::Fi... INFO Update for event time 1262305800.0', - 'DetCondTest::Fi... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262305200.0 -> 1262306400.0', - '(int) Data = 20', - 'DetCondTest::Fi... INFO Update for event time 1262307000.0', - 'DetCondTest::Fi... INFO Requested Conditions:', - '--- /dd/Conditions/Online/HeartBeatTest/Condition1', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - '--- /dd/Conditions/Online/HeartBeatTest/Condition2', - 'Validity: 1262306400.0 -> 1262307600.0', - '(int) Data = 40', - - ] - -regexp = r"^---|^Validity|^\(int\) Data|.*Requested Conditions|.*Update for event time" - -# grep -import re -exp = re.compile(regexp) -outputlines = [ l for l in outputlines if exp.match(l) ] - -if outputlines != expected: - causes.append("output") - result["GaudiTest.output.regexp"] = result.Quote(regexp) - result["GaudiTest.output.expected"] = result.Quote("\n".join(expected)) - result["GaudiTest.output.found"] = result.Quote("\n".join(outputlines)) -</text></argument> -</extension> diff --git a/Det/DetCond/tests/scripts/check_db_reading.py b/Det/DetCond/tests/scripts/check_db_reading.py deleted file mode 100755 index b3f23c080..000000000 --- a/Det/DetCond/tests/scripts/check_db_reading.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python - -import unittest - -import sys - -#import string -#import random - -class DetCondReadingTest(unittest.TestCase): - -# def assertEqualsConfig(self, lhs, rhs): -# self.assertEquals(lhs.getFullName(), rhs.getFullName()) - - def setUp(self): - unittest.TestCase.setUp(self) - self.testDB = 'sqlite_file:../data/TESTDB3.db/TESTDB3' - self.testFolder = '/lhcb.xml' - self.testout = '<?xml version="1.0" encoding="ISO-8859-1"?>\n<!DOCTYPE DDDB SYSTEM "conddb:/DTD/structure.dtd">\n<DDDB>\n <catalog name="dd">\n <catalogref href="AutoMap" />\n </catalog> \n</DDDB> \n' - self.Nmethods = 1 # number of methods - - def readDB(self): - from CondDBUI import CondDB - db = CondDB(self.testDB) - s = self.testFolder - if not db.db.existsFolder(s): return "" - data = db.getPayload(s,0,0) - if 'data' not in data: return "" - return data['data'] - -# def tearDown(self): -# unittest.TestCase.tearDown(self) - - def test_reading(self): - """Check CondDB reading """ - ret = self.readDB() - self.assertEquals(self.testout, ret) - -if __name__ == '__main__': - unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/configuration_module_test.py b/Det/DetCond/tests/scripts/configuration_module_test.py deleted file mode 100755 index 36276a6d7..000000000 --- a/Det/DetCond/tests/scripts/configuration_module_test.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python - -import unittest - -from Gaudi.Configuration import * -import GaudiKernel.Configurable -from GaudiKernel.Configurable import purge, applyConfigurableUsers -from Configurables import CondDB, DDDBConf -from Configurables import (CondDBCnvSvc, - CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc) - -#import logging -#from GaudiKernel.ProcessJobOptions import InstallRootLoggingHandler -#InstallRootLoggingHandler(level = logging.DEBUG) - -orig_reader = None -orig_dict = None -def equalConfigurable(lhs, rhs): - return lhs.getFullName() == rhs.getFullName() - -class DetCondConfigurationTest(unittest.TestCase): - - def assertEqualsConfig(self, lhs, rhs): - self.assertEquals(lhs.getFullName(), rhs.getFullName()) - - def setUp(self): - unittest.TestCase.setUp(self) - self.DDDB = DDDBConf() - self.CondDB = CondDB() - - def tearDown(self): - self.DDDB = self.CondDB = None - purge() - GaudiKernel.Configurable._appliedConfigurableUsers_ = False - unittest.TestCase.tearDown(self) - - def checkHeartBeat(self, conf, chkstr = ""): - conf = allConfigurables[eval(conf.split(':')[0]).split("/")[1]] - if isinstance(conf, CondDBLayeringSvc): - conf = conf.Layers[-1]# Only check the bottom layer - self.assertEquals(conf.getProp("HeartBeatCondition"), chkstr) - - - def test_000_originalConfiguration(self): - """Check the default configuration""" - applyConfigurableUsers() - global orig_reader, orig_dict - orig_reader = allConfigurables["CondDBCnvSvc"].CondDBReader - self.assertEquals(orig_reader.__class__.__name__, - "CondDBDispatcherSvc") - orig_dict = dict(orig_reader.Alternatives) - - def test_010_addCondDBLayer_1(self): - """Add one layer from CondDBAccessSvc instance""" - # Add the layer - layer = CondDBAccessSvc("layer") - self.CondDB.addLayer(layer) - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # check if we have a layering svc - self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") - # check for the new layer... - self.assertEqual(reader.Layers[0], layer) - # ... plus the original one - self.assertEqualsConfig(reader.Layers[1], orig_reader) - - def test_010_addCondDBLayer_2(self): - """Add layers from allowed Configurable instances""" - # Add the layers (one per type) - types = [CondDBAccessSvc, - CondDBDispatcherSvc, - CondDBLayeringSvc, - CondDBTimeSwitchSvc, - CondDBSQLiteCopyAccSvc] - layers = [] - for i in range(len(types)): - layer = types[i]("layer_%d"%i) - layers.append(layer) - self.CondDB.addLayer(layer) - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # check if we have a layering svc - self.assertEquals(reader.__class__.__name__, "CondDBLayeringSvc") - # correct size? - self.assertEquals(len(reader.Layers), len(layers) + 1) - # correct order (inverse of insertion order)... - layers.reverse() - for i in range(len(types)): - self.assertEqual(reader.Layers[i], layers[i]) - # ... plus the original one - self.assertEqualsConfig(reader.Layers[len(layers)], orig_reader) - - def test_020_addCondDBAlternative_1(self): - """Add one alternative from CondDBAccessSvc instance""" - # Add the alternative - alternative = CondDBAccessSvc("alternative") - self.CondDB.addAlternative(alternative, "/Test") - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # the reader should not have changed - self.assertEqualsConfig(reader, orig_reader) - # correct size? - self.assertEquals(len(reader.Alternatives), len(orig_dict) + 1) - # check the previous alternatives - for k in orig_dict: - self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) - # plus the new one - self.assertEqualsConfig(reader.Alternatives["/Test"], alternative) - - def test_020_addCondDBAlternative_2(self): - """Replace one alternative from CondDBAccessSvc instance""" - path = orig_dict.keys()[0] - - # Add the alternative - alternative = CondDBAccessSvc("alternative") - self.CondDB.addAlternative(alternative, path) - - applyConfigurableUsers() - - reader = allConfigurables["CondDBCnvSvc"].CondDBReader - # the reader should not have changed - self.assertEqualsConfig(reader, orig_reader) - # correct size? - self.assertEquals(len(reader.Alternatives), len(orig_dict)) - # check the previous alternatives - for k in orig_dict: - if k != path: - self.assertEqualsConfig(reader.Alternatives[k], orig_dict[k]) - else: - self.assertEqualsConfig(reader.Alternatives[k], alternative) - - def test_030_heartbeat(self): - """HeartBeat condition (off-line, Oracle, default)""" - self.CondDB.Online = False - self.CondDB.UseOracle = True - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") - - def test_031_heartbeat(self): - """HeartBeat condition (off-line, Oracle, ignore)""" - self.CondDB.Online = False - self.CondDB.UseOracle = True - self.CondDB.IgnoreHeartBeat = True - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "") - - def test_032_heartbeat(self): - """HeartBeat condition (off-line, SQLite, default)""" - self.CondDB.Online = False - self.CondDB.UseOracle = False - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers[:-1]: - self.checkHeartBeat(conf, "") - conf = online.Readers[-1] - self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") - - def test_033_heartbeat(self): - """HeartBeat condition (off-line, SQLite, ignore)""" - self.CondDB.Online = False - self.CondDB.UseOracle = False - self.CondDB.IgnoreHeartBeat = True - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers: - self.checkHeartBeat(conf, "") - - def test_040_heartbeat(self): - """HeartBeat condition (on-line, Oracle, not ignore)""" - self.CondDB.Online = True - self.CondDB.UseOracle = True - self.CondDB.IgnoreHeartBeat = False - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "/Conditions/Online/LHCb/Tick") - - def test_041_heartbeat(self): - """HeartBeat condition (on-line, Oracle, default)""" - self.CondDB.Online = True - self.CondDB.UseOracle = True - applyConfigurableUsers() - - hbc = allConfigurables["ONLINE"].getProp("HeartBeatCondition") - - self.assertEquals(hbc, "") - - def test_042_heartbeat(self): - """HeartBeat condition (on-line, SQLite, not ignore)""" - self.CondDB.Online = True - self.CondDB.UseOracle = False - self.CondDB.IgnoreHeartBeat = False - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers[:-1]: - self.checkHeartBeat(conf, "") - conf = online.Readers[-1] - self.checkHeartBeat(conf, "/Conditions/Online/LHCb/Tick") - - def test_043_heartbeat(self): - """HeartBeat condition (on-line, SQLite, default)""" - self.CondDB.Online = True - self.CondDB.UseOracle = False - applyConfigurableUsers() - - online = allConfigurables["ONLINE"] - for conf in online.Readers: - self.checkHeartBeat(conf, "") - -if __name__ == '__main__': - unittest.main(testRunner = unittest.TextTestRunner(stream=sys.stdout,verbosity=2)) diff --git a/Det/DetCond/tests/scripts/connection_timeout.py b/Det/DetCond/tests/scripts/connection_timeout.py deleted file mode 100644 index aac17167b..000000000 --- a/Det/DetCond/tests/scripts/connection_timeout.py +++ /dev/null @@ -1,22 +0,0 @@ -## @file -# Small script forcing a time-out in the access to the -from Gaudi.Configuration import * -from Configurables import CondDB, CondDBAccessSvc, DDDBConf - -DDDBConf() - -DDDB = CondDBAccessSvc("DDDB") -DDDB.ConnectionTimeOut = 5 - -#MessageSvc(OutputLevel = ERROR) - -import GaudiPython -app = GaudiPython.AppMgr() -app.initialize() -app.start() - -import time -app.detSvc()["/dd"] # access the DB -print "TEST ===> start" -time.sleep(6) # wait enough -print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/direct_mapping_test.py b/Det/DetCond/tests/scripts/direct_mapping_test.py deleted file mode 100755 index 10515b6fe..000000000 --- a/Det/DetCond/tests/scripts/direct_mapping_test.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python -""" -Script for the test of possible use-cases of the direct mapping between -the COOL hierarchy and the transient store one. -Use-cases: - 0) basic mapping (CondDBAccessSvc) - 1) alternative for a folderset in the main DB - 2) alternative for a folderset _not_ in the main DB - 3) alternative for a folder _not_ in the main DB - 4) layers -""" -__author__ = "Marco Clemencic" - -def configure(version): - from Gaudi.Configuration import (importOptions, - ApplicationMgr, - MessageSvc) - from Configurables import DDDBConf, CondDB, CondDBAccessSvc - dddbConf = DDDBConf() - cdb = CondDB() - - DBs = [] - for i in range(3): - data = { "name": "TESTDB%d"%i } - DBs.append(CondDBAccessSvc(data["name"], - ConnectionString="sqlite_file:../data/%(name)s.db/%(name)s"%data)) - - cdb.PartitionConnectionString["DDDB"] = DBs[0].ConnectionString - cdb.Tags["DDDB"] = "" - if version == 1: - cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2') - elif version == 2: - cdb.addAlternative(DBs[2],'/AutoMap/FolderSet3') - elif version == 3: - cdb.addAlternative(DBs[1],'/AutoMap/FolderSet2/ObjectA') - elif version == 4: - cdb.addLayer(DBs[1]) - cdb.addLayer(DBs[2]) - elif version != 0: - raise RuntimeError("Invalid version number") - - ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") - #MessageSvc(OutputLevel = 1) - -def datastore_walk(ds, top = "/"): - if top == "/": - top = ds._idm.rootName() - obj = ds[top] - if obj is not None: - yield ds[top] - nodes = [ i.identifier() for i in ds.leaves(ds[top]) ] - for n in nodes: - for obj in datastore_walk(ds,n): - yield obj - -def node_names(ds, top = "/"): - return [ obj.registry().identifier() for obj in datastore_walk(ds,top) ] - -def main(conf): - configure(conf) - - from Gaudi.Configuration import configurationDict - from pprint import pprint - import GaudiPython - app = GaudiPython.AppMgr() - pprint(configurationDict()) - app.initialize() - - dds = app.detsvc() - # load everything in the store - nodes = node_names(dds) - nodes.sort() - - print "=== Begin Nodes ===" - for n in nodes: - print n - print "=== End Nodes ===" - -if __name__ == '__main__': - import sys - if len(sys.argv) < 2: - version = 0 - else: - version = int(sys.argv[1]) - - main(version) diff --git a/Det/DetCond/tests/scripts/force_disconnect.py b/Det/DetCond/tests/scripts/force_disconnect.py deleted file mode 100644 index e504010ab..000000000 --- a/Det/DetCond/tests/scripts/force_disconnect.py +++ /dev/null @@ -1,28 +0,0 @@ -## @file -# Small script forcing a time-out in the access to the -from Gaudi.Configuration import * -from Configurables import CondDB, CondDBAccessSvc, DDDBConf - -DDDBConf(DataType="2008") - -#DDDB = CondDBAccessSvc("DDDB") -#DDDB.ConnectionTimeOut = 5 - -partitions = ['DDDB', 'ONLINE_2008', 'LHCBCOND', 'DQFLAGS'] -msg = MessageSvc(OutputLevel=WARNING) -msg.setDebug.extend(partitions) -msg.setVerbose.extend([p + '.TimeOutChecker' for p in partitions]) - -import GaudiPython -app = GaudiPython.AppMgr() -app.initialize() -app.start() - -import time -app.detSvc()["/dd/Conditions/Online/LHCb"] # access the DB -print "TEST ===> start" -reader = app.service('CondDBCnvSvc', GaudiPython.gbl.ICondDBReader) -reader.disconnect() -print "TEST ===> reconnect" -app.detSvc()["/dd/Conditions/Online/LHCb/Tick"] # access the DB -print "TEST ===> end" diff --git a/Det/DetCond/tests/scripts/getIOVs.py b/Det/DetCond/tests/scripts/getIOVs.py deleted file mode 100755 index 8aa9c2cd4..000000000 --- a/Det/DetCond/tests/scripts/getIOVs.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python -""" -Script for the test of IOV retrieval -""" -__author__ = "Marco Clemencic" - -import sys -from datetime import datetime, timedelta - -def toTimeStamp(dt): - if isinstance(dt, timedelta): - t = dt - else: - t = dt - datetime(1970, 1, 1, 0) - return (t.days * 60 * 60 * 24 + t.seconds) * 1000000000 - -def toDateTime(ts): - return datetime(1970, 1, 1, 0) + timedelta(seconds=ts/1000000000) - -def configure(): - from Gaudi.Configuration import (ApplicationMgr, - MessageSvc, ERROR) - from Configurables import DDDBConf, CondDB, CondDBAccessSvc, EventClockSvc, FakeEventTime - dddbConf = DDDBConf() - cdb = CondDB() - - cdb.PartitionConnectionString["DQFLAGS"] = "sqlite_file:../data/DQFLAGS.db/DQFLAGS" - cdb.Tags["DQFLAGS"] = "" - - ecs = EventClockSvc(InitialTime=toTimeStamp(datetime(2012,1,1,12))) - ecs.addTool(FakeEventTime, "EventTimeDecoder") - ecs.EventTimeDecoder.StartTime = ecs.InitialTime - ecs.EventTimeDecoder.TimeStep = toTimeStamp(timedelta(days=1)) - - ApplicationMgr(TopAlg = ["LoadDDDB"], EvtSel = "NONE") - MessageSvc(OutputLevel = ERROR) - -def checkIOVs(dbReader, since, until, expected): - import GaudiPython - IOV = GaudiPython.gbl.ICondDBReader.IOV - Time = GaudiPython.gbl.Gaudi.Time - - print "Checking %s -> %s ..." % (since, until), - t1 = Time(toTimeStamp(since)) - t2 = Time(toTimeStamp(until)) - iov = IOV(t1, t2) - result = dbReader.getIOVs("/Conditions/DQ/Flags", iov, 0) - - found = [(toDateTime(iov.since.ns()), toDateTime(iov.until.ns())) for iov in result] - - good = found == expected - if not good: - print "ERROR" - print " expected:", [tuple(map(str, iov)) for iov in expected] - print " found: ", [tuple(map(str, iov)) for iov in found] - else: - print "OK" - return good - -def main(): - configure() - - from Gaudi.Configuration import configurationDict - from pprint import pprint - import GaudiPython - app = GaudiPython.AppMgr() - pprint(configurationDict()) - app.initialize() - - dq = app.service("DQFLAGS", GaudiPython.gbl.ICondDBReader) - - dbData = [(datetime(2012,1,1,0), datetime(2012,1,2,0)), - (datetime(2012,1,2,0), datetime(2012,1,3,0)), - (datetime(2012,1,3,0), datetime(2012,1,4,0)), - (datetime(2012,1,5,0), datetime(2012,1,6,0))] - - tests = [(datetime(2012,1,1,0), datetime(2012,1,4,0), dbData[0:3]), - (datetime(2012,1,1,12), datetime(2012,1,3,12), dbData[0:3]), - (datetime(2012,1,2,12), datetime(2012,1,5,12), dbData[1:4]), - (datetime(2012,1,4,12), datetime(2012,1,6,12), dbData[3:4]), - ] - print "\n=== Begin Tests ===" - bad = 0 - for since, until, expected in tests: - if not checkIOVs(dq, since, until, expected): - bad += 1 - print "=== End Tests ===" - - if bad: - print "\nFailed %d tests out of %d\n" % (bad, len(tests)) - sys.exit(1) - - print "" - -if __name__ == '__main__': - main() diff --git a/Det/DetCond/tests/src/DQScanTest.cpp b/Det/DetCond/tests/src/DQScanTest.cpp deleted file mode 100644 index 6ff5a6faa..000000000 --- a/Det/DetCond/tests/src/DQScanTest.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Local custom parsers must be defined very early in the file. -#include "GaudiKernel/ParsersFactory.h" - -namespace Gaudi { - namespace Parsers { - // Note: to be kept in sync with the property in DetCondTest::DQScanTest - StatusCode parse(std::vector<std::pair<unsigned int, unsigned int> >& result, const std::string& input) { - return Gaudi::Parsers::parse_(result, input); - } - } -} - -// Include files - -#include "DetCond/ICondDBReader.h" - -// local -#include "DQScanTest.h" - -#include "boost/foreach.hpp" - -namespace { - inline long long s2ns(unsigned int s) { - return static_cast<long long>(s) * 1000000000; - } -} - -// ---------------------------------------------------------------------------- -// Implementation file for class: DQScanTest -// -// 31/01/2012: Marco Clemencic -// ---------------------------------------------------------------------------- -DECLARE_NAMESPACE_ALGORITHM_FACTORY(DetCondTest, DQScanTest) - -namespace DetCondTest { -// ============================================================================ -// Standard constructor, initializes variables -// ============================================================================ -DQScanTest::DQScanTest(const std::string& name, ISvcLocator* pSvcLocator) - : GaudiAlgorithm(name, pSvcLocator), m_scanner(0) -{ - declareProperty("DQScanner", - m_DQScannerName = "CondDBDQScanner", - "Type/name of the IDQScanner instance to use."); - declareProperty("IOVs", - m_iovsProp, - "List of IOVs (specified in seconds) to scan."); -} - -// ============================================================================ -// Destructor -// ============================================================================ -DQScanTest::~DQScanTest() {} - -// ============================================================================ -// Initialization -// ============================================================================ -StatusCode DQScanTest::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; - - m_scanner = tool<IDQScanner>(m_DQScannerName); - - m_iovs.clear(); - BOOST_FOREACH(IOVPropType &iov, m_iovsProp) { - m_iovs.push_back(ICondDBReader::IOV(Gaudi::Time(s2ns(iov.first)), Gaudi::Time(s2ns(iov.second)))); - } - - return StatusCode::SUCCESS; -} - -// ============================================================================ -// Main execution -// ============================================================================ -StatusCode DQScanTest::execute() { - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; - - info() << "Execute" << endmsg; - - BOOST_FOREACH(ICondDBReader::IOV &iov, m_iovs) { - always() << "Process IOV " << iov.since << " -> " << iov.until << endmsg; - IDQFilter::FlagsType result = m_scanner->scan(iov.since, iov.until); - always() << "-> Flags: " << result << endmsg; - } - - return StatusCode::SUCCESS; -} - -// ============================================================================ -// Finalize -// ============================================================================ -StatusCode DQScanTest::finalize() { - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; - - if (release(m_scanner).isFailure()) { - warning() << "Failed to release tool " << m_DQScannerName << endmsg; - } - m_scanner = 0; - - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -// ============================================================================ -} // namespace DetCondTest diff --git a/Det/DetCond/tests/src/DQScanTest.h b/Det/DetCond/tests/src/DQScanTest.h deleted file mode 100644 index 78d13b015..000000000 --- a/Det/DetCond/tests/src/DQScanTest.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef SRC_DQSCANTEST_H -#define SRC_DQSCANTEST_H 1 -// Include files -// from Gaudi -#include "GaudiAlg/GaudiAlgorithm.h" - -#include "Kernel/IDQScanner.h" - -#include "DetCond/ICondDBReader.h" - -namespace DetCondTest { - -/** @class DQScanTest DQScanTest.h src/DQScanTest.h - * - * Algorithm to test the behavior of an IDQScanner implementation. - * - * @author Marco Clemencic - * @date 31/01/2012 - */ -class DQScanTest: public GaudiAlgorithm { -public: - typedef std::pair<unsigned int, unsigned int> IOVPropType; - typedef std::vector<IOVPropType> IOVListPropType; - - /// Standard constructor - DQScanTest(const std::string& name, ISvcLocator* pSvcLocator); - virtual ~DQScanTest(); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization -protected: -private: - - /// Type/name of the IDQScanner instance. - /// (property DQScanner) - std::string m_DQScannerName; - - /// List of IOVs (with time specified in seconds) to try to retrieve (property). - IOVListPropType m_iovsProp; - - /// List of IOVs to try to retrieve. - ICondDBReader::IOVList m_iovs; - - /// Pointer to the IDQScanner instance. - IDQScanner *m_scanner; -}; - -} - -#endif // SRC_DQSCANTEST_H diff --git a/Det/DetCond/tests/src/TestConditionAlg.cpp b/Det/DetCond/tests/src/TestConditionAlg.cpp deleted file mode 100755 index d749e5d05..000000000 --- a/Det/DetCond/tests/src/TestConditionAlg.cpp +++ /dev/null @@ -1,287 +0,0 @@ -// Include files -#include "GaudiKernel/Map.h" -#include "GaudiAlg/GaudiAlgorithm.h" -#include "GaudiKernel/IDetDataSvc.h" -#include "DetDesc/Condition.h" - -#include <vector> - -namespace DetCondTest { - -/** @class TestConditionAlg TestConditionAlg.h component/TestConditionAlg.h - * - * Simple algorithm that prints the requested conditions at every event. - * - * @author Marco CLEMENCIC - * @date 2008-06-27 - */ -class TestConditionAlg : public GaudiAlgorithm { -public: - /// Standard constructor - TestConditionAlg( const std::string& name, ISvcLocator* pSvcLocator ); - - virtual ~TestConditionAlg( ); ///< Destructor - - virtual StatusCode initialize(); ///< Algorithm initialization - virtual StatusCode execute (); ///< Algorithm execution - virtual StatusCode finalize (); ///< Algorithm finalization - -protected: - - void i_dump(); - - /// Names of the conditions to print - std::vector<std::string> m_condPaths; - - /// Flag to decide if the conditions have to be loaded also during the - /// initialize step. - bool m_loadAtInit; - - /// Container of the conditions to print - std::vector<std::string> m_conditionDeps; - - /// Container of the conditions to print - GaudiUtils::Map<std::string,Condition*> m_conditions; -}; - -//----------------------------------------------------------------------------- -// Implementation file for class : TestConditionAlg -// -// 2008-06-27 : Marco CLEMENCIC -//----------------------------------------------------------------------------- - -//============================================================================= -// Standard constructor, initializes variables -//============================================================================= -TestConditionAlg::TestConditionAlg( const std::string& name, - ISvcLocator* pSvcLocator) - : GaudiAlgorithm ( name , pSvcLocator ) -{ - declareProperty("Conditions", m_condPaths, - "list of paths to conditions in the detector transient store"); - declareProperty("LoadDuringInitialize", m_loadAtInit = false, - "load the requested conditions already during the initialization"); - declareProperty("ConditionsDependencies", m_conditionDeps, - "declare dependencies between objects as a list of strings 'A -> B') " - "to indicate that the condition A depends on B."); -} -//============================================================================= -// Destructor -//============================================================================= -TestConditionAlg::~TestConditionAlg() {} - -namespace { - void printDepsError(MsgStream& stream, - size_t lineNo, const std::string& msg, - const std::string& line) { - stream << "Syntax error in item " << lineNo - << " of ConditionsDependencies: " << msg << endmsg; - stream << " '" << line << "'" << endmsg; - } -} -//============================================================================= -// Initialization -//============================================================================= -StatusCode TestConditionAlg::initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; - - std::vector<std::string>::const_iterator path; - for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ - registerCondition<TestConditionAlg>(*path,m_conditions[*path],NULL); - } - - std::vector<std::string>::const_iterator deps; - for (deps = m_conditionDeps.begin(); deps != m_conditionDeps.end(); ++deps) { - std::string::size_type pos = deps->find("->"); - if (pos == std::string::npos) { - printDepsError(error(), deps - m_conditionDeps.begin(), "missing '->'", *deps); - return StatusCode::FAILURE; - } - std::string::size_type p0, p1; - p0 = deps->find_first_not_of(" \n\r\t"); - p1 = deps->find_last_not_of(" \n\r\t", pos - 1) + 1; - std::string first(*deps, p0, p1 - p0); - if (first.empty()) { - printDepsError(error(), deps - m_conditionDeps.begin(), "missing first argument", *deps); - return StatusCode::FAILURE; - } - p0 = deps->find_first_not_of(" \n\r\t", pos + 2); - p1 = deps->find_last_not_of(" \n\r\t") + 1; - std::string second(*deps, p0, p1 - p0); - if (second.empty()) { - printDepsError(error(), deps - m_conditionDeps.begin(), "missing second argument", *deps); - return StatusCode::FAILURE; - } - info() << "Declaring dependency of '" << first << "' on '" << second << "'" << endmsg; - updMgrSvc()->registerCondition(getDet<Condition>(first), second); - } - - if (m_loadAtInit) { - sc = updMgrSvc()->update(this); - info() << "Conditions loaded at initialize" << endmsg; - if (sc.isSuccess()){ - i_dump(); - } - else return sc; - } - return StatusCode::SUCCESS; -} - -//============================================================================= -// Main execution -//============================================================================= -StatusCode TestConditionAlg::execute() { - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Execute" << endmsg; - i_dump(); - - return StatusCode::SUCCESS; -} - -//============================================================================= -// Finalize -//============================================================================= -StatusCode TestConditionAlg::finalize() { - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Finalize" << endmsg; - - updMgrSvc()->unregister(this); - m_conditions.clear(); - m_condPaths.clear(); - - return GaudiAlgorithm::finalize(); // must be called after all other actions -} - -//============================================================================= -// Print the conditions -//============================================================================= -void TestConditionAlg::i_dump() -{ - info() << "Requested Conditions:\n"; - GaudiUtils::Map<std::string,Condition*>::iterator it; - for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { - info() << "--- " << it->first << "\n" << *(it->second) << "\n"; - } - info() << endmsg; -} - -//============================================================================= - - -/** Small algorithm that runs a fake event loop during finalize to scan the - * values of the conditions (see bug #74255). - * - * @author Marco CLEMENCIC - * @date 2010-10-25 - */ -class FinalizationEvtLoop: public GaudiAlgorithm { -public: - /// Standard constructor - FinalizationEvtLoop(const std::string& name, ISvcLocator* pSvcLocator): - GaudiAlgorithm(name, pSvcLocator) - { - declareProperty("Conditions", m_condPaths, - "list of paths to conditions in the detector transient store"); - declareProperty("InitialTime", m_initTime = 0, // 1970-01-01 00:00:00UTC - "First event time of the fake event loop"); - declareProperty("FinalTime", m_finalTime = m_initTime + 10000000000LL, // init + 10s - "Final time of the loop"); - declareProperty("Step", m_step = 1000000000LL, // 1s - "Step of the loop"); - } - - virtual ~FinalizationEvtLoop() {} - - virtual StatusCode initialize() { - StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first - if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm - - if ( msgLevel(MSG::DEBUG) ) debug() << "==> Initialize" << endmsg; - - std::vector<std::string>::const_iterator path; - for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ - registerCondition<FinalizationEvtLoop>(*path, m_conditions[*path], NULL); - } - - return StatusCode::SUCCESS; - } - - virtual StatusCode execute () { - return StatusCode::SUCCESS; - } - - virtual StatusCode finalize () { - Gaudi::Time t(m_initTime); - const Gaudi::Time fin(m_finalTime); - const Gaudi::TimeSpan step(m_step); - - SmartIF<IDetDataSvc> dds(detSvc()); - for ( ; t < fin; t += step) { - dds->setEventTime(t); - info() << "Update for event time " << t << endmsg; - if (updMgrSvc()->newEvent().isSuccess()) { - info() << "Requested Conditions:\n"; - GaudiUtils::Map<std::string,Condition*>::iterator it; - for (it = m_conditions.begin(); it != m_conditions.end(); ++it) { - info() << "--- " << it->first << "\n" << *(it->second) << "\n"; - } - info() << endmsg; - } - else { - error() << "Failure updating" << endmsg; - return StatusCode::FAILURE; - } - } - - return StatusCode::SUCCESS; - } - -private: - /// First event time of the fake event loop - Gaudi::Time::ValueType m_initTime; - /// First event time of the fake event loop - Gaudi::Time::ValueType m_finalTime; - /// First event time of the fake event loop - Gaudi::Time::ValueType m_step; - - /// Names of the conditions to print - std::vector<std::string> m_condPaths; - - /// Container of the conditions to print - GaudiUtils::Map<std::string,Condition*> m_conditions; -}; - -/** Test algorithm that triggers the bug #80076 - * https://savannah.cern.ch/bugs/?80076 - */ -class bug_80076: public TestConditionAlg { -public: - /// Constructor. - bug_80076(const std::string& name, ISvcLocator* pSvcLocator): - TestConditionAlg(name, pSvcLocator) {} - - /// Override the initialize to ensure that the conditions are already loaded - /// during the initialize. - StatusCode initialize() { - StatusCode sc = TestConditionAlg::initialize(); - if (sc.isFailure()) return sc; - - std::vector<std::string>::const_iterator path; - for (path = m_condPaths.begin(); path != m_condPaths.end(); ++path){ - // this ensures that the objects are loaded in the transient store - exist<DataObject>(detSvc(), *path); - } - - return sc; - } -}; - -} - -// Declaration of the Algorithm Factory -DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, TestConditionAlg ) -DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, FinalizationEvtLoop ) -DECLARE_NAMESPACE_ALGORITHM_FACTORY( DetCondTest, bug_80076 ) -- GitLab From 0342ab032993a98a6068d0cbc7af08a550589254 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 15:30:15 +0100 Subject: [PATCH 32/37] file --- .git-lb-checkout | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .git-lb-checkout diff --git a/.git-lb-checkout b/.git-lb-checkout deleted file mode 100644 index 956923af6..000000000 --- a/.git-lb-checkout +++ /dev/null @@ -1,3 +0,0 @@ -[lb-checkout "LHCb.Det/DetCond"] - base = ed48beeb1a3925e97bfde21fd887f861b032263e - imported = 00b37002d748170a320ef743cb30b53f871a898a -- GitLab From 9fbdd53e2dc7518bef651cba8a9a916a45ad921d Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Tue, 21 Jun 2016 18:35:19 +0200 Subject: [PATCH 33/37] use warning suppression printout --- Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp index 85265ba3e..b0f8e4adf 100755 --- a/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichMissingHPDMonitor.cpp @@ -127,10 +127,11 @@ StatusCode MissingHPDMonitor::execute() if ( UNLIKELY( ( m_nEvts - m_hpdCount[HPD] ) > m_maxMissingEvents ) ) { // it is missing - std::ostringstream mess; + std::ostringstream mess, hpdS; mess << "HPD active but no data seen for " << m_maxMissingEvents << " events or more"; hpdDisableTool() -> DisableHPD( HPD, mess.str(), 10, m_nEvts-m_lastEventCheck ); - warning() << HPD << " " << mess.str() << endmsg; + hpdS << HPD; + Warning( hpdS.str()+" "+mess.str(), StatusCode::SUCCESS ); } } } @@ -148,7 +149,7 @@ StatusCode MissingHPDMonitor::execute() mess << "HPD inactive but present in the data during the last " << m_maxMissingEvents << " events"; hpdDisableTool() -> ReportHPD( HPD, mess.str() ); - warning() << HPD << " " << mess.str() << endmsg; + //warning() << HPD << " " << mess.str() << endmsg; } } } -- GitLab From 05ee56a370aa33bd10faa9c2c7d915cfe632104f Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Thu, 14 Jul 2016 15:08:21 +0100 Subject: [PATCH 34/37] replace endreq with endmsg. Depreciated in current Gaudi master --- Rich/RichDataMerge/src/RichTAEventMergeAlg.cpp | 16 ++++++++-------- .../src/RichSingleEventSnapshot.cpp | 6 +++--- Rich/RichOnlineMonitors/src/Sleeper.cpp | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Rich/RichDataMerge/src/RichTAEventMergeAlg.cpp b/Rich/RichDataMerge/src/RichTAEventMergeAlg.cpp index fb431e996..7c8aaf9cc 100755 --- a/Rich/RichDataMerge/src/RichTAEventMergeAlg.cpp +++ b/Rich/RichDataMerge/src/RichTAEventMergeAlg.cpp @@ -75,7 +75,7 @@ StatusCode TAEventMergeAlg::initialize() } m_skippedLastMainEv = false; - info() << "Spillovers = " << m_spillLocations << endreq; + info() << "Spillovers = " << m_spillLocations << endmsg; return sc; } @@ -166,7 +166,7 @@ StatusCode TAEventMergeAlg::execute() if ( m_lastMainODIN->eventNumber() > 0 && odin()->eventNumber() < m_lastMainODIN->eventNumber() ) { - error() << "Main event numbers going backwards ..." << endreq; + error() << "Main event numbers going backwards ..." << endmsg; printODIN( " -> Last ODIN ", MSG::ERROR, m_lastMainODIN ); printODIN( " -> Current ODIN ", MSG::ERROR, odin() ); } @@ -212,7 +212,7 @@ StatusCode TAEventMergeAlg::execute() { goOn = false; foundEventToMerge = false; - debug() << " -> Skipping to next main event" << endreq; + debug() << " -> Skipping to next main event" << endmsg; m_skippedLastMainEv = true; } else if ( orderedData.front()->gpsTime > main_odin.gpsTime() && @@ -227,17 +227,17 @@ StatusCode TAEventMergeAlg::execute() //plot1D( (double)gpsBackDiff, "Negative gps time Diff", -maxDiff, maxDiff, 100 ); info() << " -> Found merge events either side of main " - << endreq; + << endmsg; info() << " -> main BunchID = " << main_odin.bunchId() << " before " << orderedData.back()->bunchId << "(" << (int)orderedData.back()->bunchId-(int)main_odin.bunchId() << ")" << " after " << orderedData.front()->bunchId << "(" << (int)orderedData.front()->bunchId-(int)main_odin.bunchId() << ")" - << endreq; + << endmsg; info() << " -> main gpsTime = " << main_odin.gpsTime() << " before " << orderedData.back()->gpsTime << "(" << gpsBackDiff << ")" << " after " << orderedData.front()->gpsTime << "(" << gpsFrontDiff << ")" - << endreq; + << endmsg; goOn = false; foundEventToMerge = true; @@ -338,7 +338,7 @@ StatusCode TAEventMergeAlg::newEvent( const unsigned int iStream ) { StatusCode sc = StatusCode::SUCCESS; - debug() << "Loading new event for stream" << iStream << endreq; + debug() << "Loading new event for stream" << iStream << endmsg; if ( 0 == m_mergeIt[iStream] ) { @@ -385,7 +385,7 @@ StatusCode TAEventMergeAlg::newEvent( const unsigned int iStream ) if ( (*m_lastSpillODIN)[iStream].eventNumber() > 0 && odin()->eventNumber() < (*m_lastSpillODIN)[iStream].eventNumber() ) { - error() << "Merge event numbers going backwards ..." << endreq; + error() << "Merge event numbers going backwards ..." << endmsg; printODIN( " -> Last ODIN ", MSG::ERROR, &(*m_lastSpillODIN)[iStream] ); printODIN( " -> Current ODIN ", MSG::ERROR, odin() ); } diff --git a/Rich/RichOnlineMonitors/src/RichSingleEventSnapshot.cpp b/Rich/RichOnlineMonitors/src/RichSingleEventSnapshot.cpp index f7bf482fa..f76194596 100755 --- a/Rich/RichOnlineMonitors/src/RichSingleEventSnapshot.cpp +++ b/Rich/RichOnlineMonitors/src/RichSingleEventSnapshot.cpp @@ -177,7 +177,7 @@ StatusCode SingleEventSnapshot::execute() if ( !m_ringLoc.empty() && exist<LHCb::RichRecRings>(m_ringLoc) ) { const LHCb::RichRecRings * rings = get<LHCb::RichRecRings>(m_ringLoc); - _ri_debug << "Found " << rings->size() << " rings at " << m_ringLoc <<endreq; + _ri_debug << "Found " << rings->size() << " rings at " << m_ringLoc <<endmsg; for ( const auto * ring : *rings ) { // which RICH ? @@ -315,7 +315,7 @@ StatusCode SingleEventSnapshot::execute() // add RICH1 rings for ( auto& R : ringParams[Rich::Rich1] ) { - _ri_debug << "Adding RICH1 ring " << R << endreq; + _ri_debug << "Adding RICH1 ring " << R << endmsg; cameraTool()->Append( "TELLIPSE", &*R.begin(), 4*sizeof(float) ); } } @@ -327,7 +327,7 @@ StatusCode SingleEventSnapshot::execute() // add RICH2 rings for ( auto& R : ringParams[Rich::Rich2] ) { - _ri_debug << "Adding RICH2 ring " << R << endreq; + _ri_debug << "Adding RICH2 ring " << R << endmsg; cameraTool()->Append( "TELLIPSE", &*R.begin(), 4*sizeof(float) ); } } diff --git a/Rich/RichOnlineMonitors/src/Sleeper.cpp b/Rich/RichOnlineMonitors/src/Sleeper.cpp index 1f6ea661b..64728a2e6 100755 --- a/Rich/RichOnlineMonitors/src/Sleeper.cpp +++ b/Rich/RichOnlineMonitors/src/Sleeper.cpp @@ -67,9 +67,9 @@ StatusCode Sleeper::initialize() { StatusCode Sleeper::finalize() { - info() << "Finalizing sleeper"<<endreq; - info() <<m_myname<<endreq; - info() << endreq; + info() << "Finalizing sleeper"<<endmsg; + info() <<m_myname<<endmsg; + info() << endmsg; return GaudiAlgorithm::finalize(); } @@ -79,7 +79,7 @@ StatusCode Sleeper::finalize() StatusCode Sleeper::execute() { - info() << "Sleeper "<<m_myname<<" sleeping " << m_val1*factor <<" + " << m_val2 << " useconds"<<endreq; + info() << "Sleeper "<<m_myname<<" sleeping " << m_val1*factor <<" + " << m_val2 << " useconds"<<endmsg; mysleep((unsigned int)(m_val1*factor + m_val2)); -- GitLab From 27f58bbc99a5348a5f11285cd86a85ec0697e7e2 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Mon, 18 Jul 2016 14:08:14 +0100 Subject: [PATCH 35/37] CRJ Cambridge desktop changed. pciy -> pcfm --- Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraServer.conf | 4 ++-- Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraWebServer.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraServer.conf b/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraServer.conf index 474d6c7bf..23f7da6dc 100755 --- a/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraServer.conf +++ b/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraServer.conf @@ -4,8 +4,8 @@ ID=CambridgeServer# the unique string that identifies the server inport=45123# outport=45124# logfile=warnings.out# -datadir=/var/nwork/pciy/jonesc/camera/data# -webserver=pciy.hep.phy.cam.ac.uk# where to get the info files from +datadir=/var/nwork/pcmf/jonesc/camera/data# +webserver=pcmf.hep.phy.cam.ac.uk# where to get the info files from webport=45125# webdir=data# depends on the http-root of the webserver maxfiles=10000# maximum number of warnings in one directory diff --git a/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraWebServer.conf b/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraWebServer.conf index bcc48a143..340c671a0 100755 --- a/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraWebServer.conf +++ b/Rich/Panoptes/scripts/CRJ/Cambridge/etc/CameraWebServer.conf @@ -1,5 +1,5 @@ #end a line with # #The httproot and websdir should be set to somewhere that has plenty of storage space.# websport=45125# -websdir=/var/nwork/pciy/jonesc/camera/# -httproot=/var/nwork/pciy/jonesc/camera/data# +websdir=/var/nwork/pcmf/jonesc/camera/# +httproot=/var/nwork/pcmf/jonesc/camera/data# -- GitLab From 22c858581bc904ef22b9d52b7cba8306a5d28d2b Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Fri, 22 Jul 2016 22:18:08 +0100 Subject: [PATCH 36/37] Some printing changes for gcc 6.1 --- .../RichOnlineMonitors/src/RichDAQMonitor.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp b/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp index 555024113..392a7b28c 100755 --- a/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp @@ -190,18 +190,18 @@ StatusCode DAQMonitor::initialize() if (m_ExtendedVerbose) { verbose() << "alert counters" << endmsg; - verbose() << alertA.print() << endmsg; - verbose() << alertB.print() << endmsg; - verbose() << alertC.print() << endmsg; - verbose() << alertD.print() << endmsg; - verbose() << alertE.print() << endmsg; - verbose() << alertF.print() << endmsg; - verbose() << alertG.print() << endmsg; - verbose() << alertH.print() << endmsg; - verbose() << alertI.print() << endmsg; - verbose() << alertJ.print() << endmsg; - verbose() << alertK.print() << endmsg; - verbose() << alertL.print() << endmsg; + verbose() << alertA << endmsg; + verbose() << alertB << endmsg; + verbose() << alertC << endmsg; + verbose() << alertD << endmsg; + verbose() << alertE << endmsg; + verbose() << alertF << endmsg; + verbose() << alertG << endmsg; + verbose() << alertH << endmsg; + verbose() << alertI << endmsg; + verbose() << alertJ << endmsg; + verbose() << alertK << endmsg; + verbose() << alertL << endmsg; } // -- GitLab From d07ec40e71ec0b6c65604cbce18cc900b9c0e7a7 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Thu, 2 Feb 2017 09:49:50 +0000 Subject: [PATCH 37/37] Minor fix to DAQ monitor to support some changes downstream --- CMakeLists.txt | 6 +++--- Rich/Panoptes/options/OfflineDataFiles.py | 20 ++++++++++++------- .../RichOnlineMonitors/src/RichDAQMonitor.cpp | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb61e238b..293c21346 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ find_package(GaudiProject) #--------------------------------------------------------------- # Declare project name and version -gaudi_project(Panoptes v6r1 - USE Online v5r32 - Rec v20r1 +gaudi_project(Panoptes v7r0 + USE Online v6r0 + Rec v21r0 DATA FieldMap VERSION v5r* ParamFiles) diff --git a/Rich/Panoptes/options/OfflineDataFiles.py b/Rich/Panoptes/options/OfflineDataFiles.py index 05243d895..9127252f8 100755 --- a/Rich/Panoptes/options/OfflineDataFiles.py +++ b/Rich/Panoptes/options/OfflineDataFiles.py @@ -5,11 +5,17 @@ import glob # Check what is available searchPaths = [ - "/usera/jonesc/NFS/data/Collision16/LHCb/Raw/", # Cambridge - "/usera/jonesc/NFS/data/Collision15/LHCb/Raw/", # Cambridge - "/home/chris/LHCb/Data/" # CRJ's CernVM + #"/usera/jonesc/NFS/data/Collision16/LHCb/Raw/", # Cambridge + "/usera/jonesc/NFS/data/Collision15/LHCb/Raw/", # Cambridge + "/usera/jonesc/NFS/data/Collision12/LHCb/Raw/", # Cambridge + "/usera/jonesc/NFS/data/Collision11_25/LHCb/Raw/", # Cambridge + "/home/chris/LHCb/Data/Collision16/LHCb/Raw/" # CRJ's CernVM ] -EventSelector().Input = [ ] -for path in searchPaths : - files = sorted(glob.glob(path+"*/*.raw")) - EventSelector().Input += [ "DATAFILE='PFN:"+file+"' SVC='LHCb::MDFSelector'" for file in files ] + +files = [ ] +for path in searchPaths : files += sorted(glob.glob(path+"*/*.raw")) + +print "Data Files :-" +print("\n".join(files)) + +EventSelector().Input = [ "DATAFILE='PFN:"+file+"' SVC='LHCb::MDFSelector'" for file in files ] diff --git a/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp b/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp index 8a7b5e224..6e815cd24 100755 --- a/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp +++ b/Rich/RichOnlineMonitors/src/RichDAQMonitor.cpp @@ -982,7 +982,7 @@ StatusCode DAQMonitor::execute() verbose() << "HPD footer has parity word " << hpdInfo.footer().hasParityWord () << endmsg; if (hpdInfo.footer().hasParityWord()) { - const Rich::DAQ::LongType parityWord = hpdInfo.footer().parityWord(); + const auto parityWord = hpdInfo.footer().parityWord(); bool parityOK = hpdInfo.footer().testParityWord(parityWord); if ( msgLevel(MSG::VERBOSE) ) verbose() << " parity word " << parityWord << " is OK " << parityOK << endmsg; -- GitLab