Changeset 10913 for fact/FADctrl


Ignore:
Timestamp:
06/06/11 14:35:10 (13 years ago)
Author:
ogrimm
Message:
FADctrl will write and publish data only for active boards
Location:
fact/FADctrl
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • fact/FADctrl/FAD.cc

    r10813 r10913  
    3030   {"reset", &FAD::cmd_reset, true, 0, "", "Reset internal trigger counter"},
    3131   {"runnumber", &FAD::cmd_runnumber, true, 1, "<n>", "Set runnumber"},
    32    {"roi", &FAD::cmd_roi, true, 2, "<channel range> <value>", "Set region-of-interest to value"},
     32   {"roi", &FAD::cmd_roi, true, 2, "<range> <value>", "Set ROI to for channel range to value"},
    3333   {"dac", &FAD::cmd_dac, true, 2, "<range> <value>", "Set DAC numbers in range to value"},
    3434   {"address", &FAD::cmd_address, true, 2, "<range> <value>", "Set addresses in range to value"},
    3535   {"send", &FAD::cmd_send, true, 1, "<value>", "Send arbitrary data to board"},
    36    {"take", &FAD::cmd_take, true, 1, "<n> <dir>", "Start run with n events, write to directory"},
    37    {"acalib", &FAD::cmd_acalib, true, 0, "[n|invalidate|file]", "Perform or read amplitude calibration (n events)"},
     36   {"take", &FAD::cmd_take, true, 1, "<n> <dir>", "Start run with n events (n=0 -> unlimited)"},
     37   {"acalib", &FAD::cmd_acalib, true, 0, "[n|inval|file]", "Perform or read amplitude calibration (n events)"},
    3838   //{"wmode", &FAD::cmd_wmode, 0, "<run|stop>", "Domino wave running or stopped during read out"},
    3939   //{"rmode", &FAD::cmd_rmode, 0, "<first|stop>", "Readout start at first bin or stop position (DRS4)"},
     
    827827void FAD::EventThread() {
    828828
    829   struct timeval Time, RunStart;
     829  struct timeval Time;
    830830  struct timeval LastUpdate;
    831831  struct FADBoard::BoardStatus S;
    832832  vector<unsigned long> EventNumbers(Boards.size());
    833833  vector<bool> AcalibDone(Boards.size());
     834  map<unsigned int, class FADBoard *> ActiveBoards;
    834835  double Temp;
    835836  string IDString;
    836837  char Buffer[100];
    837838  int Ret;
    838   unsigned long long FileSize = 0;
     839  struct stat FileStat;
     840  float FileSizeMB = 0;
     841  RunHeader FileRHeader;
    839842
    840843  gettimeofday(&LastUpdate, NULL);
    841   RunStart = LastUpdate; // only to avoid 'uninitialized' warning from compiler
    842844 
    843845  // Create DIM event data and number services
    844   int EventSize = sizeof(RunHeader)+ Boards.size()*sizeof(BoardStructure)+sizeof(EventHeader) + Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
    845   char *EventData = new char [EventSize];
    846 
    847   memset(EventData, 0, EventSize);
     846  char *EventData = new char [sizeof(RunHeader)+ Boards.size()*sizeof(BoardStructure)+sizeof(EventHeader) + Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int))];
    848847
    849848  DimService EventService(SERVER_NAME"/EventData", (char *) "C", NULL, 0);
    850849  DimService EventNumService(SERVER_NAME"/EventNumber", NumEvents);
    851 
    852   // Calculate pointers to EventData array
     850  DimService FileSizeService(SERVER_NAME"/FileSizeMB", FileSizeMB);
     851
     852  // Calculate pointers to EventData array (will be updated when active number of boards changes)
    853853  RunHeader *RHeader = (RunHeader *) EventData;
    854854  BoardStructure **BStruct = new BoardStructure * [Boards.size()];
     855
    855856  for (unsigned int i=0; i<Boards.size(); i++) BStruct[i] = ((BoardStructure *) (RHeader + 1)) + i;
    856857  EventHeader *EHeader = (EventHeader *) ((char *) (RHeader + 1) + Boards.size()*sizeof(BoardStructure));
     
    858859  short *Data = (short *) (TriggerCell + NChips*Boards.size());
    859860
    860   // M0 RunHeader
     861  // Fill fixed entries in M0 RunHeader
     862  RHeader->MagicNum = MAGICNUM_CLOSED;
    861863  RHeader->DataFormat = DATA_FORMAT;
    862864  RHeader->RunHeaderSize = sizeof(RunHeader);
     
    865867  RHeader->SoftwareRevision = atoi(REVISION) * (strchr(REVISION, 'M')==NULL ? 1:-1);
    866868  RHeader->Identification = 0;
    867 
    868869  RHeader->Type = 0;                            // Run type: 0=data, 1=pedestal, 3=test
    869 
    870870  RHeader->RunNumber = -1;
    871871  RHeader->FileNumber = 0;
    872872  snprintf(RHeader->Description, sizeof(RHeader->Description), "FADctrl");       
    873 
    874   RHeader->NBoards = Boards.size();
     873  RHeader->Events = 1;
     874  RHeader->StartSecond = LastUpdate.tv_sec;                     
     875  RHeader->StartMicrosecond = LastUpdate.tv_usec;               
    875876  RHeader->NChips = NChips;
    876877  RHeader->NChannels = NChannels;
     
    879880  RHeader->NBytes = sizeof(short);
    880881
    881   // M0 EventHeader
    882   EHeader->EventSize = Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
    883 
    884882  // Update loop
    885883  while (!ExitRequest) {
     
    896894        IDString.append(string(Buffer, Ret));
    897895
    898         // If amplitude calibration mode, check if board finished procedure
     896        // Active boards for DIM and data taking must only change when idle
     897        if (Mode == idle) {
     898          ActiveBoards.clear();
     899          for (unsigned int i=0; i<Boards.size(); i++) if (Boards[i]->Active) ActiveBoards[i] = Boards[i];
     900          RHeader->NBoards = ActiveBoards.size();
     901         
     902          // Calculate updated pointers to EventData array
     903          for (unsigned int i=0; i<ActiveBoards.size(); i++) BStruct[i] = ((BoardStructure *) (RHeader + 1)) + i;
     904          EHeader = (EventHeader *) ((char *) (RHeader + 1) + ActiveBoards.size()*sizeof(BoardStructure));
     905          TriggerCell = (int *) (EHeader + 1);
     906          Data = (short *) (TriggerCell + NChips*ActiveBoards.size());
     907        }
     908
     909        // If amplitude calibration mode, check if all boards finished procedure
    899910        if (Mode == acalib) {
    900911          bool Done = true;
     
    912923        else for (unsigned int i=0; i<Boards.size(); i++) AcalibDone[i] = false;
    913924
    914         // Update run and event header with current time
     925        // Update run and event header
    915926        gettimeofday(&Time, NULL);
    916 
    917         RHeader->MagicNum = MAGICNUM_CLOSED;
    918927        RHeader->EndSecond = Time.tv_sec;                       
    919928        RHeader->EndMicrosecond = Time.tv_usec;         
    920929
     930    EHeader->EventSize = RHeader->NBoards * (NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
    921931        EHeader->Second = Time.tv_sec;
    922932        EHeader->Microsecond = Time.tv_usec;
    923933
    924         // Close data file if requested or requested number of events reached
    925         if((IDString.find("stop")!=string::npos || NumEvents==NumEventsRequested) && Mode==datarun) {
    926 
    927           // Update run header 
    928           RHeader->Events = NumEvents;
    929           RHeader->StartSecond = RunStart.tv_sec;
    930           RHeader->StartMicrosecond = RunStart.tv_usec;         
    931 
    932           if (lseek(Datafile, 0, SEEK_SET) == -1) {
    933             Message(ERROR, "Could not rewind file to write updated run header (%s)", strerror(errno));
    934           }
    935           else if (write(Datafile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
    936                 Message(ERROR, "Could not write updated run header (%s)", strerror(errno));
    937           }
    938 
    939           // Close data file and terminate run
    940           if(close(Datafile) == -1) Message(ERROR, "Could not close data file (%s)", strerror(errno));
    941           else PrintMessage("Data file closed (size %.1f MByte).\n", FileSize/1024.0/1024);
    942 
    943           Datafile = -1;
    944           Mode = idle;
    945           Message(INFO, "Data run ended, mode set to IDLE");     
    946         }
    947 
    948         // These values might have changed while close file
    949         RHeader->StartSecond = Time.tv_sec;
    950         RHeader->StartMicrosecond = Time.tv_usec;               
    951     RHeader->Events = 1;
    952 
    953934        // Check all boards that have new data
    954         for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
    955           // Identify board
     935        for (unsigned int Brd=0; Brd<ActiveBoards.size(); Brd++) {
    956936          if (IDString.find(string("EVENT")+Boards[Brd]->Name) == string::npos) continue;
    957937
    958938          // Fill M0 BoardStructure             
    959           S = Boards[Brd]->GetStatus();
     939          S = ActiveBoards[Brd]->GetStatus();
    960940          BStruct[Brd]->SerialNo = (U32) S.DNA;
    961941          BStruct[Brd]->NomFreq = S.Frequency;
     
    978958          memset(Data+Count, 0, NChips*NChannels*NBins*sizeof(short));
    979959
    980           Boards[Brd]->Lock();
     960          ActiveBoards[Brd]->Lock();
    981961          for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) {
    982962                for (int i=0; i<S.ROI[Chip][Chan]; i++) {
    983                   if (Boards[Brd]->ACalib.Time == -1) Data[Count++] = Boards[Brd]->Data[Chip][Chan][i];
     963                  if (ActiveBoards[Brd]->ACalib.Time == -1) Data[Count++] = ActiveBoards[Brd]->Data[Chip][Chan][i];
    984964                  else {
    985                     Temp = (Boards[Brd]->Data[Chip][Chan][i] - Boards[Brd]->ACalib.Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]);
    986                         Temp *= Boards[Brd]->ACalib.Gain[Chip][Chan][0]/Boards[Brd]->ACalib.Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
    987                         //Temp -= Boards[Brd]->ACalib.Secondary[Chip][Chan][i];
     965                    Temp = (ActiveBoards[Brd]->Data[Chip][Chan][i] - ActiveBoards[Brd]->ACalib.Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]);
     966                        Temp *= ActiveBoards[Brd]->ACalib.Gain[Chip][Chan][0]/ActiveBoards[Brd]->ACalib.Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
     967                        //Temp -= ActiveBoards[Brd]->ACalib.Secondary[Chip][Chan][i];
    988968                        Data[Count++] = (short) Temp;
    989969                  }
     
    991971                Count += NBins - S.ROI[Chip][Chan];
    992972          }
    993 
    994           // Inform TCP/IP thread that data has been processed   
     973          ActiveBoards[Brd]->Unlock();
     974        }
     975
     976        // Inform TCP/IP thread of all boards that send data that processing is finished
     977        for (unsigned int Brd=0; Brd<Boards.size(); Brd++) if (IDString.find(string("EVENT")+Boards[Brd]->Name) != string::npos) {
     978          Boards[Brd]->Lock();
    995979          Boards[Brd]->Continue = true;
    996980          Boards[Brd]->Unlock();
     
    999983                Message(FATAL, "pthread_cond_signal() failed (%s)", strerror(Ret));
    1000984          }
    1001         } // Loop over boards
     985        }
    1002986
    1003987        // Check if DIM service should be updated
    1004988        if ((Time.tv_sec-LastUpdate.tv_sec)*1e6 + Time.tv_usec-LastUpdate.tv_usec > EventUpdateDelay*1e6) {
    1005989          gettimeofday(&LastUpdate, NULL);
    1006           EventService.updateService(EventData, EventSize);
     990          EventService.updateService(EventData, sizeof(RunHeader) + sizeof(EventHeader) + ActiveBoards.size()*(sizeof(BoardStructure) + NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int)));
    1007991          EventNumService.updateService();
     992          if (Mode == datarun) FileSizeService.updateService();
    1008993        }
    1009994       
    1010         // ===== Data writing ===
    1011        
     995        // ===== Data writing ===       
    1012996        if (Mode != datarun) continue;
    1013997       
     
    10241008        if (CommonEventNum == numeric_limits<unsigned long>::max()) continue;
    10251009
    1026         // Write also run header if this is the first event
    1027         int Offset;     
     1010        int Error = 0;
     1011
     1012        // Initialize run
    10281013        if (NumEvents == 0) {
    1029           RHeader->MagicNum = MAGICNUM_OPEN;
    1030           RunStart = Time;
    1031           Offset = 0;
    1032           FileSize = 0;
    1033         }
    1034         else Offset = sizeof(RunHeader) + Boards.size()*sizeof(BoardStructure);
     1014          FileSizeMB = 0;
     1015
     1016          FileRHeader = *RHeader;
     1017          FileRHeader.MagicNum = MAGICNUM_OPEN;
     1018          FileRHeader.StartSecond = Time.tv_sec;
     1019          FileRHeader.StartMicrosecond = Time.tv_usec;         
     1020
     1021          // Write run header and board structures
     1022          if (write(Datafile, &FileRHeader, sizeof(RunHeader)) == -1) Error = errno;
     1023          else if (write(Datafile, BStruct[0], FileRHeader.NBoards*sizeof(BoardStructure)) == -1) Error = errno;
     1024        }
     1025
     1026        // Write event header, trigger cells and ADC data to file
     1027        if (write(Datafile, EHeader, sizeof(EventHeader)+NChips*sizeof(int)+ActiveBoards.size()*NChips*NChannels*NBins*sizeof(short)) == -1) Error = errno;
     1028
     1029        NumEvents++;
     1030
     1031        // Write event header to file
     1032        //if(write(Datafile, EHeader, sizeof(EventHeader)) != sizeof(EventHeader)) Error = true;
     1033
     1034        // Write trigger cells
     1035        //for (unsigned int i=0; i<ActiveBoards.size(); i++) {
     1036          //if(write(Datafile, TriggerCell + i*NChips, NChips*sizeof(int)) != NChips*sizeof(int)) Error = true;
     1037        //}
     1038
     1039        // Write ADC data
     1040        //unsigned int Bins = NChips*NChannels*NBins;
     1041        //for (unsigned int i=0; i<ActiveBoards.size(); i++) {
     1042          //if(write(Datafile, Data+i*Bins, Bins*sizeof(short)) != (ssize_t) (Bins*sizeof(short))) Error = true;
     1043        //}
    10351044       
    1036         // Write data to file
    1037         if(write(Datafile, EventData+Offset, EventSize-Offset) != (ssize_t) EventSize-Offset) {
    1038           Message(ERROR, "Could not write all data to file, terminating run, setting mode to IDLE (%s)", strerror(errno));
    1039 
    1040           // Close file if error
     1045        // Update file size
     1046        if (fstat(Datafile, &FileStat) == -1) Error = errno;
     1047    else FileSizeMB = FileStat.st_size/1024.0/1024.0;
     1048
     1049        // Check for write errors and for correct file size
     1050        if (Error !=0) {
     1051          Message(ERROR, "Error writing to data data file (%s), terminating run, setting mode to IDLE", strerror(Error));
     1052        }
     1053        else if ((size_t) FileStat.st_size != sizeof(RunHeader)+ FileRHeader.NBoards*sizeof(BoardStructure)+NumEvents*(sizeof(EventHeader) + FileRHeader.NBoards*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int)))) {
     1054          Message(ERROR, "Could not write all data to file, terminating run, setting mode to IDLE");
     1055          Error = 1;
     1056        }
     1057
     1058        // Close file if error
     1059        if (Error != 0) {
    10411060          if (close(Datafile) == -1) Message(ERROR, "Could not close data file (%s)", strerror(errno));
    10421061          Datafile = -1;
     
    10451064        }
    10461065       
    1047         NumEvents++;
    1048         FileSize += EventSize-Offset;
     1066        // Close data file if requested or requested number of events reached
     1067        if(IDString.find("stop")!=string::npos || (NumEvents==NumEventsRequested && NumEventsRequested!=0)) {
     1068
     1069          // Update run header for writing     
     1070          FileRHeader.MagicNum = MAGICNUM_CLOSED;
     1071          FileRHeader.Events = NumEvents;
     1072          FileRHeader.EndSecond = Time.tv_sec;                 
     1073          FileRHeader.EndMicrosecond = Time.tv_usec;           
     1074
     1075          if (lseek(Datafile, 0, SEEK_SET) == -1) {
     1076            Message(ERROR, "Could not rewind file to write updated run header (%s)", strerror(errno));
     1077          }
     1078          else if (write(Datafile, &FileRHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
     1079                Message(ERROR, "Could not write updated run header (%s)", strerror(errno));
     1080          }
     1081
     1082          // Close data file and terminate run
     1083          if(close(Datafile) == -1) Message(ERROR, "Could not close data file (%s)", strerror(errno));
     1084          else PrintMessage("Data file closed (size %.1f MByte).\n", FileSizeMB);
     1085
     1086          Datafile = -1;
     1087          Mode = idle;
     1088          Message(INFO, "Data run ended, mode set to IDLE");     
     1089        }
    10491090  }
    10501091
    10511092  delete[] BStruct;
    10521093  delete[] EventData;
    1053 
    10541094}
    10551095
  • fact/FADctrl/History.txt

    r10813 r10913  
    3030                        cancelled
    313125/5/2011       dcm_lock and dcm_ready bits were incorrectly evaluated.
     323/6/2011        Raw data files will only contain boards active at the start of the run.
Note: See TracChangeset for help on using the changeset viewer.