// // File : MiEventHeader.hh // // Purpose: Declaration of Mirror event header class // // Author : H.-J. Mathes, Forschungszentrum Karlsruhe, IK // // $Id: MiEventHeader.hh 12217 2011-03-16 21:24:22Z mathes $ // /** @file MiEventHeader.hh * Declaration of class TMirrorEventHeader. * @author H.-J. Mathes, FzK */ #ifndef _MiEventHeader_hh_ #define _MiEventHeader_hh_ // --> prevent users from including that file directly #ifndef __CINT__ # if (!defined _MiEvent_hh_) && (!defined _VMiEvent_hh_) # error You are not supposed to include that header file ! # error Please use MiEvent.hh instead ! # endif // !_MiEvent_hh_ && !_VMiEvent_hh_ #endif // __CINT__ #include #include #include #include #include #include #include /** This class contains general, event related information. This information * consists at present of: * * @li the Eye and Mirror number, the numbers are chosen according to the * numbering conventions at the Eye level * @li the 'run number' of the current RUN * @li an event and a trigger number. The 'event number' (T2 count) is * increased for each accepted event whereas the 'trigger number' (T1 * count) is increased for each trigger received from the SLT electronic. * @li several time related informations: *
    *
  • the GPS time and the GPS nano time of the current event.
    * Note: Old data before October 2001 have the system time * stored here. *
  • the UTC time of the event, at present UTC = GPS + 315964800 *
    * Note: The system time of the event could be calculated using: * Sys = GPS + 315964800 - 13 *
  • the used value for the NextPageDelay which is the time between * the first trigger in the camera and the time of the page switching *
  • the time stamp when the SLT/FLT hardware switched to the next * page in memory.
    * Note: For some data the GPSNanoTime might have been incorrectly * calculated. As the NextPageTimeStamp is the information * read directly from the hardware and is supposed to be * without this error ! *
