| 1 | /********************************************************************\
 | 
|---|
| 2 | 
 | 
|---|
| 3 |   RawDataCTX.cc
 | 
|---|
| 4 | 
 | 
|---|
| 5 |   Class for raw data handling of the DRS 2-based DAQ
 | 
|---|
| 6 | 
 | 
|---|
| 7 |   Oliver Grimm
 | 
|---|
| 8 |   
 | 
|---|
| 9 | \********************************************************************/
 | 
|---|
| 10 | 
 | 
|---|
| 11 | #include "RawDataCTX.h"
 | 
|---|
| 12 | 
 | 
|---|
| 13 | // *** Constructor
 | 
|---|
| 14 | RawDataCTX::RawDataCTX(bool BeSilent) {
 | 
|---|
| 15 |   RHeader = new RunHeader; 
 | 
|---|
| 16 |   EHeader = new EventHeader;
 | 
|---|
| 17 |   FileOpen = false;
 | 
|---|
| 18 |   Silent = BeSilent;
 | 
|---|
| 19 | }
 | 
|---|
| 20 | 
 | 
|---|
| 21 | // *** Destructor
 | 
|---|
| 22 | RawDataCTX::~RawDataCTX() {
 | 
|---|
| 23 |   if(FileOpen) CloseDataFile();
 | 
|---|
| 24 | 
 | 
|---|
| 25 |   delete RHeader;
 | 
|---|
| 26 |   delete EHeader;
 | 
|---|
| 27 | }
 | 
|---|
| 28 | 
 | 
|---|
| 29 | // *** Open raw data file
 | 
