/** @file CbmDaq.h ** @author Volker Friese ** @date 20 July 2012 ** **/ #ifndef CBMDAQ_H #define CBMDAQ_H 1 #include #include #include "TStopwatch.h" #include "FairTask.h" #include "CbmDaqBuffer.h" #include "CbmMCEventList.h" class TClonesArray; class CbmDigi; class CbmDigitize; class CbmMatch; class CbmTimeSlice; /** @class CbmDaq ** @author Volker Friese ** @date 20 July 2012 ** @brief CBM task class for filling digis into time slices ** ** The CbmDaq collects raw data (digis) from various input sources ** (detectors), sorts them w.r.t. time and fills time slices. ** The digis in one time slice are written to TCLonesArrays as branches of ** the output tree. One tree entry corresponds to one time slice (interval), ** the duration of which can be adjusted. **/ class CbmDaq : public FairTask { public: /** @brief Constructor ** @param interval Duration of a time-slice [ns] ** ** By default, the DAQ will run in time-based mode. The event-based mode ** can be selected by the method SetEventMode. ** If the time-slice interval is negative (default), all data will be ** written into one time-slice. Otherwise, time-slices of equal lengths ** will be created. **/ CbmDaq(Double_t interval = -1.); /** @brief Destructor **/ ~CbmDaq(); /** @brief Task execution **/ virtual void Exec(Option_t* opt); /** @brief Initialisation **/ virtual InitStatus Init(); /** @brief Check whether DAQ runs in event-by-event mode ** @value kTRUE if DAQ is in event-by-event mode **/ Bool_t IsEventMode() { return fEventMode; } /** @brief Receive data ** @param digi Unique pointer to digi object ** @param match Unique pointer to match object ** ** This method is to be used from the registered digitizers. ** The data will be buffered and sorted into the output time-slices. ** The digi pointer is asserted for validity. **/ void ReceiveData(up_CbmDigi digi, up_CbmMatch match); /** @brief Set the DAQ buffer time ** @param time Buffer time [ns] ** ** To guarantee time-ordering and correct sorting of digis into ** time-slices, the DAQ writes digis into the output time-slice ** only up to a maximum time, which is is time of the previous ** event minus the buffer time. The buffer time takes into account ** the disordered delivery of digis by the digitizers. It should ** at least be the maximum dead time of all detectors plus ** some safety margin accounting for the time resolution of the ** detectors. ** The current default of 1,000 ns corresponds to the STS with ** dead time of 800 ns and time resolution of 5 ns. **/ void SetBufferTime(Double_t time) { fBufferTime = time; } /** @brief Set event-by-event mode ** @param choice If kTRUE, digitisation will be done event-by-event ** ** In the event-by-event mode, one time slice will be created for ** each input event. There will be no interference between events. **/ void SetEventMode(Bool_t choice = kTRUE) { fEventMode = choice; } /** @brief Set the digitizer for a given system ** @param system System Id (ECbmModuleId) ** @param digitizer Pointer to digitizer instance **/ void SetDigitizer(Int_t system, CbmDigitize* digitizer); /** @brief Set the time-slice length ** @param length Length of a time-slice [ns] **/ void SetTimeSliceLength(Double_t length) { fTimeSliceLength = length; } /** @brief Store all time-slices ** @param choice If kTRUE; also empty slices will be stored. ** ** By default, only time slices containing data are filled into the tree. **/ void StoreAllTimeSlices(Bool_t choice = kTRUE) { fStoreEmptySlices = choice; } private: Bool_t fEventMode; ///< Flag for event-by-event mode Double_t fTimeSliceLength ; ///< Time-slice length [ns] Double_t fBufferTime; ///< Maximal time disorder of input data [ns] Bool_t fStoreEmptySlices; ///< Flag to store also empty time slices Double_t fTimeEventPrevious; ///< Time of previous event [ns] Int_t fNofEvents; ///< Number of processed events Int_t fNofDigis; ///< Total number of processed digis Int_t fNofDigisIgnored; ///< Number of ignored digis Int_t fNofTimeSlices; ///< Number of time slices Int_t fNofTimeSlicesEmpty; ///< Number of empty time slices Double_t fTimeDigiFirst; ///< Time of first digi Double_t fTimeDigiLast; ///< Time of last digi Double_t fTimeSliceFirst; ///< Start time of first time slice Double_t fTimeSliceLast; ///< Stop time of last time slice TStopwatch fTimer; //! Stop watch std::map fDigis; //! Output arrays (digis) std::map fDigitizers; //! CbmTimeSlice* fTimeSlice; //! Current time slice CbmDaqBuffer fBuffer; //! DaqBuffer instance CbmMCEventList fEventList; //! MC event list (all) CbmMCEventList* fEventsCurrent; //! MC events for current time slice /** First and last event in current time slice for each input **/ std::map> fEventRange; //! /** Close the current time slice ** The current slice is filled to the tree. It is then reset ** to the next time slice interval. */ void CloseTimeSlice(); /** Copy the MC events contributing to the current time slice ** to the output array. ** ** @value Number of MC events for this time slice **/ Int_t CopyEventList(); /** @brief Copy data (digi) from the DaqBuffer into the output array ** @param digi Pointer to digi object **/ void FillData(CbmDigi* digi); /** Fill data from the buffer into the current time slice ** @param fillTime Maximum time for digis to be filled ** @param limit Apply time limit for filling from buffer ** @return Number of digis filled into the time slice ** ** If limit if kFALSE, all data from the buffer ** are copied to the time slice. **/ Int_t FillTimeSlice(Double_t fillTime, Bool_t limit = kTRUE); /** Screen log of the range of MC events contributing to the ** current time slice **/ void PrintCurrentEventRange() const; /** @brief Register input and entry number of a MC event contributing data ** to the current time slice. ** @param digi Pointer to digi object. ** ** CbmDaqNew stores the first and last event for each input such that ** it can be copied from the event list after the time slice is ** closed and filled to the tree. ** ** TODO: Legacy implementation for match objects carried with the digi object. ** For TOF development branch only (CbmTofDigi or CbmTofDigiExp). Should be ** removed once TOF is in line. **/ void RegisterEvent(CbmDigi* digi); /** @brief Register input and entry number of a MC event contributing data ** to the current time slice. ** @param match Pointer to match object. ** ** CbmDaqNew stores the first and last event for each input such that ** it can be copied from the event list after the time slice is ** closed and filled to the tree. **/ void RegisterEvent(const CbmMatch& match); /** @brief Register input and entry number of a MC event contributing data ** to the current time slice. ** @param data Pair of unique pointers to digi and match objects ** ** CbmDaqNew stores the first and last event for each input such that ** it can be copied from the event list after the time slice is ** closed and filled to the tree. **/ void RegisterEvent(const CbmDaqBuffer::Data& data); /** At end of run: Process the remaining data in the CbmDaqBuffer **/ virtual void Finish(); /** @brief Trigger data write to the output ** @param Data Pair of unique pointers to digi and match objects **/ void WriteData(CbmDaqBuffer::Data& data); /** Copy constructor and assignment operator are not allowed. **/ CbmDaq(const CbmDaq&) = delete; CbmDaq& operator=(const CbmDaq&) = delete; ClassDef(CbmDaq, 3); }; #endif /* CBMDAQ_H */