//////////////////////////////////////////////////////////////////// /// \class RAT::DS::EV /// /// \brief This class represents a detected event. /// /// \author Stan Seibert \n /// P G Jones /// /// REVISION HISTORY:\n /// - 2009 : Aleksandra Bialek - Updates /// - 03/10 : Phil Jones - Added Near AV Fit Results /// - 29 Mar 2010 : Gabriel Orebi Gann - add additional members /// to hold the full detector data /// - TEMP: increment NHits with each new PMTCal /// This should really be PMTUncal, but this will /// do until we have an uncalibrator in place /// - 29 Mar 2010 : G Orebi Gann - a basic uncalibrator is now in place, /// so Nhits is once more incremented with each new /// PMTUnCal (as it should be). /// - 28 Apr 2010 : G Orebi Gann - add a PMTTruth branch, to hold pure /// MC PMT hit information (i.e. with no uncal/cal applied) /// - 07 May 2010 : G Orebi Gann - add gTrigTime (GT time in ns) /// - 12 May 2010 : G Orebi Gann - make gTrigTime a float /// - 18-Jan_2011 : M. Hedayatipour - add posFitH2OQPDF and eFitQPDF /// - 03 Mar 2011 : G Orebi Gann - split PMT objects by chan type /// - 27 Apr 2011 : P G Jones - Add new FitResult structure /// - 21 Jun 2011 : R Bonventre - Added data cleaning word /// - 27 Apr 2012 : P G Jones - Add new ClassifierResult structure. /// Obsolete old fitters. /// - 01 Aug 2013 : R Bonventre - Updated data cleaning word /// - 2014-03-19 : P G Jones - New DS refactor, new name. /// - 2014-12-12 : M Mottram - FitResult/ClassifierExists return false if empty. /// - 2017-03-28 : T Kaptanoglu - Add NHits with no crosstalk /// - 2017-09-28 : Anthony LaTorre - Add in time hits /// - 2017-10-11 : T Kaptanoglu - Add calibration tag /// - 2018-09-27 : T Kaptanoglu - Add front-end polling tag /// /// \details An instance of this class exists for every triggered event /// in either the simulation or detector data. Note that in both cases /// the structure is equivalent. /// //////////////////////////////////////////////////////////////////////// #ifndef __RAT_DS_EV__ #define __RAT_DS_EV__ #include #include #include #include #include #include #include #include #include #include #include #include #include namespace RAT { namespace DS { class EV : public TObject { public: EV() : TObject(), clockCount50(0), clockCount10(0), pmtCalType(0), gtid(0), nhits(0), nhits_cleaned(0), totalCharge(0), eSumPeak(0), eSumDerivative(0), eSumIntegral(0), dataSet(0), trigError(0), trigType(0), tubiiTrig(0xC000000), clockStat10(0), iscal(0), ispolling(0) { } /// Set the event Universal Time /// /// This is the time of the event relative to the SNO+ time origin /// /// @param[in] time of the event in the universal time system void SetUniversalTime( const UniversalTime& time ) { universalTime = time; } /// Get the event Universal Time /// /// This is the time of the event relative to the SNO+ time origin /// /// @return time of the event in the universal time system UniversalTime GetUniversalTime() const { return universalTime; } /// Get the uncalibrated PMTs /// /// @return the set of uncalibrated pmts UncalPMTs& GetUncalPMTs() { return uncalPMTs; } /// @copydoc GetUncalPMTs() const UncalPMTs& GetUncalPMTs() const { return uncalPMTs; } /// Get the calibrated PMTs /// /// @return the set of calibrated pmts CalPMTs& GetCalPMTs() { return calPMTs; } /// @copydoc GetCalPMTs() const CalPMTs& GetCalPMTs() const { return calPMTs; } /// Get the current PMT calibration type /// /// @return the current PMT calibration type UInt_t GetPMTCalType() const { return pmtCalType; } /// Add a new calibration /// /// @param[in] pmts set of calibrated PMTs /// @param[in] calType type of calibrated applied inline void AddCalPMTs( const CalPMTs& pmts, const UInt_t calType ); /// Get a calibration by id /// /// @param[in] type calibration type to return /// @throws out_of_range if there are no pmts calibrated by the type CalPMTs& GetPartialCalPMTs( const UInt_t type ) { return partialCalPMTs.at( type ); } /// @copydoc GetPartialCalPMTs(Int_t) const CalPMTs& GetPartialCalPMTs( const UInt_t type ) const { return partialCalPMTs.at( type ); } /// Get the partial (intermediate) PMT Calibration types /// /// These are PMTs that have not had some but not all calibration applied to them - /// suggest consulting with PMTCal group to understand how to use these. /// /// @return vector of calibration types std::vector GetPartialPMTCalTypes() const { return keys_in_map( partialCalPMTs ); } /// Get the data cleaning flags /// /// @return reference to the flags DataQCFlags& GetDataCleaningFlags() { return dataCleaningFlags; } /// @copydoc GetDataCleaningFlags() const DataQCFlags& GetDataCleaningFlags() const { return dataCleaningFlags; } /// Set default fit results (for easy access and plotting) /// /// @param[in] name of the fit /// @param[in] vertex of the fit inline void SetDefaultFitVertex( const std::string name, const FitVertex& vertex ); /// Check if the default fit vertex exists /// /// @return true if it does Bool_t DefaultFitVertexExists() const { return !fit.empty(); } /// Get default fit results (for easy access and plotting) /// /// @return fit vertex (NULL if not present so that TTree->Draw skips) FitVertex GetDefaultFitVertex() const { if( fit.empty() ) return FitVertex(); return fit[0]; } /// Get default fit name (for easy access and plotting) /// /// @return fitName string std::string GetDefaultFitName() const { return fitName; } /// Prune default fit void PruneDefaultFit() { fitName = ""; clear_vector( fit ); } /// Create an empty fitter pass if none currently exists /// /// In case fitters fail, ensures default last pass number is correct /// /// @param[in] pass number void AddFitterPass( UInt_t pass ) { if( fitResults.count( pass ) == 0 ) fitResults[pass] = FitCollection(); } /// Get the FitCollection (collection of FitResults) for a given pass /// /// @param[in] pass number /// @return collection of results /// @throws DataNotFound error if no collection for given pass const FitCollection& GetFitResults( UInt_t pass ) const { if( fitResults.count( pass ) == 0 ) throw DataNotFound( "EV", "FitCollection" ); return fitResults.at( pass ); } /// Get the fit names for the last pass /// /// @return a vector of the fit names std::vector GetFitNames() const { if( fitResults.empty() ) return std::vector(); return fitResults.at( largest_key(fitResults) ).GetNames(); } /// Get Property for the FitResults for the last pass /// /// @param[in] name of fit /// @return result of fitter /// @throws DataNotFound if no fit results are stored /// @throws NoResultError if named fit not present const FitResult& GetFitResult( const std::string& name ) const { if( fitResults.empty() ) throw DataNotFound( "EV", "FitResult" ); return fitResults.at( largest_key(fitResults) ).GetResult( name ); } /// Check if a fit result exists for the last pass /// /// @param[in] name of fit /// @return true if present Bool_t FitResultExists( const std::string& name ) const { if( fitResults.empty() ) return false; return fitResults.at( largest_key(fitResults) ).ResultExists( name ); } /// Set Property for the FitResults /// /// param[in] pass number /// param[in] name of fit /// param[in] fitResult void SetFitResult( UInt_t pass, const std::string& name, const FitResult& fitResult ) { fitResults.at( pass ).SetResult( name, fitResult ); }; /// Prune FitResults for given pass /// /// @param[in] pass number void PruneFitResults( UInt_t pass ) { fitResults.erase( pass ); } /// Create an empty classifier pass if none currently exists /// /// In case classifiers fail, ensures default GetLastClassifierPassNumber is correct /// /// @param[in] pass number void AddClassifierPass( UInt_t pass ) { if( classifierResults.count( pass ) == 0 ) classifierResults[pass] = ClassifierCollection(); } /// Get the ClassifierCollection (collection of ClassifierResults) for a given pass /// /// @param[in] pass number /// @return collection of results /// @throws DataNotFound error if no collection for given pass const ClassifierCollection& GetClassifierResults( UInt_t pass ) const { if( classifierResults.count( pass ) == 0 ) throw DataNotFound( "EV", "ClassifierCollection" ); return classifierResults.at( pass ); } /// Get the classifier names for the last pass /// /// @return a vector of the classifier names std::vector GetClassifierNames() const { if( fitResults.empty() ) return std::vector(); return classifierResults.at( largest_key(classifierResults) ).GetNames(); } /// Get Property for the ClassifierResults for the last pass /// /// @param[in] name of classifier /// @return result of classifier /// @throws DataNotFound if no classifier results are stored /// @throws NoResultError if named classifier not present const ClassifierResult& GetClassifierResult( const std::string& name ) const { if( classifierResults.empty() ) throw DataNotFound( "EV", "ClassifierResult" ); return classifierResults.at( largest_key(classifierResults) ).GetResult( name ); } /// Check if a classifier result exists for the last pass /// /// @param[in] name of classifier /// @return true if present Bool_t ClassifierResultExists( const std::string& name ) const { if( classifierResults.empty() ) return false; return classifierResults.at( largest_key(classifierResults) ).ResultExists( name ); } /// Set Property for the ClassifierResults /// /// @param[in] pass number /// @param[in] name of classifier /// @param[in] classifierResult void SetClassifierResult( UInt_t pass, const std::string& name, const ClassifierResult& classifierResult ) { return classifierResults.at( pass ).SetResult( name, classifierResult ); } /// Prune ClassifierResults for given pass /// /// @param[in] pass number void PruneClassifierResults( UInt_t pass ) { classifierResults.erase( pass ); } /// Set CAEN digitiser information for this event /// /// @param[in] dig CAEN digitiser object void SetDigitiser( const Digitiser& dig ) {if( digitiser.empty() ) { digitiser.push_back(dig); } else { digitiser.at(0) = dig; } } /// Get CAEN digitiser information for this event /// /// @return CAEN digitiser information Digitiser& GetDigitiser() { if( digitiser.empty() ) throw DataNotFound( "EV", "Digitiser" ); return digitiser.at( 0 ); }; /// @copydoc GetDigitiser() const Digitiser& GetDigitiser() const { if( digitiser.empty() ) throw DataNotFound( "EV", "Digitiser" ); return digitiser.at( 0 ); }; /// Check if the digitiser exists /// /// @return true if it is present bool DigitiserExists() const { return !digitiser.empty(); } /// Prune digitiser information from this event void PruneDigitiser() { clear_vector( digitiser ); } /// Get Event ID (Global Trigger ID, GTID) /// /// @return globalTriggerID (GTID) Int_t GetGTID() const { return gtid; }; /// Set Event ID (Global Trigger ID, GTID) /// /// @param[in] gtid_ the global trigger ID void SetGTID(const Int_t gtid_) { gtid = gtid_; }; /// Get 50 MHz clock time /// /// @return clockCount50 50 MHz clock time in tick counts ULong64_t GetClockCount50() const{return clockCount50;}; /// Set 50Mz clock time /// /// @param[in] ticks 50 MHz clock time in tick counts void SetClockCount50(const ULong64_t ticks){clockCount50 = ticks;}; /// Get 10 MHz clock time /// /// @return clockCount10 10 MHz clock time in tick counts ULong64_t GetClockCount10() const{return clockCount10;}; /// Set 10 MHz clock time /// /// @param[in] ticks 10 MHz clock time in tick counts void SetClockCount10(const ULong64_t ticks){clockCount10 = ticks;}; /// Get 10 MHz clock status /// /// @return status 10 Mhz clock Char_t GetClockStat10() const{return clockStat10;}; /// Set 10 MHz clock status /// /// @param[in] stat status of 10 MHz clock void SetClockStat10(const Char_t stat){clockStat10 = stat;}; /// Get digitized ESUM peak /// /// @return eSumPeak ESUM peak Int_t GetESumPeak() const { return eSumPeak; }; /// Set digitized ESUM peak /// /// @param[in] eSumPeak_ void SetESumPeak(const Int_t eSumPeak_) { eSumPeak = eSumPeak_; }; /// Get digitized ESUM derivative /// /// @return eSumDiff ESUM derivative Int_t GetESumDerivative() const { return eSumDerivative; }; /// Set digitized ESUM derivative /// /// @param[in] eSumDiff_ void SetESumDerivative(const Int_t eSumDiff_) { eSumDerivative = eSumDiff_; }; /// Set digitized ESUM integral /// /// @return eSumInt ESUM integral Int_t GetESumIntegral() const { return eSumIntegral; }; /// Set digitized ESUM integral /// /// @param[in] eSumInt_ void SetESumIntegral(const Int_t eSumInt_) { eSumIntegral = eSumInt_; }; /// Get trigger error bits /// /// @return trigError error bits Int_t GetTrigError() const { return trigError; }; /// Set trigger error bits /// /// @param[in] trigError_ trigger error bits void SetTrigError(Int_t trigError_) { trigError = trigError_; }; /// Get trigger type /// /// @return trigType trigger type word Int_t GetTrigType() const { return trigType; }; /// Set trigger type /// /// @param[in] trigType_ trigger type word void SetTrigType(Int_t trigType_) { trigType = trigType_; }; /// Get TUBii trigger word /// /// @return tubiiTrig TUBii trigger word Int_t GetTubiiTrig() const { return tubiiTrig; }; /// Get an individual bit in TUBii trigger word /// /// @return trigBit Status of a bit in TUBii word bool GetTubiiTrigBit(Int_t bit) { return ((tubiiTrig >> bit) & 1); }; /// Set TUBii trigger word /// /// @param[in] tubiiTrig_ TUBii trigger word void SetTubiiTrig(Int_t tubiiTrig_) { tubiiTrig = tubiiTrig_; }; /// Set an individual bit in TUBii trigger word /// /// @param[in] bit, value void SetTubiiTrigBit(Int_t bit, bool value) { if(value==true) tubiiTrig |= 1 << bit; else tubiiTrig &= ~(1 << bit); }; /// A check to see if TUBii word exists /// Default value is 0xC000000, which is not possible in real data /// /// @return true if present bool TUBiiTrigExists() const { return (tubiiTrig != 0xC000000); } /// Get data splitter /// /// @return dataSet data splitter word Int_t GetDataSet() const { return dataSet; }; /// Set data splitter /// /// @param[in] dataSet_ data splitter word void SetDataSet(Int_t dataSet_) { dataSet = dataSet_; }; /// Get sum of all charge samples in this event /// /// @return totalQ sum of all charges in this event Double_t GetTotalCharge() const { return totalCharge; }; /// Set sum of all charge samples in this event /// /// @param[in] totalQ_ sum of all charges in this event void SetTotalCharge(Double_t totalQ_) { totalCharge = totalQ_; }; /// Get number of normal PMTs which where hit at least once /// /// @return number of hit PMTs UInt_t GetNhits() const { return nhits; }; /// Set the number of normal uncalibrated PMTs which were hit at least once /// /// @param[in] nhits_ number of hit PMTs void SetNhits( const UInt_t nhits_ ) { nhits = nhits_; }; /// Get number of normal PMTs which where hit at least once, /// with crosstalk hits removed /// /// @return number of hit PMTs, with crosstalk hits removed UInt_t GetNhitsCleaned() const { return nhits_cleaned; }; /// Set the number of normal calibrated PMTs which were hit at least once, /// with crosstalk hits removed /// /// @param[in] nhits_ number of hit PMTs, with crosstalk hits removed void SetNhitsCleaned( const UInt_t nhits_cleaned_ ) { nhits_cleaned = nhits_cleaned_; }; /// Get number of in time hits with triggers enabled in a ~89 ns time window. /// /// @return number of in time hits with triggers enabled Double_t GetInTimeHits100() const { return inTimeHits100; }; /// Set the number of in time hits with triggers enabled in a ~89 ns time /// window. /// /// @param[in] hits number of in time hits with triggers enabled void SetInTimeHits100( const Double_t hits ) { inTimeHits100 = hits; }; /// Get number of in time hits with triggers enabled in a ~46 ns time window. /// /// @return number of in time hits with triggers enabled Double_t GetInTimeHits20() const { return inTimeHits20; }; /// Set the number of in time hits with triggers enabled in a ~46 ns time /// window. /// /// @param[in] hits number of in time hits with triggers enabled void SetInTimeHits20( const Double_t hits ) { inTimeHits20 = hits; }; /// Get whether the event was tagged by calibration source /// /// @return true if event was tagged by calibration source Bool_t GetCalibrationEvent() const { return iscal; }; /// Set whether the event was tagged by calibration source /// /// @param[in] true if tagged by calibration source void SetCalibrationEvent( const Bool_t iscal_ ) { iscal = iscal_; }; /// Get whether the event was during front-end polling /// /// @return true if event was during front-end polling Bool_t GetPollingEvent() const { return ispolling; }; /// Set whether the event was during front-end polling /// /// @param[in] true if event was during front-end polling void SetPollingEvent( const Bool_t ispolling_ ) { ispolling = ispolling_; }; // This ROOT macro adds dictionary methods to this class. // The number should be incremented whenever this class's members are changed. // It assumes this class has no virtual methods, use ClassDef if change this. ClassDefNV( EV, 5 ); protected: UniversalTime universalTime; ///< Universal time of the event DataQCFlags dataCleaningFlags; ///< The data cleaning flags UncalPMTs uncalPMTs; ///< The uncalibrated PMTs for this event CalPMTs calPMTs; ///< The most recent (best) calibration PMTs for this event std::map< UInt_t, PMTSet > partialCalPMTs; ///< Calibrated PMTs by calibration identification std::string fitName; ///< The default fit name std::vector fit; ///< A single user-specified fit vertex for easy access std::map< UInt_t, FitCollection > fitResults; ///< FitCollection of FitResults, indexed by pass number std::map< UInt_t, ClassifierCollection > classifierResults; ///< ClassifierCollection of ClassifierResults, indexed by pass number std::vector digitiser; ///< The digitiser information (only one exists) ULong64_t clockCount50; ///< 50 MHz clock in tick counts ULong64_t clockCount10; ///< 10 MHz clock in tick counts UInt_t pmtCalType; ///< Identifier for the PMT calibration type Int_t gtid; ///< Event ID (Global Trigger ID, GTID) UInt_t nhits; ///< Number of normal/inward looking PMT hits in this event UInt_t nhits_cleaned; ///< Number of normal/inward looking PMT hits in this event, crosstalk removed Double_t inTimeHits100; ///< Maximum number of in time hits in a ~89 ns time window Double_t inTimeHits20; ///< Maximum number of in time hits in a ~46 ns time window Double32_t totalCharge; ///< Integrated uncalibrated charge for this event Int_t eSumPeak; ///< Digitized ESUM peak. Int_t eSumDerivative; ///< Digitized ESUM derivative. Int_t eSumIntegral; ///< Digitized ESUM integral. Int_t dataSet; ///< Data Splitter Word Int_t trigError; ///< Trigger error bits Int_t trigType; ///< Trigger word Int_t tubiiTrig; ///< TUBii Trigger word (defaults to 0xC000000 if TUBii data is not present) Char_t clockStat10; ///< 10 MHz clock status Bool_t iscal; ///< True if event tagged by calibration souce Bool_t ispolling; ///< True if event was during polling }; inline void EV::AddCalPMTs( const CalPMTs& pmts, const UInt_t calType ) { if( calPMTs.GetAllCount() > 0 ) partialCalPMTs[pmtCalType] = calPMTs; calPMTs = pmts; pmtCalType = calType; } inline void EV::SetDefaultFitVertex( const std::string name, const FitVertex& vertex ) { fitName = name; if( fit.empty() ) fit.push_back( vertex ); else fit[0] = vertex; } } // namespace DS } // namespace RAT #endif