|---|
| 30 | CTX_ErrCode RawDataCTX::OpenDataFile(char *Filename, FILE *fptr) {
 | 
|---|
| 31 | 
 | 
|---|
| 32 |   // Close file if currently open    
 | 
|---|
| 33 |   if(FileOpen) CloseDataFile();
 | 
|---|
| 34 | 
 | 
|---|
| 35 |   // Open file
 | 
|---|
| 36 |   if ((Rawfile = fopen(Filename, "r")) == NULL) {
 | 
|---|
| 37 |     if(!Silent) printf("Error: Could not open file: %s\n", Filename);
 | 
|---|
| 38 |     return CTX_FOPEN;
 | 
|---|
| 39 |   }
 | 
|---|
| 40 | 
 | 
|---|
| 41 |   // Read run header
 | 
|---|
| 42 |   if (fread(RHeader, sizeof(RunHeader), 1, Rawfile) != 1) {
 | 
|---|
| 43 |     if(!Silent) printf("Error: Could not read run header\n");
 | 
|---|
| 44 |     fclose(Rawfile);
 | 
|---|
| 45 |     return CTX_RHEADER;  
 | 
|---|
| 46 |   }
 | 
|---|
| 47 | 
 | 
|---|
| 48 |   // Check magic number of run header
 | 
|---|
| 49 |   if (RHeader->MagicNum!=MAGICNUM_OPEN && RHeader->MagicNum!=MAGICNUM_CLOSED && RHeader->MagicNum!=MAGICNUM_ERROR) {
 | 
|---|
| 50 |     if(!Silent) printf("Error: Magic number of run header incorrect\n");
 | 
|---|
| 51 |     fclose(Rawfile);
 | 
|---|
| 52 |     return CTX_RHEADER;  
 | 
|---|
| 53 |   }
 | 
|---|
| 54 | 
 | 
|---|
| 55 |   // Check if version of this software is not older than raw data format
 | 
|---|
| 56 |   if (RHeader->DataFormat > DATA_FORMAT) {
 | 
|---|
| 57 |     if(!Silent) printf("Error: Data format too new, incompatible with this read-out routine\n");
 | 
|---|
| 58 |     fclose(Rawfile);
 | 
|---|
| 59 |     return CTX_VERSION;  
 | 
|---|
| 60 |   }  
 | 
|---|
| 61 | 
 | 
|---|
| 62 |   // Check if allocated headers are long enough
 | 
|---|
| 63 |   if (RHeader->RunHeaderSize>sizeof(RunHeader) || RHeader->BoardStructureSize>sizeof(BoardStructure) || RHeader->EventHeaderSize>sizeof(EventHeader)) {
 | 
|---|
| 64 |     if(!Silent) printf("Error: Header size(s) too long (there must be a problem with the data version!)\n");
 | 
|---|
| 65 |     fclose(Rawfile);
 | 
|---|
| 66 |     return CTX_VERSION;  
 | 
|---|
| 67 |   }
 | 
|---|
| 68 |   
 | 
|---|
| 69 |   // Read board structures
 | 
|---|
| 70 |   BStruct = new BoardStructure [RHeader->NBoards];
 | 
|---|
| 71 |   for(unsigned int i=0; i<RHeader->NBoards; i++) {
 | 
|---|
| 72 |     if(fread(&BStruct[i], RHeader->BoardStructureSize, 1, Rawfile) != 1) {
 | 
|---|
| 73 |       if(!Silent) printf("Error: Could not read board structure of board number %d\n",i+1);
 | 
|---|
| 74 |       fclose(Rawfile);
 | 
|---|
| 75 |       delete[] BStruct;
 | 
|---|
| 76 |       return CTX_BSTRUCT;
 | 
|---|
| 77 |     }
 | 
|---|
| 78 |   }
 | 
|---|
| 79 | 
 | 
|---|
| 80 |   // Initialize variables
 | 
|---|
| 81 |   Data = NULL;
 | 
|---|
| 82 |   FileOpen = true;
 | 
|---|
| 83 |   
 | 
|---|
| 84 |   // If requested, print run header (including board structures) to file 
 | 
|---|
| 85 |   if(fptr != NULL) {
 | 
|---|
| 86 |     fprintf(fptr, "Magic number          %x (%s)\n", RHeader->MagicNum, RHeader->MagicNum==MAGICNUM_CLOSED?"OK":(RHeader->MagicNum==MAGICNUM_OPEN?"File not closed":"Error"));
 | 
|---|
| 87 |     fprintf(fptr, "Data format:          %u\n", RHeader->DataFormat);
 | 
|---|
| 88 |     fprintf(fptr, "Software revision:    %d\n", RHeader->SoftwareRevision);         
 | 
|---|
| 89 | 
 | 
|---|
| 90 |     fprintf(fptr, "Run header size:      %d\n", RHeader->RunHeaderSize);
 | 
|---|
| 91 |     fprintf(fptr, "Event header size:    %d\n", RHeader->EventHeaderSize);
 | 
|---|
| 92 |     fprintf(fptr, "Board structure size: %d\n", RHeader->BoardStructureSize);
 | 
|---|
| 93 | 
 | 
|---|
| 94 |     fprintf(fptr, "Description:      %s\n", RHeader->Description);
 | 
|---|
| 95 |     fprintf(fptr, "Identification:   %u\n", RHeader->Identification);
 | 
|---|
| 96 |     fprintf(fptr, "Run type:         %u\n", RHeader->Type);
 | 
|---|
| 97 |     fprintf(fptr, "Run number:       %u\n", RHeader->RunNumber);
 | 
|---|
| 98 |     fprintf(fptr, "File number:      %u\n", RHeader->FileNumber);
 | 
|---|
| 99 |     
 | 
|---|
| 100 |     fprintf(fptr, "Events:           %u\n", RHeader->Events);
 | 
|---|
| 101 |     fprintf(fptr, "Boards:           %u\n", RHeader->NBoards);
 | 
|---|
| 102 |     fprintf(fptr, "Chips/board:      %u\n", RHeader->NChips);
 | 
|---|
| 103 |     fprintf(fptr, "Channels/chip:    %u\n", RHeader->NChannels);
 | 
|---|
| 104 |     fprintf(fptr, "Samples:          %u\n", RHeader->Samples);
 | 
|---|
| 105 |     fprintf(fptr, "Offset:           %u\n", RHeader->Offset);
 | 
|---|
| 106 |     fprintf(fptr, "Bytes/sample:     %u\n", RHeader->NBytes);
 | 
|---|
| 107 | 
 | 
|---|
| 108 |     fprintf(fptr, "Start second:     %u - UTC %s", RHeader->StartSecond, asctime(gmtime((time_t *) &RHeader->StartSecond)));
 | 
|---|
| 109 |     fprintf(fptr, "  microsecond:    %u\n", RHeader->StartMicrosecond);
 | 
|---|
| 110 |     fprintf(fptr, "End second:       %u - UTC %s", RHeader->EndSecond, asctime(gmtime((time_t *) &RHeader->EndSecond)));
 | 
|---|
| 111 |     fprintf(fptr, "  microsecond:    %u\n", RHeader->EndMicrosecond);
 | 
|---|
| 112 | 
 | 
|---|
| 113 |     for (unsigned int i=0; i<RHeader->NBoards; i++) {
 | 
|---|
| 114 |       fprintf(fptr, "*** Board %d ***\n", i);
 | 
|---|
| 115 |       fprintf(fptr, "Serial number:            %d\n", BStruct[i].SerialNo);
 | 
|---|
| 116 |       fprintf(fptr, "Sampling frequency:       %.3f GHz\n", BStruct[i].NomFreq);
 | 
|---|
| 117 |       fprintf(fptr, "Temperature:              %.3f deg C\n", BStruct[i].BoardTemp);  
 | 
|---|
| 118 |       fprintf(fptr, "Scale factor:             %.3f\n", BStruct[i].ScaleFactor);
 | 
|---|
| 119 |     }     
 | 
|---|
| 120 |   }
 | 
|---|
| 121 | 
 | 
|---|
| 122 |   return CTX_OK;
 | 
|---|
| 123 | }
 | 
|---|
| 124 | 
 | 
|---|
| 125 | // *** Close raw data file
 | 
