Changeset 10114 for fact/FADctrl


Ignore:
Timestamp:
01/24/11 08:47:21 (14 years ago)
Author:
ogrimm
Message:
Event data can be written to disk in M0 format with command take
Location:
fact/FADctrl
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • fact/FADctrl/FAD.cc

    r10113 r10114  
    3232   {"address", &FAD::cmd_address, true, 2, "<range> <value>", "Set addresses in range to value"},
    3333   {"send", &FAD::cmd_send, true, 1, "<value>", "Send arbitrary data to board"},
     34   {"take", &FAD::cmd_take, true, 1, "<n> <dir>", "Start run with n events, write to directory"},
    3435   {"acalib", &FAD::cmd_acalib, true, 0, "[n|invalidate|file]", "Perform or read amplitude calibration (n events)"},
    3536   //{"wmode", &FAD::cmd_wmode, 0, "<run|stop>", "Domino wave running or stopped during read out"},
    3637   //{"rmode", &FAD::cmd_rmode, 0, "<first|stop>", "Readout start at first bin or stop position (DRS4)"},
    3738   //{"dmode", &FAD::cmd_dmode, 0, "<single|continuous>", "Domino wave single shot or continuous"},
    38    {"cancel", &FAD::cmd_cancel, false, 0, "", "Cancel current operation"},
     39   {"cancel", &FAD::cmd_cancel, false, 0, "", "Cancel current operation/run"},
    3940   {"update", &FAD::cmd_update, false, 1, "<sec>", "Minimum delay between updates to DIM event service"},                 
    4041   {"socketmode", &FAD::cmd_socketmode, true, 1, "<com|daq>", "Choose which Sockets are used for data transmission"},             
     
    5758  MainThread = pthread_self();
    5859  Mode = idle;
     60  Datafile = -1;
    5961  EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str());
    6062
     
    450452
    451453//
     454// Start data run
     455//
     456void FAD::cmd_take() {
     457
     458  time_t Time = time(NULL);
     459  struct tm *T = localtime(&Time);
     460  char Filename[500];
     461
     462  // Set number of requested events
     463  NumEventsRequested = atoi(Parameter[1].c_str());
     464  NumEvents = 0;
     465
     466  //  Open file with rwx right for owner and group, never overwrite file
     467  snprintf(Filename, sizeof(Filename),"%s/%d%02d%02dT%02d%02d%02d.raw", Parameter[2].c_str(), T->tm_year+1900, T->tm_mon+1, T->tm_mday, T->tm_hour, T->tm_min, T->tm_sec);
     468
     469  Datafile = open(Filename,O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
     470  if(Datafile == -1) {
     471    PrintMessage("Error: Could not open file \"%s\" (%s)\n", Filename, strerror(errno));
     472    return;
     473  }
     474
     475  // Start run
     476  Mode = datarun;
     477  PrintMessage("Starting run with %d events, filename '%s'\n", NumEventsRequested, Filename);
     478}
     479
     480//
    452481// Amplitude calibration
    453482//
     
    684713void FAD::cmd_cancel() {
    685714
     715  static char Stop[] = "stop";
     716
    686717  if (Mode == idle) PrintMessage("Nothing to cancel\n");
    687718  else {
     719        // Inform event thread to stop run in case datarun active
     720        if (write(Pipe[1], Stop, strlen(Stop)+1) == -1) {
     721          Message(ERROR, "write() to Pipe[1] failed in FAD::cmd_cancel() (%s)", strerror(errno));
     722        }
     723    Cancel = true;
    688724    PrintMessage("Requested cancelation of current operation\n");
    689     Cancel = true;
    690725  }
    691726}
     
    915950
    916951//
    917 // DIM event service update thread (publishes M0 format)
     952// Event thread (publishes/writes M0 format)
    918953//
    919954void FAD::EventThread() {
    920955
    921   struct timeval Time;
     956  struct timeval Time, RunStart;
    922957  struct timeval LastUpdate;
    923958  struct FADBoard::BoardStatus S;
     959  vector<unsigned long> EventNumbers(Boards.size());
    924960  double Temp;
    925961  string IDString;
    926962  char Buffer[100];
    927963  int Ret;
     964  unsigned long long FileSize = 0;
    928965
    929966  gettimeofday(&LastUpdate, NULL);
    930 
     967  RunStart = LastUpdate; // only to avoid 'uninitialized' warning from compiler
     968 
    931969  // Create DIM event data service
    932970  int EventSize = sizeof(RunHeader)+ Boards.size()*sizeof(BoardStructure)+sizeof(EventHeader) + Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int));
     
    945983
    946984  // M0 RunHeader
    947   RHeader->MagicNum = 0xE0E0;
    948   RHeader->DataFormat = 1;
     985  RHeader->DataFormat = DATA_FORMAT;
    949986  RHeader->RunHeaderSize = sizeof(RunHeader);
    950987  RHeader->EventHeaderSize = sizeof(EventHeader);
     
    954991
    955992  RHeader->Type = 0;                            // Run type: 0=data, 1=pedestal, 3=test
    956   RHeader->Events = 1;
    957993
    958994  RHeader->RunNumber = -1;
    959995  RHeader->FileNumber = 0;
    960   snprintf(RHeader->Description, sizeof(RHeader->Description), "FADctrl_Event");       
     996  snprintf(RHeader->Description, sizeof(RHeader->Description), "FADctrl");       
    961997
    962998  RHeader->NBoards = Boards.size();
     
    9651001  RHeader->Samples = NBins;                     // Always full pipeline
    9661002  RHeader->Offset = 0;
    967   RHeader->NBytes = 2;
     1003  RHeader->NBytes = sizeof(short);
    9681004
    9691005  // M0 EventHeader
     
    9771013       
    9781014        // Update run and event header with current time
    979         gettimeofday(&Time, NULL);     
     1015        gettimeofday(&Time, NULL);
     1016
     1017        RHeader->MagicNum = MAGICNUM_CLOSED;
     1018        RHeader->EndSecond = Time.tv_sec;                       
     1019        RHeader->EndMicrosecond = Time.tv_usec;         
     1020
     1021        EHeader->Second = Time.tv_sec;
     1022        EHeader->Microsecond = Time.tv_usec;
     1023
     1024        // Close data file if requested or requested number of events reached
     1025        if((IDString.find("stop")!=string::npos || NumEvents==NumEventsRequested) && Mode==datarun) {
     1026
     1027          // Update run header 
     1028          RHeader->Events = NumEvents;
     1029          RHeader->StartSecond = RunStart.tv_sec;
     1030          RHeader->StartMicrosecond = RunStart.tv_usec;         
     1031
     1032          if (lseek(Datafile, 0, SEEK_SET) == -1) {
     1033            PrintMessage("Error: Could not rewind file to write updated run header (%s)\n", strerror(errno));
     1034          }
     1035          else if (write(Datafile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
     1036                PrintMessage("Error: Could not write updated run header (%s)\n", strerror(errno));
     1037          }
     1038
     1039          // Close data file and terminate run
     1040          if(close(Datafile) == -1) PrintMessage("Error: Could not close data file (%s)\n", strerror(errno));
     1041          else PrintMessage("Data file closed (size %.1f MByte).\n", FileSize/1024.0/1024);
     1042
     1043          Datafile = -1;
     1044          Mode = idle;   
     1045        }
     1046
     1047        // These values might have changed while close file
    9801048        RHeader->StartSecond = Time.tv_sec;
    9811049        RHeader->StartMicrosecond = Time.tv_usec;               
    982         RHeader->EndSecond = Time.tv_sec;                       
    983         RHeader->EndMicrosecond = Time.tv_usec;         
    984 
    985         EHeader->Second = Time.tv_sec;
    986         EHeader->Microsecond = Time.tv_usec;
     1050    RHeader->Events = 1;
    9871051
    9881052        // Check all boards that have new data
     
    10031067          EHeader->TriggerType = S.TriggerType;
    10041068
     1069          // Register event number for data writing below
     1070          EventNumbers[Brd] = S.TriggerID;
     1071
    10051072          // Write trigger cells
    10061073          for(unsigned int i=0; i<NChips; i++) TriggerCell[Brd*NChips+i] = (int) S.TriggerCell[i];
    10071074
    1008           // Write channel data (stored in 12 bit signed twis complement with out-of-range-bit and leading zeroes)
     1075          // Write channel data (12 bit signed twis complement with out-of-range-bit and leading zeroes)
    10091076          int Count = 0;
    10101077          memset(Data, 0, Boards.size()*NChips*NChannels*NBins*sizeof(short));
     
    10231090                Count += NBins - S.ROI[Chip][Chan];
    10241091          }
     1092
     1093          // Inform TCP/IP thread that data has been processed   
     1094          Boards[Brd]->Continue = true;
    10251095          Boards[Brd]->Unlock();
    1026         }
     1096
     1097          if ((Ret = pthread_cond_signal(&Boards[Brd]->CondVar)) != 0) {
     1098                Message(FATAL, "pthread_cond_signal() failed (%s)", strerror(Ret));
     1099          }
     1100        } // Loop over boards
    10271101
    10281102        // Check if DIM service should be updated
     
    10311105          EventService->updateService(EventData, EventSize);
    10321106        }
     1107       
     1108        // ===== Data writing ===
     1109       
     1110        if (Mode != datarun) continue;
     1111       
     1112        // Check if all event numbers are the same
     1113        bool Same = true;
     1114        for (unsigned int i=0; i<Boards.size(); i++) {
     1115          if (Boards[i]->Active && EventNumbers[i] != EventNumbers[0]) Same = false;
     1116        }
     1117        if (!Same) continue;
     1118
     1119        // Write also run header if this is the first event
     1120        int Offset;     
     1121        if (NumEvents == 0) {
     1122          RHeader->MagicNum = MAGICNUM_OPEN;
     1123          RunStart = Time;
     1124          Offset = 0;
     1125          FileSize = 0;
     1126        }
     1127        else Offset = sizeof(RunHeader) + Boards.size()*sizeof(BoardStructure);
     1128       
     1129        // Write data to file
     1130        if(write(Datafile, EventData+Offset, EventSize-Offset) != (ssize_t) EventSize-Offset) {
     1131          PrintMessage("Error: Could not write all data to file, terminating run (%s)\n", strerror(errno));
     1132
     1133          // Close file if error
     1134          if (close(Datafile) == -1) PrintMessage("Error: Could not close data file (%s)\n", strerror(errno));
     1135          Datafile = -1;
     1136          Mode = idle;
     1137          continue;
     1138        }
     1139       
     1140        NumEvents++;
     1141        FileSize += EventSize-Offset;
     1142       
     1143        printf("Wrote event %d\n", NumEvents-1);
    10331144  }
    10341145
  • fact/FADctrl/FAD.h

    r10113 r10114  
    1717#include <sys/time.h>
    1818#include <limits>
     19#include <fcntl.h>
    1920
    2021#include "FADBoard.h"
     
    2324const char CALIB_DIRECTORY[] = "~/";
    2425
    25 enum ModeType {idle, acalib, tcalib};
     26enum ModeType {idle, datarun, acalib};
    2627
    2728class FAD: public EvidenceServer {
     
    4445        float EventUpdateDelay;
    4546
     47    int Datafile;
     48    int NumEvents;                      // Number of event taken           
     49    int NumEventsRequested;     // Number of events requested
    4650        int NumCalibEvents;
    4751       
     
    7377        void cmd_phase();               void cmd_send();
    7478        void cmd_cancel();              void cmd_update();
     79        void cmd_take();
    7580
    7681    void EnableDomino();
  • fact/FADctrl/FADBoard.cc

    r10113 r10114  
    1919  InitOK = false;
    2020  Active = true;
     21  Continue = true;
    2122  CommError = false;
    2223  ACalibTime = -1;
     
    7273  }
    7374
     75  // Initialise condition variable for synchronization
     76  if ((Ret = pthread_cond_init(&CondVar, NULL)) != 0) {
     77    m->Message(m->ERROR, "pthread_cond_init() failed (%s)", strerror(Ret));
     78        return;
     79  }
     80
    7481  // Create thread that receives data
    7582  if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) {
     
    93100        if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
    94101        if ((Ret = pthread_join(Thread, NULL)) != 0) m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
     102  }
     103
     104  // Delete condition variable
     105  if ((Ret = pthread_cond_destroy(&CondVar)) != 0) {
     106        m->Message(m->ERROR, "pthread_cond_destroy() failed in ~FADBoard (%s)", strerror(Ret));
    95107  }
    96108
     
    187199  ssize_t Result;
    188200  struct BoardStatus PrevStatus;
     201  int Ret;
    189202
    190203  memset(&PrevStatus, 0, sizeof(PrevStatus));
     
    249262          // Lock to avoid concurrent access in GetStatus()
    250263          Lock();
     264
     265          // Wait until event thread processed the previous data
     266          while (!Continue) {
     267                if ((Ret = pthread_cond_wait(&CondVar, &Mutex)) != 0) {
     268                  m->Message(m->ERROR, "pthread_cond_wait() failed (%s)", strerror(Ret));
     269                }
     270          }
    251271
    252272          gettimeofday(&Status.Update, NULL);
     
    297317          }
    298318
     319          Continue = false;
    299320          Unlock();
    300321         
  • fact/FADctrl/FADBoard.h

    r10113 r10114  
    7575        bool CommError;
    7676        bool Active;
     77        bool Continue;
     78        pthread_cond_t CondVar;
    7779};
    7880
  • fact/FADctrl/History.txt

    r10113 r10114  
    6619/1/2011       Implemented secondary calibration.
    7721/1/2011       DIM event thread now informed through pipe of new data
     823/1/2011       Data can be written to disk in M0 format
Note: See TracChangeset for help on using the changeset viewer.