Changeset 63


Ignore:
Timestamp:
06/16/09 17:54:09 (15 years ago)
Author:
ogrimm
Message:
Trigger cells stored in event data, data rotation no in memory but at disk transfer
Location:
drsdaq
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • drsdaq/DAQReadout.cc

    r55 r63  
    5959// -----------------------------------------------
    6060//
    61 // Note that constructor cannot report error and should not fail
    6261 
    6362DAQReadout::DAQReadout(const char *Configfile) {
     
    8887    ReadCard("MaxLogLines",        &fMaxLogLines,       'U', File);
    8988    ReadCard("RawDataPath",         fRawDataPath,       's', File);
    90     ReadCard("RotateWave",         &fRotateWave,        'I', File);
    9189    ReadCard("FirstSample",        &fFirstSample,       'I', File);
    92     ReadCard("LastSample",         &fLastSample,        'I', File);
     90    ReadCard("Samples",            &fSamples,           'U', File);
    9391    ReadCard("MinDiskSpaceMB",     &fMinDiskSpaceMB,    'U', File);
    9492    ReadCard("MaxFileSizeMB",      &fMaxFileSizeMB,     'I', File);
     
    9997    fclose(File);
    10098  }
    101   if (fFirstSample < 0 || fFirstSample >= kNumberOfBins || fLastSample < 0 || fLastSample >= kNumberOfBins) {
     99  if (fFirstSample < 0 || fFirstSample > kNumberOfBins || fSamples > kNumberOfBins) {
    102100    PrintMessage("Warning: Sample range in configuration beyond limits, setting to full range\n");
    103     fFirstSample = 0;
    104     fLastSample = kNumberOfBins;
     101    fFirstSample = kNumberOfBins;
     102    fSamples = kNumberOfBins;
    105103  }
    106104 
     
    128126
    129127  // 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");
    132129
    133130  for (int i=0; i<drs->GetNumberOfBoards(); i++) {
     
    138135    LastBoard++;
    139136    drs->GetBoard(i)->Init();
    140     drs->GetBoard(i)->SetRotation(fRotateWave);
     137    drs->GetBoard(i)->SetRotation(false);
    141138    DRSFreq[i] = 0;
    142139  }
    143140  BStruct  = new BoardStructure [NumBoards == 0 ? 1:drs->GetNumberOfBoards()];
    144141  WaveForm = new short [NumBoards == 0 ? 1:NumBoards][kNumberOfChips][kNumberOfChannels][kNumberOfBins];
     142  TriggerCell = new int [NumBoards == 0 ? 1:NumBoards][kNumberOfChips] ();  // Zero initialised
    145143 
    146144  // Create instance of HV feedback (must be called after CMC board detection)
     
    162160  delete drs;         delete HVFB;
    163161  delete[] DRSFreq;   delete[] BStruct;
    164   delete[] WaveForm;
     162  delete[] WaveForm;  delete[] TriggerCell;
    165163 
    166164  PrintMessage(MsgToLog,"********** Logging ended **********\n\n");
     
    219217void DAQReadout::cmd_config() {
    220218  PrintMessage("LogFile: %s\tMaxLogLines: %u\tRawDataPath: %s\n"
    221                "RotateWave: %d\t\tFirstSample: %d\t\tLastSample: %d\n"
     219               "FirstSample: %d\tSamples: %u\n"
    222220               "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,
    225224    fMaxFileSizeMB,fCCPort,fFirstVMESlot,fLastVMESlot,fHVFeedbackConfig);
    226225}
     
    664663  for (int i=FirstBoard; i<=LastBoard; i++) {
    665664    (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);
    669670    }
    670671  }
     
    926927
    927928  RHeader->Offset  = fFirstSample;
    928   RHeader->Samples = fLastSample - fFirstSample + 1;
     929  RHeader->Samples = fSamples;
    929930
    930931  if(write(Rawfile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
     
    953954}
    954955
    955 // Update the run header before closing file
     956// Update run header before closing file
    956957bool DAQReadout::UpdateRunHeader(unsigned int Events, bool Error) {
    957958
     
    988989  EHeader->Second = Time.tv_sec;
    989990  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;
    991993
    992994  if(write(Rawfile, EHeader, sizeof(EventHeader)) != sizeof(EventHeader)) {
     
    994996    return false;
    995997  }
     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
     1003bool 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
    9961042  return true;
    9971043}
     
    11431189
    11441190  struct timeval StartTime, StopTime;
    1145   int Count;
    11461191  unsigned int EventsInFile;
    11471192  unsigned long long RunSize = 0;
    11481193  bool WriteError = false;
    1149   struct iovec DataPart[IOV_MAX];
    1150   ssize_t WriteResult;
    11511194  off_t FileSize;
    11521195
     
    11551198  m->HVFB->ClearAverages();   
    11561199  gettimeofday(&StartTime, NULL);
    1157 
    11581200  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
    11591202  do {
    11601203    // Check if enough disk space is left
     
    11691212    EventsInFile = 0;
    11701213    FileSize = 0;
     1214
    11711215    WriteError |= !m->WriteRunHeader();
    11721216   
     
    11901234      else {
    11911235        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++)
    11931237          *((short *) m->WaveForm+i) = (short) (sin(i/Period)*1000);
    11941238      }
    11951239
    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
    12171243      if((FileSize = lseek(m->Rawfile, 0, SEEK_CUR)) == -1) {
    12181244        m->PrintMessage("Error: Could not determine file size, terminating run (%s)\n", strerror(errno));
    12191245        WriteError = true;
    12201246      }
     1247
    12211248      // Call feedback to process event
    12221249      m->HVFB->ProcessEvent();
     
    12321259  } while(m->NumEvents<m->NumEventsRequested && !m->Stop && !WriteError);
    12331260
     1261  // Print run summary to slow data file and to screen
    12341262  m->StopDRS();
    12351263  if(!WriteError) {
     
    12391267  }
    12401268  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
    12411271  if (m->NumEvents>0 && !WriteError) {
    12421272    gettimeofday(&StopTime, NULL);
     
    12451275    m->PrintMessage("Run size %llu MByte, data rate %.1f MByte/s.\n", RunSize/1024/1024, RunSize/1024.0/1024/RunTime);
    12461276  }
     1277 
    12471278  m->daq_state = stopped;
    12481279}
  • drsdaq/DAQReadout.h

    r55 r63  
    4444   
    4545    short (*WaveForm)[kNumberOfChips][kNumberOfChannels][kNumberOfBins];
     46    int (*TriggerCell)[kNumberOfChips];
     47
    4648    pthread_mutex_t control_mutex;
    4749    int Rawfile;
     
    5557    int fMinDiskSpaceMB;   // Minimum required disk space in MBytes
    5658    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;
    6061    int fCCPort;
    6162    int fLastVMESlot;
     
    128129    bool UpdateRunHeader(unsigned int, bool);
    129130    bool WriteEventHeader();
     131    bool WriteEventData();
    130132};
    131133
  • drsdaq/History.txt

    r55 r63  
    3434            safe for buffer overflow. RawDataCTX class take the possibility of
    3535            varying event data size into account.
     3612/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*.
     3916/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  
    2525endif
    2626
    27 CPPFLAGS = -DREVISION='"$(REVISION)"' -Wl,-rpath,VME/atlas/lib -O3 -Wall $(VMECTRL)
     27CPPFLAGS = -DREVISION='"$(REVISION)"' -O3 -Wall $(VMECTRL)
    2828LIBS = -lstdc++ -lz -lpthread -lutil -lfl -lreadline -ltermcap $(VMELIB)
    2929
    3030drsdaq: $(OBJECTS)
    31         $(CC) $(CPPFLAGS) -o $@ $(OBJECTS) $(LIBS)
     31        $(CC) $(CPPFLAGS) -Wl,-rpath,VME/atlas/lib -o $@ $(OBJECTS) $(LIBS)
    3232
    3333clean:
  • drsdaq/RawDataCTX.cc

    r55 r63  
    2929// *** Open raw data file
    3030CTX_ErrCode RawDataCTX::OpenDataFile(char *Filename, FILE *fptr) {
    31    
     31
     32  // Close file if currently open   
    3233  if(FileOpen) CloseDataFile();
     34
    3335  // Open file
    3436  if ((Rawfile = fopen(Filename, "r")) == NULL) {
     
    3638    return CTX_FOPEN;
    3739  }
     40
    3841  // Read run header
    3942  if (fread(RHeader, sizeof(RunHeader), 1, Rawfile) != 1) {
     
    4245    return CTX_RHEADER; 
    4346  }
     47
    4448  // Check magic number of run header
    4549  if (RHeader->MagicNum!=MAGICNUM_OPEN && RHeader->MagicNum!=MAGICNUM_CLOSED && RHeader->MagicNum!=MAGICNUM_ERROR) {
     
    4852    return CTX_RHEADER; 
    4953  }
     54
    5055  // Check if version of this software is not older than raw data format
    5156  if (RHeader->DataFormat > DATA_FORMAT) {
     
    5459    return CTX_VERSION; 
    5560  } 
     61
    5662  // Check if allocated headers are long enough
    5763  if (RHeader->RunHeaderSize>sizeof(RunHeader) || RHeader->BoardStructureSize>sizeof(BoardStructure) || RHeader->EventHeaderSize>sizeof(EventHeader)) {
     
    7177    }
    7278  }
    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;
    7582  FileOpen = true;
    7683 
     
    110117    }     
    111118  }
     119
    112120  return CTX_OK;
    113121}
     
    123131  }
    124132 
    125   delete[] BStruct;
    126   delete[] Data;
    127  
     133  delete[] BStruct;     delete[] Data;
     134 
    128135  FileOpen = false;
    129136  return CTX_OK;
     
    159166  }
    160167
     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
    161174  // Read event data
    162175  if(fread(Data, 1, EHeader->EventSize, Rawfile) != EHeader->EventSize) {
  • drsdaq/RawDataCTX.h

    r49 r63  
    9898    EventHeader *EHeader;
    9999    BoardStructure *BStruct;
    100     short *Data;
    101 
     100    char *Data;
     101   
    102102    RawDataCTX(bool = false);
    103103    ~RawDataCTX();
  • drsdaq/drsdaq.cpp

    r55 r63  
    4343  int LockDescriptor;
    4444 
     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   
    4551  // Interpret command line (do before lockfile creation in case of exit())
    4652  if((argc==3 && strcmp(argv[1],"-c")!=0) || argc==2) {
Note: See TracChangeset for help on using the changeset viewer.