|---|
| 126 | CTX_ErrCode RawDataCTX::CloseDataFile() {
 | 
|---|
| 127 | 
 | 
|---|
| 128 |   if(!FileOpen) return CTX_NOTOPEN;
 | 
|---|
| 129 | 
 | 
|---|
| 130 |   if (fclose(Rawfile) == EOF) {
 | 
|---|
| 131 |     if(!Silent) perror("Could not close file");
 | 
|---|
| 132 |     return CTX_FCLOSE;
 | 
|---|
| 133 |   }
 | 
|---|
| 134 |   
 | 
|---|
| 135 |   delete[] BStruct;     delete[] Data;
 | 
|---|
| 136 |  
 | 
|---|
| 137 |   FileOpen = false;
 | 
|---|
| 138 |   return CTX_OK;
 | 
|---|
| 139 | }
 | 
|---|
| 140 | 
 | 
|---|
| 141 | // *** Read next event from file
 | 
|---|
| 142 | CTX_ErrCode RawDataCTX::ReadEvent(unsigned int EventNo, FILE *fptr) {
 | 
|---|
| 143 |     
 | 
|---|
| 144 |   if (!FileOpen) {
 | 
|---|
| 145 |     if(!Silent) printf("Error: No data file open.\n");
 | 
|---|
| 146 |     return CTX_NOTOPEN;
 | 
|---|
| 147 |   }
 | 
|---|
| 148 |   
 | 
|---|
| 149 |   // Move file pointer to desired event header (if zero read next event)
 | 
|---|
| 150 |   bool SEEK_OK = true;
 | 
|---|
| 151 |   unsigned int Count = 0;
 | 
|---|
| 152 |   
 | 
|---|
| 153 |   if (EventNo!=0 && fseek(Rawfile, RHeader->RunHeaderSize+RHeader->BoardStructureSize*RHeader->NBoards, SEEK_SET) != 0) SEEK_OK=false;
 | 
|---|
| 154 |   while(SEEK_OK) {
 | 
|---|
| 155 |     if (fread(EHeader, RHeader->EventHeaderSize, 1, Rawfile) != 1) {
 | 
|---|
| 156 |       if (feof(Rawfile)==0) {
 | 
|---|
| 157 |         if (!Silent) printf("Error: Could not read event header\n");
 | 
|---|
| 158 |         return CTX_EHEADER;
 | 
|---|
| 159 |       }
 | 
|---|
| 160 |       else return CTX_EOF;  
 | 
|---|
| 161 |     }
 | 
|---|
| 162 |     else {
 | 
|---|
| 163 |       if ((++Count)==EventNo || EventNo==0) break;
 | 
|---|
| 164 |       if (fseek(Rawfile, EHeader->EventSize, SEEK_CUR) != 0) SEEK_OK = false;
 | 
|---|
| 165 |     }
 | 
|---|
| 166 |   }
 | 
|---|
| 167 |   if(!SEEK_OK) {
 | 
|---|
| 168 |     if(!Silent) printf("Error: Could not move to requested event\n");
 | 
|---|
| 169 |     return CTX_SEEK;
 | 
|---|
| 170 |   }
 | 
|---|
| 171 | 
 | 
|---|
| 172 |   // Allocate memory for event data (enlarge if necessary)
 | 
|---|
| 173 |   if(Data==NULL || (sizeof(Data) < EHeader->EventSize)) {
 | 
|---|
| 174 |     delete[] Data;
 | 
|---|
| 175 |     Data = new char[EHeader->EventSize];
 | 
|---|
| 176 |   }
 | 
|---|
| 177 | 
 | 
|---|
| 178 |   // Read event data
 | 
|---|
| 179 |   if(fread(Data, 1, EHeader->EventSize, Rawfile) != EHeader->EventSize) {
 | 
|---|
| 180 |     if(!Silent) printf("Error: Could not read (all) event data\n");
 | 
|---|
| 181 |     return CTX_DATA;    
 | 
|---|
| 182 |   }
 | 
|---|
| 183 | 
 | 
|---|
| 184 |   // If requested, print event header to file 
 | 
|---|
| 185 |   if(fptr != NULL) {
 | 
|---|
| 186 |     fprintf(fptr, "Event number:    %u\n",        EHeader->EventNumber);
 | 
|---|
| 187 |     fprintf(fptr, "Time [sec]:      %u - UTC %s", EHeader->Second, asctime(gmtime((time_t *) &EHeader->Second)));
 | 
|---|
| 188 |     fprintf(fptr, "Time [usec]:     %u\n",        EHeader->Microsecond);
 | 
|---|
| 189 |     fprintf(fptr, "Trigger type:    0x%0X\n",     EHeader->TriggerType);
 | 
|---|
| 190 |     fprintf(fptr, "Size [byte]:     %u\n",        EHeader->EventSize);
 | 
|---|
| 191 |   }
 | 
|---|
| 192 |   
 | 
|---|
| 193 |   return CTX_OK;
 | 
|---|
| 194 | }
 | 
|---|
| 195 | 
 | 
|---|
| 196 | // *** Check if file currently open
 | 
|---|
| 197 | bool RawDataCTX::IsFileOpen() {
 | 
|---|
| 198 |   return FileOpen;
 | 
|---|
| 199 | }
 | 
|---|