/* * AeraEvent.h * * Created on: 17.11.2009 * Author: weindl */ #ifndef AERAEVENT_H_ #define AERAEVENT_H_ #include "amsg.h" #include "Event.h" #ifndef AERADEFS_H_ #include "AeraDefs.h" #endif #include #define AERA_EVENT_VERSION 1 // starting after 10 o'clock german time, 25.01.2011 #define SET_AERA_EVENT_VERSION(a) (a = ((AERA_EVENT_VERSION<<16) | a)) #define GET_AERA_EVENT_VERSION(a) ((a & 0xFFFF0000) >> 16) #define SET_AERA_EVENT_TYPE(a, type) ( a = ((type & 0xFFFF) | a)) #define GET_AERA_EVENT_TYPE(a) (a & 0xFFFF) #define MAX_EVBODY_SIZE (sizeof(EVENTBODY) + (int)LS_MAX_DATA_SIZE) /* Dutch trigger definitions: * The trigger flag is a bitmask describing what triggered the LS. * * Firmware v5: * trigger[0] = channel 1 // self * trigger[1] = channel 2 // self * trigger[2] = channel 3 // self * trigger[3] = channel 4 // self * trigger[4] = external // external (electronically on station level) * trigger[5] = 10 second // random * trigger[6] = calibration // calibration (by electronics) * trigger[7] = channel 1 & channel 2 // self * * Firmware v6: * single channel triggers are stored in the channel readout and trigger byte * (formerly just the channel readout) * * combination and alternate triggers sources are stored in the alt. trigger byte * (formerly the trigger byte) * * channel[5] = trig channel 1 // self * channel[6] = trig channel 2 // self * channel[7] = trig channel 3 // self * channel[8] = trig channel 4 // self * * trigger[3] = power ch1+ch2 // self * trigger[4] = external // external (electronically on station level) * trigger[5] = 10 second // random * trigger[6] = calibration // calibration (by electronics) * trigger[7] = channel 1 & channel 2 // self * */ /* Firmware version including trigger change */ #define NL_FIRMWARE_TRIG_VERS(fwvers) (fwvers <= 5 ? 0 : 1) /* This should not really be done in #defines! */ /* * Usage: trigger(alt_trig, channel_trig, NL_FIRMWARE_TRIG_VERS(fwversion)) * */ #define NL_TRIGGER_CHAN1(a, b, vers) (vers == 0 ? (a & 0x01) : (b & 0x10)) #define NL_TRIGGER_CHAN2(a, b, vers) (vers == 0 ? (a & 0x02) : (b & 0x20)) #define NL_TRIGGER_CHAN3(a, b, vers) (vers == 0 ? (a & 0x04) : (b & 0x40)) #define NL_TRIGGER_CHAN4(a, b, vers) (vers == 0 ? (a & 0x08) : (b & 0x80)) #define NL_TRIGGER_POW1a2(a, b, vers) (vers == 0 ? 0 : (b & 0x08)) #define NL_TRIGGER_EXT(a, b, vers) (a & 0x10) #define NL_TRIGGER_10S(a, b, vers) (a & 0x20) #define NL_TRIGGER_CAL(a, b, vers) (a & 0x40) #define NL_TRIGGER_CHAN1a2(a, b, vers) (a & 0x80) /* this has to be verified by the dutch guys!!!! #define NL_TRIGGER_EXT_T3_SD(a) (a & TRIGGER_T3_EXT_SD) #define NL_TRIGGER_EXT_T3_GUI(a) (a & TRIGGER_T3_EXT_GUI) #define NL_TRIGGER_EXT_T3_FD(a) (a & TRIGGER_T3_EXT_FD) */ #define NL_SELF_TRIGGER(a, b, vers) (vers == 0 ? (a & 0x8f) : (a & 0x88) | (b & 0xf0)) /* German trigger definitions * Trigger_flag&0x01=High-gain 1 channel, * Trigger_flag&0x02=High-gain 2 channel, * Trigger_flag&0x04=low-gain 1 channel, * Trigger_flag&0x08=low-gain 2 channel * Trigger_flag&0x10=external * Trigger_flag&0x20=10 second background readout */ #define DU_TRIG_CHAN1_HG(a) (a & 0x01) #define DU_TRIG_CHAN2_HG(a) (a & 0x02) #define DU_TRIG_CHAN1_LG(a) (a & 0x04) #define DU_TRIG_CHAN2_LG(a) (a & 0x08) #define DU_TRIGGER_EXT(a) (a & 0x10) #define DU_TRIGGER_10S(a) (a & 0x20) // this macro DU_TRIGGER_EXT_T3 is not unambiguous in this version! It checks SD, GUI, FD and external bit, which could also be a scintillator, but not before run 100104. // before run 100104, DU_TRIGGER_EXT means SD trigger!!! #define DU_TRIGGER_EXT_OLD(a) (DU_TRIGGER_EXT(a) || (a & TRIGGER_T3_EXT_SD) || (a & TRIGGER_T3_EXT_GUI) || (a & TRIGGER_T3_EXT_FD)) #define DU_TRIGGER_EXT_T3(a) ((a & TRIGGER_T3_EXT_SD) || (a & TRIGGER_T3_EXT_GUI) || (a & TRIGGER_T3_EXT_FD)) #define DU_TRIGGER_EXT_T3_SD(a) (a & TRIGGER_T3_EXT_SD) #define DU_TRIGGER_EXT_T3_GUI(a) (a & TRIGGER_T3_EXT_GUI) #define DU_TRIGGER_EXT_T3_FD(a) (a & TRIGGER_T3_EXT_FD) #define DU_SELF_TRIGGER_MASK 0x0F /* French trigger definitions * Bit Origin Name * 0 Trigger North-South Pole * 1 Trigger East-West Pole * 2 Trigger 1Wire * 3 Trigger External * 4 unused * 5 unused * 6 unused * 7 unused */ #define FR_TRIG_NS(a) (a & 0x01) #define FR_TRIG_EW(a) (a & 0x02) #define FR_TRIG_1WIRE(a) (a & 0x04) /* TO BE VERIFIED BY FRENCH GUYS - AND WHAT MEANS EXTERNAL FOR FRENCH ELECTRONICS? #define FR_TRIGGER_EXT_T3(a) ((a & 0x10) || (a & TRIGGER_T3_EXT_SD) || (a & TRIGGER_T3_EXT_GUI) || (a & TRIGGER_T3_EXT_FD)) #define FR_TRIGGER_EXT_T3_SD(a) (a & TRIGGER_T3_EXT_SD) #define FR_TRIGGER_EXT_T3_GUI(a) (a & TRIGGER_T3_EXT_GUI) #define FR_TRIGGER_EXT_T3_FD(a) (a & TRIGGER_T3_EXT_FD) */ #define FR_SELF_TRIGGER_MASK 0x03 // general aera event types #define SELF_TRIGGERED 0x0001 #define EXT_EL_TRIGGER 0x0002 #define CALIB_TRIGGER 0x0004 #define EXT_T3_SD_TRIGGER 0x0008 // by SD #define RANDOM_TRIGGER 0x0010 #define EXT_T3_GUI_TRIGGER 0x0020 // by Gui #define EXT_T3_FD_TRIGGER 0x0040 // by FD // how to access threshold informations: // in dutch electronics, the numbers indicate bytes, the byte index is given by (NL_MSG_DATA_STHRES1 - NL_MSG_OFFSET) // #include "scope.h" // header file of dutch electronics, to access thresholds in info_ADCbuffer // scope.h requires defintion of a version, which I cannot ensure outside, so the information is copied and hopefully updated if necessary ... #define NL_MSG_OFFSET 1 #define NL_MSG_DATA_STHRES1 23 #define NL_MSG_DATA_STHRES2 25 #define NL_MSG_DATA_STHRES3 27 #define NL_MSG_DATA_STHRES4 29 #define NL_MSG_DATA_NTHRES1 31 #define NL_MSG_DATA_NTHRES2 33 #define NL_MSG_DATA_NTHRES3 35 #define NL_MSG_DATA_NTHRES4 37 // in german electronics, the numbers are directly indices of UINT16 #define DU_MSG_DATA_STHRES1 6 #define DU_MSG_DATA_STHRES2 7 // for french electronics, the corresponding words contain more than just the threshold, and add. info numbering is the continued numbering from EVENTBODY #define FR_MSG_OFFSET 17 #define FR_MSG_DATA_STHRES1 27 #define FR_MSG_DATA_STHRES2 28 #define FR_THRES_MASK 0xFFF #define FR_LNA_MASK 0x8000 #define FR_LNA_ON(a) ((FR_LNA_MASK & a) ? true : false) namespace aera { /* LS data struct, keeping LS data - compare "Event Structure" (Table 6) and "Event Message" (Table 7) in "Message Structure v0.2" by Charles Timmermans * size: 36 bytes * this version is not conform to the "use ints within CRS" idea */ struct ls_data_unused { // added by aevb/postmaster short int length; short int ls_id; // coming up from ls char hardwareType; // NL, FR, DE int gps_second; // counted from 05.01.1980 int gps_nanoseconds; short int triggerflag; // why this ls sent data short int triggerpos; // no. of ADC channel? short int free_space1; short int free_space2; short int free_space3; short int free_space4; short int channel_count; // 1-4 ADC channels at ls short int tracelength; // count of samples per channel short int *data; // 1,5 * tracelength bytes, 1-12 bits directly appended for 1-4 channels } ; /** * @brief keeping LS data -NOT USED - replaced by ainc/amsg.h-EVENTBODY * * @struct ls_data AeraEvent.h ainc/AeraEvent.h * LS data struct, keeping LS data - either put in this form/struct by event builder or already by slave PC out of messages coming from LS * compare "Event Structure" (Table 6) and "Event Message" (Table 7) in "Message Structure v0.2" by Charles Timmermans * size: RECALCULATE! 60 = 15 * 4 plus data (=12288) => total size 12348 */ struct ls_data { // coming up from ls // added by aevb/postmaster UINT16 length; // count of shorts, including the length itself UINT16 ls_id; // contains station number and hardware type (NL, FR, DE) and hardware version UINT16 header_length; // length of the following header as count of shorts including this header_length itself // => 11 + length of free space unsigned int utc_second; // counted from 01.01.1970, derived from GPS unsigned int utc_nanoseconds; // depends on hardware UINT16 triggerflag; // why this ls sent data UINT16 triggerpos; // in fact the GPS-position: the position of the sample corresponding to the GPS timestamp, not necessarily the position of the pulse // depending on type of electronics, this value needs calibration UINT16 sampl_freq; // ADC sampling frequency in MHz UINT16 channel_mask; // Bit 0-3 indicating the ADC channels of ls, if bit is set, data follow in the order lowest channel ... UINT16 ADC_resolution; // resolution of ADC, 12 for 12 bit etc. UINT16 tracelength; // count of samples per channel UINT16 version; // version number, new since 07.02.2011 UINT16 additional_info[0]; // additional header information. Length defined by header length // UINT16 additional_info[LS_DATA_FREE_SPACE_SIZE/sizeof(int)]; // in upcoming data, 20 bytes are forseen as free space for additional information // to be extended on information about needs for French electronic from Jean-Luc int data[0]; // 1,5 * tracelength bytes, 1-12 bits directly appended for 1-4 channels } ; /** * @brief message send from postmaster(s) containing one (maybe several?) structs ls_data - NOT USED WITH Rc protocol */ // TODO: RECALCULATE size 4*4 + 12348 = 12364 struct ls_data_msg { UINT16 length; // length of message without size(length) UINT16 command; UINT16 runevno; ls_data lsd; }; #define GET_LST3INF_SEC(ls_time) ((ls_time & 0xFF000000) >> 24) #define GET_LST3INF_NSEC(ls_time) ((ls_time & 0x00FFFFFF)) // if bytes are in correct order #define GETT3STATIONSEC(t3station) (t3station->sec) // re-ordering of bytes, ns is in count of 64ns units! #define GETT3STATIONNS(t3station) ((t3station->NS1<<16) | (t3station->NS2<<8) | (t3station->NS3)) /** * @brief keeping information about a station beeing part of a t3 list * * @struct ls_t3_inf AeraEvent.h ainc/AeraEvent.h */ struct ls_t3_inf { int32_t ls_id; int32_t ls_time; // this is the sorted time information coming with T3 request: sec << 24 | NS1 << 16 | NS2 << 8 | .NS3; }; // size: 12 bytes /** * @brief keeping information about all stations composing a t3 list * * @struct t3_event_request_list AeraEvent.h ainc/AeraEvent.h */ struct t3_event_request_list { uint32_t length; // count of bytes of list without sizeof(length) uint32_t runevno; #ifdef USE_FIXED_MEMORY ls_t3_inf ls_t3_infp[LS_MAX_COUNT]; // for LS_MAX_COUNT = 25 on 32 bit, this means 1600 bytes per EventEntry #else ls_t3_inf *ls_t3_infp; // oldest first! #endif // #ifdef USE_FIXED_MEMORY // ls_t3_inf ls_t3_infp[1]; // oldest first! // ls_t3_infp contains/points to pairs of ls_id/ls_timestamps, count of pairs identified by (length - sizeof(runevno))/sizeof(ls_t3_inf) }; /** * @brief message containing a t3_event_request_list - NOT_USED * * @struct t3_event_request_list AeraEvent.h ainc/AeraEvent.h */ struct t3_event_request_list_msg { uint32_t length; // length of message without size(length) uint32_t tag; uint32_t subtag; t3_event_request_list t3erl; }; /** * @brief keeping general information about the event, and the LS data themselves * * @struct aera_event AeraEvent.h ainc/AeraEvent.h * size: ... bytes, depending on free space */ struct aera_event { int32_t length; // count of bytes of aera_event without sizeof(length) (( change to "and without lsdata" ???)) int32_t run_id; // running index of run numbers int32_t event_id; // number of event in run int32_t run_ev_id; // running number as created by t3_maker int32_t first_ls_id; // ID of LS with earliest time int32_t seconds; // time in seconds of LS with earliest time, UTC based int32_t nanoseconds; // resolution //int version; // versioning is included in event_type since 25.01.2011 int32_t event_type; // event_type && 0xFFFF = T3 event, ... / event_type & 0xFFFF0000 = aera_event version int32_t additional_info[AERA_EVENT_FREE_SPACE_SIZE/sizeof(int)]; // real size calculated by: length - sizeof(... all other final elements ... ) int32_t ls_count; // count (N) of LS/datablocks in event (with timebased/runeventno merging, there may be more than one per LS) // reserve the maximum possible space, copy data only to the places of LS included // AW, 28.05.2010 : switched from fixed length array to array of pointers, as each event has different size, and info size may be unlimited high void* lsdataptr[LS_MAX_COUNT]; //char lsdata[LS_MAX_COUNT * (int)(MAX_EVBODY_SIZE)]; }; #define AERA_EVENT_HEADER_SIZE offsetof(aera_event, lsdataptr) //#define AERA_EVENT_HEADER_SIZE (offsetof(aera_event, ls_count) + sizeof(aera_event::ls_count)) // which information is needed in aera_event to know about stations in T3 event request list struct aera_event_t3_inf { UINT16 ls_id; UINT16 ls_tag; // LS_EVENT, LS_NOEVENT }; struct aera_event_t3_list { UINT16 length; aera_event_t3_inf t3_inf[]; }; /** * @brief the AERA event file header, if several events are stored in a file, after the header, aera_event structs follow one by one * * @struct aera_file_header AeraEvent.h ainc/AeraEvent.h * size: 40 bytes, for 2 ints free space */ struct aera_file_header { int length; // size of header in count of bytes without sizeof(length) int run_id; // running index of run number int run_mode; // mode of run : normal, test, calibration int file_id; // running index of file number of the run int first_event_id; // event number of first event in file. Event number counted per run int first_event_time; // time of first event in file (in seconds, UTC based int last_event_id; // event number of last event in file. Event number counted per run int last_event_time; // time of last event in file (in seconds, UTC based int32_t additional_info[AERA_FILE_FREE_SPACE_SIZE/sizeof(int)]; }; //#define AERA_FILE_HEADER_ADDITIONAL_INFO_SIZE(afh) (afh.length + sizeof(afh.length) - offsetof(aera_file_header, additional_info)) /** * @brief a generic message structure in AERA, as used in communication internally in CRS, for ease of use, subtag AND data are defined, subtag optionally * * @struct aera_msg AeraEvent.h ainc/AeraEvent.h */ struct aera_msg { int length; // length of the complete message without sizeof(length) itself, in count of shorts int tag; // major tag int body[]; }; /** * @brief The AeraEvent class wraps around an area event * * @class AeraEvent AeraEvent.h ainc/AeraEvent.h * The AeraEvent class wraps around an aera event struct and eases initialization and access of parameters */ class AeraEvent : public Event { private: aera_event aev; public: AeraEvent(); AeraEvent(int32_t ls_count); AeraEvent(TimeStamp timeStamp); AeraEvent(int32_t ls_count, TimeStamp timeStamp); ~AeraEvent(); aera_event* getEvent(); void initEvent(); void dumpAeraEventStructure(); std::string dumpAeraEvent(); unsigned int getEventGPSSeconds(); unsigned int getEventSubSeconds(); void removeLSfromEvent(int lsid); void writeLSData(int position, EVENTBODY *evbp); }; // helper functions //std::string dumpEventList(std::list *evList); std::string dumpLSData(EVENTBODY *body); std::string dumpLSDataShort(EVENTBODY *body); std::string dumpMem (int* memp, int intCount); std::string dumpMemUINT16 (UINT16* memp, int intCount); std::string dumpEventShort(aera_event* aep); std::string dumpT3List(t3_event_request_list *t3erlp); std::string dumpT3List(AMSG *amsgp); std::string dumpT3ListShort(AMSG *amsgp); int getLSInfCountFromT3List(t3_event_request_list *t3erlp); int getLSInfCountFromT3ListRcMsg(AMSG *amsgp); std::string dumpAeraFileHeader(aera_file_header* afhp); uint16_t getT2countFromAmsg(AMSG *amsgp); void dumpT2Body(T2BODY *t2bp, uint16_t t2count); void dumpT2Amsg(AMSG *t2msg); /* class AeraEvent : public Event { private: aera_event aep; public: AeraEvent(); virtual ~AeraEvent(); void dumpAeraEventStructure(); void writeLSData(int lsid, short *lsData); }; */ }; // namespace aera #endif /* AERAEVENT_H_ */