- Timestamp:
- 06/16/09 17:54:09 (16 years ago)
- Location:
- drsdaq
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq/DAQReadout.cc
r55 r63 59 59 // ----------------------------------------------- 60 60 // 61 // Note that constructor cannot report error and should not fail62 61 63 62 DAQReadout::DAQReadout(const char *Configfile) { … … 88 87 ReadCard("MaxLogLines", &fMaxLogLines, 'U', File); 89 88 ReadCard("RawDataPath", fRawDataPath, 's', File); 90 ReadCard("RotateWave", &fRotateWave, 'I', File);91 89 ReadCard("FirstSample", &fFirstSample, 'I', File); 92 ReadCard(" LastSample", &fLastSample, 'I', File);90 ReadCard("Samples", &fSamples, 'U', File); 93 91 ReadCard("MinDiskSpaceMB", &fMinDiskSpaceMB, 'U', File); 94 92 ReadCard("MaxFileSizeMB", &fMaxFileSizeMB, 'I', File); … … 99 97 fclose(File); 100 98 } 101 if (fFirstSample < 0 || fFirstSample > = kNumberOfBins || fLastSample < 0 || fLastSample >=kNumberOfBins) {99 if (fFirstSample < 0 || fFirstSample > kNumberOfBins || fSamples > kNumberOfBins) { 102 100 PrintMessage("Warning: Sample range in configuration beyond limits, setting to full range\n"); 103 fFirstSample = 0;104 f LastSample= kNumberOfBins;101 fFirstSample = kNumberOfBins; 102 fSamples = kNumberOfBins; 105 103 } 106 104 … … 128 126 129 127 // Scan for DRS boards 130 if (drs->GetNumberOfBoards()==0) 131 PrintMessage("No DRS boards found - check VME crate and configuration file!\n"); 128 if (drs->GetNumberOfBoards()==0) PrintMessage("No DRS boards found - check VME crate and configuration file!\n"); 132 129 133 130 for (int i=0; i<drs->GetNumberOfBoards(); i++) { … … 138 135 LastBoard++; 139 136 drs->GetBoard(i)->Init(); 140 drs->GetBoard(i)->SetRotation(f RotateWave);137 drs->GetBoard(i)->SetRotation(false); 141 138 DRSFreq[i] = 0; 142 139 } 143 140 BStruct = new BoardStructure [NumBoards == 0 ? 1:drs->GetNumberOfBoards()]; 144 141 WaveForm = new short [NumBoards == 0 ? 1:NumBoards][kNumberOfChips][kNumberOfChannels][kNumberOfBins]; 142 TriggerCell = new int [NumBoards == 0 ? 1:NumBoards][kNumberOfChips] (); // Zero initialised 145 143 146 144 // Create instance of HV feedback (must be called after CMC board detection) … … 162 160 delete drs; delete HVFB; 163 161 delete[] DRSFreq; delete[] BStruct; 164 delete[] WaveForm; 162 delete[] WaveForm; delete[] TriggerCell; 165 163 166 164 PrintMessage(MsgToLog,"********** Logging ended **********\n\n"); … … 219 217 void DAQReadout::cmd_config() { 220 218 PrintMessage("LogFile: %s\tMaxLogLines: %u\tRawDataPath: %s\n" 221 " RotateWave: %d\t\tFirstSample: %d\t\tLastSample: %d\n"219 "FirstSample: %d\tSamples: %u\n" 222 220 "MinDiskSpaceMB: %u\tMaxFileSizeMB: %d\tCCPort: %d\n" 223 "FirstVMESlot: %d\t\tLastVMESlot: %d\t\tHVFeedbackConfig: %s\n", 224 fLogFile,fMaxLogLines,fRawDataPath,fRotateWave,fFirstSample,fLastSample,fMinDiskSpaceMB, 221 "FirstVMESlot: %d\t\tLastVMESlot: %d\n" 222 "HVFeedbackConfig: %s\n", 223 fLogFile,fMaxLogLines,fRawDataPath,fFirstSample,fSamples,fMinDiskSpaceMB, 225 224 fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fHVFeedbackConfig); 226 225 } … … 664 663 for (int i=FirstBoard; i<=LastBoard; i++) { 665 664 (drs->GetBoard(i))->TransferWaves(kNumberOfChannels*kNumberOfChips); 666 for (int ch=0; ch<kNumberOfChannels; ch++) { 667 (drs->GetBoard(i))->GetWave(0, ch, WaveForm[i][0][ch], true); // Chip #1 668 (drs->GetBoard(i))->GetWave(1, ch, WaveForm[i][1][ch], true); // Chip #2 665 for (int j=0; j<kNumberOfChannels; j++) { 666 drs->GetBoard(i)->GetWave(0, j, WaveForm[i][0][j], true); // Chip #1 667 TriggerCell[i][0] = drs->GetBoard(i)->GetTriggerCell((unsigned int) 0); 668 drs->GetBoard(i)->GetWave(1, j, WaveForm[i][1][j], true); // Chip #2 669 TriggerCell[i][1] = drs->GetBoard(i)->GetTriggerCell((unsigned int) 1); 669 670 } 670 671 } … … 926 927 927 928 RHeader->Offset = fFirstSample; 928 RHeader->Samples = f LastSample - fFirstSample + 1;929 RHeader->Samples = fSamples; 929 930 930 931 if(write(Rawfile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) { … … 953 954 } 954 955 955 // Update therun header before closing file956 // Update run header before closing file 956 957 bool DAQReadout::UpdateRunHeader(unsigned int Events, bool Error) { 957 958 … … 988 989 EHeader->Second = Time.tv_sec; 989 990 EHeader->Microsecond = Time.tv_usec; 990 EHeader->EventSize = sizeof(short)*RHeader->NBoards*RHeader->NChips*RHeader->NChannels*RHeader->Samples; 991 EHeader->EventSize = sizeof(short)*RHeader->NBoards*RHeader->NChips*RHeader->NChannels*RHeader->Samples + 992 sizeof(int)*RHeader->NBoards*RHeader->NChips; 991 993 992 994 if(write(Rawfile, EHeader, sizeof(EventHeader)) != sizeof(EventHeader)) { … … 994 996 return false; 995 997 } 998 return true; 999 } 1000 1001 // Write event data (It is required that at least three chunks can be written with writev(), therefore 1002 // IOV_MAX>=3 is checked at startup 1003 bool DAQReadout::WriteEventData() { 1004 1005 unsigned int Start, Count = 0; 1006 ssize_t WriteResult, Size = 0; 1007 struct iovec DataPart[IOV_MAX]; 1008 1009 // First chunk: trigger cells 1010 DataPart[Count].iov_base = TriggerCell + FirstBoard*kNumberOfChips; 1011 DataPart[Count++].iov_len = RHeader->NBoards * kNumberOfChips * sizeof(int); 1012 Size += DataPart[Count-1].iov_len; 1013 1014 // Remaining chunks: ADC data (two chucks per channel if wrap around of pipeline occurred) 1015 for (int i=FirstBoard; (i<=LastBoard + (NumBoards==0)); i++) { 1016 for (unsigned int k=0; k<RHeader->NChips; k++) { 1017 Start = (TriggerCell[i][k]-fFirstSample+kNumberOfBins) % kNumberOfBins; // Start bin for this chip 1018 for (unsigned int l=0; l<RHeader->NChannels; l++) { 1019 DataPart[Count].iov_base = &WaveForm[i][k][l][Start]; 1020 DataPart[Count++].iov_len = (Start+fSamples<kNumberOfBins ? fSamples:(kNumberOfBins-Start)) * sizeof(short); 1021 Size += DataPart[Count-1].iov_len; 1022 // In case second part of waveform still missing, write now 1023 if(DataPart[Count-1].iov_len < fSamples * sizeof(short)) { 1024 DataPart[Count].iov_base = &WaveForm[i][k][l][0]; 1025 DataPart[Count++].iov_len = (fSamples-(kNumberOfBins-Start)) * sizeof(short); 1026 Size += DataPart[Count-1].iov_len; 1027 } 1028 1029 // Write to disk if either maximum size of DataPart[] array or last loop interation is reached 1030 // Possibly 2 chunks are entered in array in the previous lines of code, therefore IOV_MAX-1 1031 if (Count>=IOV_MAX-1 || (l==(RHeader->NChannels-1) && k==(RHeader->NChips-1) && i==(LastBoard+(NumBoards==0)))) { 1032 if ((WriteResult=writev(Rawfile, DataPart, Count)) != (int) Size) { 1033 if (WriteResult==-1) PrintMessage("Error: Could not write event data, terminating run (%s)\n", strerror(errno)); 1034 else PrintMessage("Error: Could only write %u out of %u bytes of event data, terminating run\n", WriteResult,Count*DataPart[0].iov_len); 1035 return false; 1036 } 1037 Count = 0; Size = 0; 1038 } 1039 } // Channels 1040 } // Chips 1041 } // Boards 996 1042 return true; 997 1043 } … … 1143 1189 1144 1190 struct timeval StartTime, StopTime; 1145 int Count;1146 1191 unsigned int EventsInFile; 1147 1192 unsigned long long RunSize = 0; 1148 1193 bool WriteError = false; 1149 struct iovec DataPart[IOV_MAX];1150 ssize_t WriteResult;1151 1194 off_t FileSize; 1152 1195 … … 1155 1198 m->HVFB->ClearAverages(); 1156 1199 gettimeofday(&StartTime, NULL); 1157 1158 1200 m->PrintMessage("\rStarting run #%d (%s) on \"%s\" with %u event(s)\n",m->RunNumber,daq_runtype_str[m->daq_runtype],m->RHeader->Description,m->NumEventsRequested); 1201 1159 1202 do { 1160 1203 // Check if enough disk space is left … … 1169 1212 EventsInFile = 0; 1170 1213 FileSize = 0; 1214 1171 1215 WriteError |= !m->WriteRunHeader(); 1172 1216 … … 1190 1234 else { 1191 1235 double Period = ((double) rand())/RAND_MAX*20; 1192 for (long int i=0; i<(m->NumBoards>0 ? m->NumBoards : 1)*kNumberOfChips*kNumberOfChannels*kNumberOfBins; i++)1236 for (long unsigned int i=0; i<m->RHeader->NBoards*kNumberOfChips*kNumberOfChannels*kNumberOfBins; i++) 1193 1237 *((short *) m->WaveForm+i) = (short) (sin(i/Period)*1000); 1194 1238 } 1195 1239 1196 // Write data to disk (using writev() for performance reason) 1197 Count = 0; 1198 for (int i=m->FirstBoard; (i<=m->LastBoard + (m->NumBoards==0)) && !WriteError; i++) { 1199 for (unsigned int k=0; k<m->RHeader->NChips*m->RHeader->NChannels; k++) { 1200 DataPart[Count].iov_base = &m->WaveForm[i][k/m->RHeader->NChannels][k%m->RHeader->NChannels][m->RHeader->Offset]; 1201 DataPart[Count++].iov_len = m->RHeader->Samples * sizeof(short); 1202 1203 // Write to disk if either maximum size of DataPart[] array or last loop interation is reached 1204 if (Count==IOV_MAX || (k==(m->RHeader->NChips*m->RHeader->NChannels-1) && i==(m->LastBoard+(m->NumBoards==0)))) { 1205 if ((WriteResult=writev(m->Rawfile, DataPart, Count)) != (int) (Count*DataPart[0].iov_len)) { 1206 if (WriteResult==-1) m->PrintMessage("Error: Could not write event data, terminating run (%s)\n", strerror(errno)); 1207 else m->PrintMessage("Error: Could only write %u out of %u bytes of event data, terminating run\n", WriteResult,Count*DataPart[0].iov_len); 1208 WriteError = true; 1209 break; 1210 } 1211 Count = 0; 1212 } 1213 } 1214 } 1215 1216 // Update file size 1240 // Write data to disk and update file size 1241 WriteError |= !m->WriteEventData(); 1242 1217 1243 if((FileSize = lseek(m->Rawfile, 0, SEEK_CUR)) == -1) { 1218 1244 m->PrintMessage("Error: Could not determine file size, terminating run (%s)\n", strerror(errno)); 1219 1245 WriteError = true; 1220 1246 } 1247 1221 1248 // Call feedback to process event 1222 1249 m->HVFB->ProcessEvent(); … … 1232 1259 } while(m->NumEvents<m->NumEventsRequested && !m->Stop && !WriteError); 1233 1260 1261 // Print run summary to slow data file and to screen 1234 1262 m->StopDRS(); 1235 1263 if(!WriteError) { … … 1239 1267 } 1240 1268 else m->PrintMessage("\rRun #%d (%s) aborted due to error after %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],m->NumEvents); 1269 1270 // Print run statistics 1241 1271 if (m->NumEvents>0 && !WriteError) { 1242 1272 gettimeofday(&StopTime, NULL); … … 1245 1275 m->PrintMessage("Run size %llu MByte, data rate %.1f MByte/s.\n", RunSize/1024/1024, RunSize/1024.0/1024/RunTime); 1246 1276 } 1277 1247 1278 m->daq_state = stopped; 1248 1279 } -
drsdaq/DAQReadout.h
r55 r63 44 44 45 45 short (*WaveForm)[kNumberOfChips][kNumberOfChannels][kNumberOfBins]; 46 int (*TriggerCell)[kNumberOfChips]; 47 46 48 pthread_mutex_t control_mutex; 47 49 int Rawfile; … … 55 57 int fMinDiskSpaceMB; // Minimum required disk space in MBytes 56 58 int fMaxFileSizeMB; // Maximum File size in Bytes 57 unsigned int fFirstSample; 58 unsigned int fLastSample; 59 short fRotateWave; 59 int fFirstSample; 60 unsigned int fSamples; 60 61 int fCCPort; 61 62 int fLastVMESlot; … … 128 129 bool UpdateRunHeader(unsigned int, bool); 129 130 bool WriteEventHeader(); 131 bool WriteEventData(); 130 132 }; 131 133 -
drsdaq/History.txt
r55 r63 34 34 safe for buffer overflow. RawDataCTX class take the possibility of 35 35 varying event data size into account. 36 12/6/2009 Trigger cells (determined using DRS class GetTriggerCell()) are 37 stored as array of integers in event data. RawDataCTX class pointer 38 'Data' changed from short* to char*. 39 16/6/2009 Data is not rotated by copying in memory, but by saving to disk in 40 correct order using writev() (10% gain in rate) 41 -
drsdaq/Makefile
r57 r63 25 25 endif 26 26 27 CPPFLAGS = -DREVISION='"$(REVISION)"' - Wl,-rpath,VME/atlas/lib -O3 -Wall $(VMECTRL)27 CPPFLAGS = -DREVISION='"$(REVISION)"' -O3 -Wall $(VMECTRL) 28 28 LIBS = -lstdc++ -lz -lpthread -lutil -lfl -lreadline -ltermcap $(VMELIB) 29 29 30 30 drsdaq: $(OBJECTS) 31 $(CC) $(CPPFLAGS) - o $@ $(OBJECTS) $(LIBS)31 $(CC) $(CPPFLAGS) -Wl,-rpath,VME/atlas/lib -o $@ $(OBJECTS) $(LIBS) 32 32 33 33 clean: -
drsdaq/RawDataCTX.cc
r55 r63 29 29 // *** Open raw data file 30 30 CTX_ErrCode RawDataCTX::OpenDataFile(char *Filename, FILE *fptr) { 31 31 32 // Close file if currently open 32 33 if(FileOpen) CloseDataFile(); 34 33 35 // Open file 34 36 if ((Rawfile = fopen(Filename, "r")) == NULL) { … … 36 38 return CTX_FOPEN; 37 39 } 40 38 41 // Read run header 39 42 if (fread(RHeader, sizeof(RunHeader), 1, Rawfile) != 1) { … … 42 45 return CTX_RHEADER; 43 46 } 47 44 48 // Check magic number of run header 45 49 if (RHeader->MagicNum!=MAGICNUM_OPEN && RHeader->MagicNum!=MAGICNUM_CLOSED && RHeader->MagicNum!=MAGICNUM_ERROR) { … … 48 52 return CTX_RHEADER; 49 53 } 54 50 55 // Check if version of this software is not older than raw data format 51 56 if (RHeader->DataFormat > DATA_FORMAT) { … … 54 59 return CTX_VERSION; 55 60 } 61 56 62 // Check if allocated headers are long enough 57 63 if (RHeader->RunHeaderSize>sizeof(RunHeader) || RHeader->BoardStructureSize>sizeof(BoardStructure) || RHeader->EventHeaderSize>sizeof(EventHeader)) { … … 71 77 } 72 78 } 73 // Allocate memory for event data 74 Data = new short[RHeader->NBoards*RHeader->NChips*RHeader->NChannels*RHeader->Samples]; 79 80 // Initialize variables 81 Data = NULL; 75 82 FileOpen = true; 76 83 … … 110 117 } 111 118 } 119 112 120 return CTX_OK; 113 121 } … … 123 131 } 124 132 125 delete[] BStruct; 126 delete[] Data; 127 133 delete[] BStruct; delete[] Data; 134 128 135 FileOpen = false; 129 136 return CTX_OK; … … 159 166 } 160 167 168 // Allocate memory for event data (enlarge if necessary) 169 if(Data==NULL || (sizeof(Data) < EHeader->EventSize)) { 170 delete[] Data; 171 Data = new char[EHeader->EventSize]; 172 } 173 161 174 // Read event data 162 175 if(fread(Data, 1, EHeader->EventSize, Rawfile) != EHeader->EventSize) { -
drsdaq/RawDataCTX.h
r49 r63 98 98 EventHeader *EHeader; 99 99 BoardStructure *BStruct; 100 short*Data;101 100 char *Data; 101 102 102 RawDataCTX(bool = false); 103 103 ~RawDataCTX(); -
drsdaq/drsdaq.cpp
r55 r63 43 43 int LockDescriptor; 44 44 45 // writev() in DAQ thread needs to be able to write at least 3 chunks 46 if(IOV_MAX < 3) { 47 printf("Fatal error: IOV_MAX is less than 3, cannot use writev() to write event data.\n"); 48 exit(EXIT_FAILURE); 49 } 50 45 51 // Interpret command line (do before lockfile creation in case of exit()) 46 52 if((argc==3 && strcmp(argv[1],"-c")!=0) || argc==2) {
Note:
See TracChangeset
for help on using the changeset viewer.