* @li the trigger source of the current event * @li the event type of the current event which might distinguish between * different operation modes (see enum EMiEventType). * @li the event label of the current event which is assigned to the event * by the TLT (third level trigger) software trigger (see enum * EMiEventLabel) * @li the T3 id, a number which is assigned to the event by the Mirror * level T3 processor. This number might be used for debugging purposes * together with CDAS as long as only one Mirror DAQ system is active. * * Note: The time stamps sub-second information is coded according to the * values read from the corresponding hardware registers: * @li the tick counter, 0 ... 1999, counting the number of 50 ns ticks, * written to bits 0:10 * @li the overflow of the 50 ns tick counter which counts the number of 100 * usec intervalls, thus 0 ... 9999, written to bits 11:24 * */ class TMirrorEventHeader : public TObject { friend class TEyeEvent; friend class TShmEvent; friend class TMirrorEvent; friend class ShmEventDescriptor; friend class TFADCData; friend bool TestMirrorStructSizes(); // test code protected: /** Definition of some constants. */ enum { /** Number of nanosecs per second. */ kNanoSecPerSecond = 1000000000 }; /** Definition of the bit positions in fEventBits bit vector. */ typedef enum { /** VETO bit is set. */ kIsVeto = 0x01 } EEventBits; /** This structure describes the (optional) time correction parameters. */ typedef struct _MiTimeCorrectionParameterRec { /** Length of the a 10MHz pulse from the gps unit [ns]. */ Float_t fT10Mhz; /** Offset/Phase between 1PPS signal and 10MHz signal [ns]. */ Float_t fOffset; } MiTimeCorrectionParameterRec, *MiTimeCorrectionParameter; /** Event header structure of the mirror event. * * At present this structure contains the following information: * @li MiEventHeader version number * @li the mirror number in the eye internal numbering scheme * @li the GPS time of the event (seconds since ...) * @li the GPS nano time (sub-seconds in units of nano seconds) * @li the trigger number (T1) * @li the event number (T2), always T2 <= T1 * @li the time stamp of the last trigger signal * @li the time stamp of the NextPage signal * @li the NextPageDelay value * @li the current trigger source * @li the RUN number * @li the dead time counter (this counter is reset at the start of RUN) * @li the VETO time counter (this counter is reset at the start of RUN) * @li a number of status/state bits * * @todo The following items could be added to the event header: * @li the hardware detector_id */ typedef struct _MiEventHeader { /** Internally used structure version number. */ Version_t fVersion; /** Number of the mirror and the eye from where the event was read. */ FdUtil::Fd::MirrorNumberRec fMirrorNumber; /** Bit vector which decodes different states ... */ int fEventBits; /** An optional label which could be assigned to the event. */ int fEventLabel; /** Event number of current event in current run. */ unsigned int fEventNo; /** The type of the event described by these data. */ unsigned char fEventType; /** Time (in sec.) when the trigger for that event happens. */ unsigned int fGpsTime; /** Sub-second (0..999999999 nano secs.) event time. */ unsigned int fGpsNanoTime; /** Trigger number of current event. Each triggered * event is assigned a trigger number regardless if * the event is read out or not. */ unsigned int fTriggerNo; /** 'Time stamp' of the trigger. */ unsigned int fTriggerTimeStamp; /** GPS time of the next page signal (NxPage). */ unsigned int fNextPageTime; /** Nanosec time of the next page signal (NxPage). */ unsigned int fNextPageNanoTime; /** TimeStamp of the NextPage signal (low). * This is a value read from a register, its interpretation might * differ betwen different hardware versions. */ unsigned int fNextPageTimeStampL; /** TimeStamp of the NextPage signal (high). */ unsigned int fNextPageTimeStampH; /** Value of the NextPageDelay parameter. */ unsigned int fNextPageDelay; /** Current value of the events trigger source. */ unsigned char fTriggerSource; /** Current RUN number. */ unsigned int fRunNo; /** T3 id assigned by the CDAS interface. */ unsigned short fT3Id; #ifndef __CINT__ /** The accumulated dead time since start of RUN. */ unsigned long long fDeadTimeCounter; #else unsigned int fDeadTimeCounter[2]; #endif // __CINT__ /** The accumulated RUN time since start of RUN. */ unsigned long long fRunTimeCounter; #ifndef __CINT__ /** The accumulated VETO time since start of RUN. */ unsigned long long fVetoTimeCounter; #else unsigned int fVetoTimeCounter[2]; #endif // __CINT__ /** Optionally time correction parameters, normally left empty. */ MiTimeCorrectionParameterRec fTimeCorrection; unsigned long long fDaqDeadTime; //<<< dead time caused by the DAQ unsigned int fNSkippedTriggers; /** Version info from FLT and SLT. */ unsigned int fFLTVersion; unsigned int fSLTVersion; } MiEventHeaderRec, *MiEventHeader; public: /** Enumeration type for the various event types. * The event type is determined by the trigger type which gives * that event. */ typedef enum { /** Event type is not known or not set. */ kUnknownEvent, /** A physics event, the real purpose of the DAQ. */ kPhysicsEvent, /** Any type of artificial (calibration) event. */ kCalibrationEvent, /** A simulated event, usually generated by the DAQ simulation * (no physics). */ kSimulatedEvent } EMiEventType; /** Enumeration type for different event labels which are assigned to the * events after the Mirror based 3rd level trigger (TLT). */ typedef enum { /** Event has not yet been labelled or this feature is not supported. */ kUnlabelled = 0, /** Identical to kUnlabelled. */ kDefault = kUnlabelled, /** Event was accepted by the readout process. */ kAcceptedEvent, /** Event was identified to be a muon event. */ kMuonEvent, /** Event seems to be a shower candidate. */ kShowerCandidate, /** Event is a real shower. */ kShowerEvent, /** Event has a random time order. */ kRandomEvent, /** Event has very much pixels set, probably e-noise of lightning. */ kManyPixelEvent, /** Event should be rejected, but is kept for trigger studies. */ kRejected = 99 } EMiEventLabel; /** A definitions of masks for the possible trigger sources of the * Mirror DAQ. * * Note: These masks coincide with the SLT_TRIGGER_* macros of the * FE hardware revision V3, see also Hw/SltStatusReg.h and * Hw/SltDef.h * * In V4 they are finalyl also identical, see hw4/sltdef.h */ typedef enum { kUnknownTrigger = 0x00, kIllegalTrigger = kUnknownTrigger, kSoftwareTrigger = 0x01, kRightTrigger = 0x02, kLeftTrigger = 0x04, kInternalTrigger = 0x08, kExternalTrigger = 0x10, #ifdef USE_HW_V4 kFrontTrigger = 0x20, #endif // USE_HW_V4 #ifdef USE_HW_V4 kTriggerMask = 0x3f #else kTriggerMask = 0x1f #endif // USE_HW_V4 } EMiTriggerSource; /** Default constructor of the class TMirrorEVentHeader. Space for the * TMirrorEventHeader is allocated separately within this method. * * This constructor is needed (at least) by ROOT to create an object of * this class in memory. */ TMirrorEventHeader(); /** Constructor for the class TMirrorEventHeader from a void pointer. */ TMirrorEventHeader(void *); /** Copy constructor of the class TMirrorEventHeader. */ TMirrorEventHeader(const TMirrorEventHeader&); /** Destructor for class TMirrorEventHeader using the private variable * fConstructorType to decide how to delete the object. */ virtual ~TMirrorEventHeader(); /** operator=() for class TMirrorEventHeader. * * This operator has to be defined in order to perform a deep copy of * a TMirrorEventHeader object. */ TMirrorEventHeader& operator=(const TMirrorEventHeader&); public: /** Clear the contents of the object (preset with default values). */ virtual void Clear(Option_t * ="") { Init(); } /** Correct the pair of times in [sec,nsec] representation. * * @return true, if correction was successful. */ bool DoTimeCorrection(UInt_t sec_in,Int_t nsec_in, UInt_t* sec_out,UInt_t* nsec_out) const; /** Print the event headers content verbosely to the specified stream. * * Changes: * @li 2001/07/19 (thjm) changed to cout implementation * @li 2001/05/11 (thjm) added kSimulatedEvent and fixed wrong name. */ void Show(std::ostream& ostr=std::cout) const; // --- getters ... /** Get the total dead time of the DAQ (in multiples of 100 nsec). */ unsigned long long GetDaqDeadTime() const { return fHeader->fDaqDeadTime; } /** Get the time in nsec of the specified FADC bin. */ UInt_t GetFADCBinNanoTime(TFADCData*,UInt_t) const; /** Get the time in sec of the specified FADC bin. */ UInt_t GetFADCBinTime(TFADCData*,UInt_t) const; /** Get the time in nsec when the FADC trace is starting. */ UInt_t GetFADCTraceStartNanoTime(TFADCData* fadc) const { return GetFADCBinNanoTime( fadc, 0 ); } /** Get the time in sec when the FADC trace is starting. */ UInt_t GetFADCTraceStartTime(TFADCData* fadc) const { return GetFADCBinTime( fadc, 0 ); } /** Get the time in nsec of the specified SLT bin. */ UInt_t GetSltBinNanoTime(UInt_t bin) const { return GetFADCBinNanoTime( NULL, bin * 10 ); } /** Get the time in sec of the specified SLT bin. */ UInt_t GetSltBinTime(UInt_t bin) const { return GetFADCBinTime( NULL, bin * 10 ); } /** Get the time in nsec when the SLT trace is starting. */ UInt_t GetSltStartNanoTime() const { return GetSltBinNanoTime( 0 ); } /** Get the time in sec when the SLT trace is starting. */ UInt_t GetSltStartTime() const { return GetSltBinTime( 0 ); } #ifndef __CINT__ /** Get the current value of the dead time counter. */ unsigned long long GetDeadTimeCounter() const { return fHeader->fDeadTimeCounter; } #endif // __CINT__ /** Get the current value of the RUN time counter. */ unsigned long long GetRunTimeCounter() const { return fHeader->fRunTimeCounter; } #ifndef __CINT__ /** Get the current value of the VETO time counter. */ unsigned long long GetVetoTimeCounter() const { return fHeader->fVetoTimeCounter; } #endif // __CINT__ /** Retrieve the label given to the current event. */ EMiEventLabel GetEventLabel() const { return (EMiEventLabel)fHeader->fEventLabel; } /** Retrieve the event number from the event header. The event number is * used as an individual number for each accepted event of a run. */ unsigned int GetEventNo() const { return fHeader->fEventNo; } /** Retrieve the current event's type from the event header. */ EMiEventType GetEventType() const { return (EMiEventType)fHeader->fEventType; } /** Get the eye number which is stored in the event header. */ unsigned int GetEyeNo() const { return FdUtil::Fd::GetEyeNo( &fHeader->fMirrorNumber ); } /** Get the version of the FLT of the hardware, 0 if not applicable. */ unsigned int GetFltVersion() const { return fHeader->fFLTVersion; } /** Retrieve the GPS time of the current event from the event header. * * The GPS time counts the seconds since 6.1.1980 0:00 UTC and is * synchronized with the GPS '1 second' signal. */ UInt_t GetGPSTime() const; /** Retrieve the GPS nano time of the current event which is stored in the * event header. * * The GPS nano time is a fine resolution clock counting within the GPS * synchronized '1 second' interval. * Its possible values are: 0... 999999999, i.e. the finest resolution is * 1 ns, though the ADC binning is only 100 ns. */ UInt_t GetGPSNanoTime() const; /** Get the mirror number which is stored in the event header. */ UInt_t GetMirrorNo() const { return FdUtil::Fd::GetMirrorNo( &fHeader->fMirrorNumber ); } /** Retrieve the composite mirror number which is stored in the event * header. */ FdUtil::Fd::MirrorNumber GetMirrorNumber() const { return &fHeader->fMirrorNumber; } /** Get the parameter NextPageDelay from the event header. */ UShort_t GetNextPageDelay() const { return fHeader->fNextPageDelay; } /** Get the GPS time of the occurrence of the NxPage signal. */ UInt_t GetNextPageTime() const { return fHeader->fNextPageTime; } /** Get the nano second time of the occurrence of the NxPage signal. */ UInt_t GetNextPageNanoTime() const { return fHeader->fNextPageNanoTime; } /** Get the number of skipped triggers of the present RUN (due to DAQ VETO algorithms etc.). */ UInt_t GetNumSkippedTriggers() const { return fHeader->fNSkippedTriggers; } /** Return the RUN number stored in the event header. */ UInt_t GetRunNo() const { return fHeader->fRunNo; } /** Get the version of the SLT of the hardware, 0 if not applicable. */ unsigned int GetSltVersion() const { return fHeader->fSLTVersion; } /** Get the time stamp information for the trigger (lower part). */ UInt_t GetTriggerTimeStamp() const { return fHeader->fTriggerTimeStamp; } /** Return the high part of the time stamp. */ UInt_t GetTimeStampHigh() const { return fHeader->fNextPageTimeStampH; } /** Return the low part of the time stamp. */ UInt_t GetTimeStampLow() const { return fHeader->fNextPageTimeStampL; } /** Retrieve the trigger number from the event header. * * The trigger number is a 'private' counting variable counting all * triggers even when the event is later on rejected. * * This variable might be useful for deadtime or trigger ratio calculations. * * This variable is sometimes referred as T1 trigger rate. */ UInt_t GetTriggerNo() const { return fHeader->fTriggerNo; } /** Retrieve the trigger source of the actual event which is stored in the * event header. */ EMiTriggerSource GetTriggerSource() const { return (EMiTriggerSource)fHeader->fTriggerSource; } /** Return the T3 id which might have been assigned to that event. * * This T3 id is normally in the range 4096 < t3_id < 8192. If a value * outside this range is returned, no T3 id has ever been assigned. */ UShort_t GetT3Id() const { return fHeader->fT3Id; } #if 0 /** Retrieve the UTC time of the current event. The UTC time starts at * 1.1.1970 00:00 UT. It differs from the GPS time by 315964800 seconds. */ UInt_t GetUTCTime() const { return FdUtil::TimeConvert::GetUTCTimeFromGPSTime( GetGPSTime() ); } #endif /** Get the event type (EMiEventLabel) verbosely. */ static const std::string GetVerboseEventLabel(EMiEventLabel); /** Get the event type (EMiEventType) verbosely. */ static const std::string GetVerboseEventType(EMiEventType); /** Get the trigger source (EMiTriggerSource) verbosely. */ static const std::string GetVerboseTriggerSource(EMiTriggerSource); /** Retrieve the version number describing the current version of the event * header data structure which is stored in the event header. */ Version_t GetVersion() const { return fHeader->fVersion; } /** Retrieve the Unix time of the current event. The Unix time starts at * 1.1.1970 00:00 UT. It differs from the GPS time by 315964800 - 13 * seconds. * @todo * @li develop a function which converts from GPS to UTC and vice versa * and which takes the current number of leap seconds into account. */ UInt_t GetUnixTime() const { return FdUtil::TimeConvert::GetUnixTimeFromGPSTime( GetGPSTime() ); } /** Return the status of the FE crate VETO line during DAQ. */ bool IsVeto() const { return (fHeader->fEventBits & kIsVeto) ? true : false; } // --- setters ... /** Set the DAQ dead time (* 100 nsec). */ void SetDaqDeadTime(unsigned long long dead_time) { fHeader->fDaqDeadTime = dead_time; } #ifndef __CINT__ /** Set the current value of the dead time counter. */ void SetDeadTimeCounter(unsigned long long dead_time) { fHeader->fDeadTimeCounter = dead_time; } #endif // __CINT__ /** Set the event label for the current event. */ void SetEventLabel(EMiEventLabel label) { fHeader->fEventLabel = (Int_t)label; } /** Set the event number in the event header. */ void SetEventNo(UInt_t event_no) { fHeader->fEventNo = event_no; } /** Set the current events type in the event header. */ void SetEventType(EMiEventType type) { fHeader->fEventType = (int)type; } /** Set the eye number and stored in the event header. */ void SetEyeNo(UInt_t eye_num) { FdUtil::Fd::SetEyeNo( &fHeader->fMirrorNumber, eye_num ); } /** Set the version of the FLT. */ void SetFltVersion(unsigned int v) { fHeader->fFLTVersion = v; } /** Set the mirror number and stored in the event header. */ void SetMirrorNo(UInt_t mirror_no) { FdUtil::Fd::SetMirrorNo( &fHeader->fMirrorNumber, mirror_no ); } /** Set the parameter NextPageDelay() of the event header. */ void SetNextPageDelay(UShort_t delay) { fHeader->fNextPageDelay = delay; } /** Set the time (in sec) of the occurrence of the NxPage signal. */ void SetNextPageTime(UInt_t nxpage_time) { fHeader->fNextPageTime = nxpage_time; } /** Set the nano time (in nsec) of the occurrence of the NxPage signal. */ void SetNextPageNanoTime(UInt_t nxpage_nano_time) { fHeader->fNextPageNanoTime = nxpage_nano_time; } /** Set the number of skipped trigger (due to DAQ dead time). */ void SetNumSkippedTriggers(UInt_t n_skipped) { fHeader->fNSkippedTriggers = n_skipped; } /** Set the curent RUN number in the event header. */ void SetRunNo(UInt_t run_no) { fHeader->fRunNo = run_no; } /** Set the current value of the RUN time counter. */ void SetRunTimeCounter(unsigned long long run_time) { fHeader->fRunTimeCounter = run_time; } /** Set the two time correction constants for the calculation of the * exact times of, for example individual FADC bins. * * @see GetFADCBinNanoTime(), GetFADCBinTime(), * GetFADCTraceStartNanoTime() and GetFADCTraceStartTime(). */ void SetTimeCorrectionParameters(Float_t t10,Float_t offset); /** Set the high part of the NextPage signals time stamp in the event * header. */ void SetTimeStampHigh(UInt_t time_high) { fHeader->fNextPageTimeStampH = time_high; } /** Set the low part of the NextPage signals time stamp in the event * header. */ void SetTimeStampLow(UInt_t time_low) { fHeader->fNextPageTimeStampL = time_low; } /** Set the trigger number of the current event. */ void SetTriggerNo(UInt_t trigger_no) { fHeader->fTriggerNo = trigger_no; } /** Set the low part of the time stamp of the trigger. */ void SetTriggerTimeStamp(UInt_t time_low) { fHeader->fTriggerTimeStamp = time_low; } /** Set the trigger source indication in the event header. */ void SetTriggerSource(EMiTriggerSource trigger_source) { fHeader->fTriggerSource = (EMiTriggerSource)trigger_source ; } /** Set the T3 id for the current event. */ void SetT3Id(UShort_t t3_id) { fHeader->fT3Id = t3_id; } /** Set the version of the SLT. */ void SetSltVersion(unsigned int v) { fHeader->fSLTVersion = v; } #ifndef __CINT__ /** Set the current value of the VETO time counter. */ void SetVetoTimeCounter(unsigned long long veto_time) { fHeader->fVetoTimeCounter = veto_time; } #endif // __CINT__ public: /** Reset the time correction warnings ... */ static void ResetTimeCorrectionWarning() { fgTimeCorrectionWarningDisabled = false; } protected: /** Get the current values of the time correction parameters. */ void GetTimeCorrectionParameters(Float_t *t10,Float_t *offset) const; /** Return 'true' if the time correction parameters are set. */ bool IsTimeCorrectionSet() const { return (fHeader->fTimeCorrection.fT10Mhz > 50.0); } /** Return 'true' if the timing data is excact, i.e. the 10 MHz is 10 MHz * (T_10 = 100). * * This is the case for all data recorded with version 3 or less and * for all data of version 4 recorded until April 2002. * * The first production data has been measured with FDEventLib-v2r0, v2r1 * which produces also version 4 data but a different GPS clock was used. */ bool IsOldTimingFormat() const; /** Calculate the time of the NxPage signal from GPS (event time) time. */ void SetNextPageTimes(); #if 0 UInt_t AddTime(UInt_t t_sec, UInt_t t_nano); UInt_t AddNanoTime(UInt_t t_sec, UInt_t t_nano); UInt_t SubtractTime(UInt_t t_sec, UInt_t t_nano); UInt_t SubtractNanoTime(UInt_t t_sec, UInt_t t_nano); #endif private: /** */ void Construct() { fHeader = new MiEventHeaderRec(); } /** */ void Destruct() { delete fHeader; fHeader = NULL; } /** Initialize the data structure to its default values. */ void Init(); MiEvent::Constructor_t fConstructorType; //! how object was created MiEventHeader fHeader; //! pointer to C struct static bool fgTimeCorrectionWarningDisabled; //! ClassDef(TMirrorEventHeader,MiEVENTVERSIONv8) }; #endif // _MiEventHeader_hh_