Changeset 36 for drsdaq


Ignore:
Timestamp:
05/07/09 09:16:29 (15 years ago)
Author:
ogrimm
Message:
Various changes, see History.txt
Location:
drsdaq
Files:
2 added
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • drsdaq

    • Property svn:ignore
      •  

        old new  
        22DRSDAQ.log
        33Dep.d
        4 
         4calib
  • drsdaq/DAQReadout.cc

    r31 r36  
    1010
    1111#include "DAQReadout.h"
     12#include "SlowData.h"
    1213
    1314static const char* daq_state_str[] = {"active", "stopped"};
     
    2223  {{"board", &DAQReadout::cmd_board, true, "<i> [j] | <all>" ,"Address board i, boards i-j, all boards"},
    2324   {"status", &DAQReadout::cmd_status, false, "[daq|drs]", "Show DAQ/DRS status information"},
    24    {"freq", &DAQReadout::cmd_freq, true, "<GHz>", "Set DRS sampling frequency"},
     25   {"freq", &DAQReadout::cmd_freq, true, "<GHz> [reg]", "Set DRS sampling frequency (regulated)"},
    2526   {"calib", &DAQReadout::cmd_calib, true, "<t_f> <c_f> [dir]", "Response calibration"},
    2627   {"trigger", &DAQReadout::cmd_trigger, true, "<on|off>", "Hardware trigger on or off"},
     
    2829   {"wmode", &DAQReadout::cmd_wmode, true, "<0|1>", "Set DRS wave mode"},
    2930   {"rmode", &DAQReadout::cmd_rmode, true, "<0|1>", "Set DRS readout mode"},
    30    {"mode", &DAQReadout::cmd_mode, true, "<0|1>", "Set DRS mode: 0 = single shot, 1 = continuous"},
    31    {"read", &DAQReadout::cmd_read, true, "<brd> <chip> <chan>", "Read current data from board, chip, channel"},
     31   {"mode", &DAQReadout::cmd_mode, true, "<single|continuous>", "Set DRS single shot or continuous mode"},
     32   {"read", &DAQReadout::cmd_read, false, "<brd chip chan> [res]", "Read current data (and restart if DAQ not active)"},
    3233   {"take", &DAQReadout::cmd_take, false, "<d|p|t> [n] [source]", "Start run (data, pedestal or test) with n events"},
    3334   {"events", &DAQReadout::cmd_events, false, "", "Number of events in current run"},
     
    4647   {"faverage", &DAQReadout::cmd_faverage, false, "[n]", "Set ot get number of averages for feedback"},
    4748   {"fgain", &DAQReadout::cmd_fgain, false, "[gain]", "Set ot get feedback gain"},
    48    {"ftarget", &DAQReadout::cmd_ftarget, false, "[brd chip chan]", "Set or get target value"},
    49    {"fresponse", &DAQReadout::cmd_fresponse, false, "[V1 V2]", "Start response measurement with voltages V1 and V2"},
     49   {"ftarget", &DAQReadout::cmd_ftarget, false, "[brd chip chan]", "Set or get target value (also 'all' supported)"},
     50   {"fresponse", &DAQReadout::cmd_fresponse, false, "[voltage]", "Start response measurement with given voltage difference"},
    5051   {"fconfig", &DAQReadout::cmd_fconfig, false, "", "Print feedback configuration"},
    5152   {"help", &DAQReadout::cmd_help, false, "", "Print help"}};
     
    6162   
    6263  time(&StartTime);  // Start time of DAQ
    63   Rawfile = NULL;
    6464
    6565  // Initialize status structure
    66   daq_state     = stopped;
    67   daq_runtype   = data;
    68   Socket        = -1;
    69   Exit          = false;
     66  daq_state         = stopped;
     67  daq_runtype       = data;
     68  Socket            = -1;
     69  Exit              = false;
     70  CalibrationRead   = false;
    7071  NumEvents             = 0;
    7172  NumEventsRequested    = 100;
     
    7374  FirstBoard            = 0;
    7475  LastBoard             = -1;
    75   sprintf(Source,"DUMMY");
     76  snprintf(Source,sizeof(Source),"DUMMY");
    7677 
    7778  // Read configuration file
     
    8283  else {
    8384    printf("Reading drsdaq configuration file %s\n", Configfile);
    84     ReadCard("LogFile",            fLogFile,            's', File);
    85     ReadCard("RawDataPath",        fRawDataPath,        's', File);
     85    ReadCard("LogFile",             fLogFile,           's', File);
     86    ReadCard("RawDataPath",         fRawDataPath,       's', File);
    8687    ReadCard("RotateWave",         &fRotateWave,        'I', File);
    8788    ReadCard("FirstSample",        &fFirstSample,       'I', File);
     
    101102  }
    102103
    103   // Open log file
     104  // Open log file and print configuration
    104105  if ((Logfile = fopen(fLogFile, "a")) == NULL)
    105106    fprintf(stderr,"Warning: Could not open log file '%s'\n", fLogFile);
    106107  else PrintMessage(MsgToLog,"********** Logging started **********\n");
    107  
    108108  cmd_config();
    109109
    110110  // Create DRS instance and perform initial scan
    111   drs     = new DRS();
     111  drs = new DRS();
    112112  drs->SetFirstVMESlot(fFirstVMESlot);
    113113  drs->SetLastVMESlot(fLastVMESlot);
    114114  drs->InitialScan();
    115115
    116   RHeader  = new RunHeader;
    117   EHeader  = new EventHeader;
    118   DRSFreq  = new float [drs->GetNumberOfBoards()];
     116  RHeader = new RunHeader;
     117  EHeader = new EventHeader;
     118  DRSFreq = new float [drs->GetNumberOfBoards()];
    119119
    120120  // Scan for DRS boards
     
    135135  WaveForm = new short [NumCMCBoards == 0 ? 1:NumCMCBoards][kNumberOfChips][kNumberOfChannels][kNumberOfBins];
    136136 
    137   // Create instance of HV feedback (must be after CMC board detection)
     137  // Create instance of HV feedback (must be called after CMC board detection)
    138138  HVFB    = new HVFeedback(this, fHVFeedbackConfig);
     139 
     140  // Create instance of slow data class for DAQ
     141  char Filename[MAX_PATH];
     142  snprintf(Filename,sizeof(Filename),"%s/SlowData/", fRawDataPath);
     143  SlowDataClass = new SlowData(this, "DAQ", Filename);
    139144}
    140145
     
    144149
    145150DAQReadout::~DAQReadout() {
     151  delete SlowDataClass;
    146152  delete RHeader;     delete EHeader;
    147153  delete drs;         delete HVFB;
     
    176182  for(CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++)
    177183    if (Match(Param[0], CommandList[CmdNumber].Name)) {
    178       if(CommandList[CmdNumber].NeedNotBusy && IsDAQBusy()) PrintMessage("DAQ is busy\n");
     184      if(CommandList[CmdNumber].NeedNotBusy && daq_state==active) PrintMessage("DAQ is busy\n");
    179185      else if(CommandList[CmdNumber].NeedNotBusy && NumCMCBoards==0) PrintMessage("No mezzanine boards available\n");
    180186      else (this->*CommandList[CmdNumber].CommandPointer)();
     
    189195  time_t ActualT;
    190196  time (&ActualT);
    191   PrintMessage("%d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
     197  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole, "%d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
    192198}
    193199
    194200// Print disk space
    195201void DAQReadout::cmd_disk() {
    196   PrintMessage("Free disk space (%s) [MB]: %lu\n", fRawDataPath, CheckDisk(fRawDataPath));
     202  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole, "Free disk space (%s) [MB]: %lu\n", fRawDataPath, CheckDisk(fRawDataPath));
    197203}
    198204
     
    217223void DAQReadout::cmd_take() {
    218224 
    219   if(!Match(Param[1],"test") && (IsDAQBusy() || NumCMCBoards==0)) {
    220     PrintMessage("DAQ is busy or no boards available.\n");
    221     return;
    222   }
    223   if (!IsDRSFreqSet()) return;
    224   if (!IsCalibrationRead())
    225     if(!ReadCalibration()) {
    226       PrintMessage("Problem with response calibration!\n");
     225  if(!Match(Param[1],"test")) {
     226    if (daq_state==active || NumCMCBoards==0) {
     227      PrintMessage("DAQ is busy or no boards available.\n");
    227228      return;
    228229    }
     230    if (!IsDRSFreqSet()) return;
     231    if (!CalibrationRead && !ReadCalibration()) {
     232      PrintMessage("Cannot start run if response calibration not read.\n");
     233      return;
     234    }
     235  }
    229236   
    230237  if (Match(Param[1],"data")) {
     
    244251  }
    245252
    246   if (NParam==3 && atoi(Param[2])) NumEventsRequested = atoi(Param[2]);
     253  if (NParam==3) NumEventsRequested = atoi(Param[2]);
    247254  if (NParam==4) {
    248     if(atoi(Param[2])) NumEventsRequested = atoi(Param[2]);
     255    NumEventsRequested = atoi(Param[2]);
    249256    strcpy(Source, Param[3]);
    250257  }
    251258
     259  // Determine new run number using the file RUN_NUM_FILE
     260  FILE *RunNumFile = fopen(RUN_NUM_FILE,"r+");
     261  if(RunNumFile == NULL) {
     262    PrintMessage("Error: Could not open file '%s' that contains the last run number (%s)\n",RUN_NUM_FILE,strerror(errno));
     263    return;
     264  }
     265  if(fscanf(RunNumFile,"%u", &RunNumber) != 1 ) {
     266    PrintMessage("Error: Could not read run number from file '%s'\n",RUN_NUM_FILE);
     267    fclose(RunNumFile);
     268    return;
     269  }
     270  RunNumber++;
     271  rewind(RunNumFile);
     272  if((fprintf(RunNumFile,"%.8u   ",RunNumber) < 0) || (fclose(RunNumFile)!=0)) {
     273    PrintMessage("Error: Could not write to or close run number file '%s'\n",RUN_NUM_FILE);
     274    PrintMessage("*** This is a serious error because run numbers will get mixed. Fix it. DAQ will terminate.\n");
     275    throw;
     276  }
     277
     278  // Create DAQ thread
    252279  if ((pthread_create(&thread_DAQ, NULL, (void * (*)(void *)) DAQ,(void *) this)) != 0)
    253280    perror("pthread_create failed with DAQ thread");
     
    295322  }
    296323 
    297   if (NumCMCBoards)
    298     for (i=FirstBoard; i<=LastBoard; i++) {
    299       PrintMessage("BLT test started (board #%d)\n",i);
    300       (drs->GetBoard(i))->TestRead(Param[2][0] && atoi(Param[2])<=10000 && atoi(Param[2])>0 ? atoi(Param[2]):1, Type);
    301     }
     324  if (NumCMCBoards) for (i=FirstBoard; i<=LastBoard; i++) {
     325        PrintMessage("BLT test started (board #%d)\n",i);
     326        (drs->GetBoard(i))->TestRead(Param[2][0] && atoi(Param[2])<=10000 && atoi(Param[2])>0 ? atoi(Param[2]):1, Type);
     327      }
    302328  else PrintMessage("No DRS boards available\n");
    303329}
     
    305331// Stop DAQ
    306332void DAQReadout::cmd_stop() {
    307   if(!IsDAQBusy() && !IsDRSBusy()) PrintMessage("Nothing to stop\n");
    308   if (IsDAQBusy()) StopRun();
     333  if(!daq_state==active && !IsDRSBusy()) PrintMessage("Nothing to stop\n");
     334  if (daq_state==active) StopRun();
    309335  if (IsDRSBusy()) {
    310336    StopDRS();
     
    313339}
    314340 
    315 // Read data
     341// Read current data
     342// For socket transmission: all numbers must be separated by exactly one
     343// whitespace; the first number is the number of numbers that follow, the
     344// second number the sampling frequency in GHz, the third the conversion factor
     345
    316346void DAQReadout::cmd_read() {
    317   if (IsDRSBusy()) {
    318     PrintMessage("Domino wave is running, issue \"stop first\"\n");
     347  if(NumCMCBoards==0) {
     348    PrintMessage("No mezzanine boards available\n");
    319349    return;
    320   }
    321   if (Param[1][0] && Param[2][0] && Param[3][0]) {
    322     if (IsDRSFreqSet()&& !IsCalibrationRead()) ReadCalibration();
    323     ReadandPrintDRSData(atoi(Param[1]),atoi(Param[2]),atoi(Param[3]));
    324   }
    325   else PrintUsage(); 
     350  }
     351  if (NParam<4) {
     352    PrintUsage();
     353    return;
     354  }     
     355  if (atoi(Param[1])>LastBoard || atoi(Param[1])<FirstBoard) {
     356    PrintMessage("Error: Board number out of range\n");
     357    return;
     358  }
     359  if (atoi(Param[3])<0 || atoi(Param[3])>=kNumberOfChannels) {
     360    PrintMessage("Error: Channel number out of range\n");
     361    return;
     362  }
     363  if (atoi(Param[2])<0 || atoi(Param[2])>=kNumberOfChips) {
     364    PrintMessage("Error: Chip number out of range\n");
     365    return;
     366  }
     367 
     368  if(daq_state!=active) {
     369    if (!CalibrationRead) ReadCalibration();
     370    if(NParam==5) StopDRS();
     371    ReadCalibratedDRSData();
     372    if(NParam==5) StartDRS();
     373  } 
     374  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "==START== %d %.2f %.2f ",kNumberOfBins+2,DRSFreq[atoi(Param[1])],drs->GetBoard(atoi(Param[1]))->GetPrecision());
     375  for (int k=0; k<kNumberOfBins; k++) PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "%.1f ", (float) WaveForm[atoi(Param[1])][atoi(Param[2])][atoi(Param[3])][k]);
     376  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "==END==");
     377  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole|MsgToLog, "\n");
    326378}
    327379
     
    387439// Set DRS sampling frequency
    388440void DAQReadout::cmd_freq() {   
    389   if (NParam==3 && atof(Param[1]) && atoi(Param[2]))
    390     SetRegulatedDRSFrequency(atof(Param[1]));
    391   else if (NParam==2 && atof(Param[1]))
    392     SetDRSFrequency(atof(Param[1]));
     441  if (NParam>=2 && atof(Param[1])) {
     442    SetDRSFrequency(atof(Param[1]), NParam==2 ? false : true);
     443    CalibrationRead = false;
     444  }
    393445  else PrintUsage();
    394446}
     
    510562  }
    511563  else PrintMessage("Cannot address board(s), out of range.\n");
     564  CalibrationRead = false;
    512565}
    513566
     
    516569  char Buffer[MAX_COM_SIZE];
    517570  for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
    518     sprintf(Buffer, "%s %s", CommandList[i].Name, CommandList[i].Parameters);
    519     PrintMessage(MsgToConsole|MsgToSocket,"%-28s%s\n", Buffer, CommandList[i].Help);
     571    snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);
     572    PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole,"%-28s%s\n", Buffer, CommandList[i].Help);
    520573  }     
    521   PrintMessage(MsgToConsole|MsgToSocket,".<command>                  Execute shell command\n\n"
     574  PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole,".<command>                  Execute shell command\n\n"
    522575   "Items in <> are mandatory, in [] optional, | indicates mutual exclusive or.\n"
    523576   "Test data can also be written if no DRS boards are available.\n"
     
    531584     return;
    532585  }     
    533   if (IsDAQBusy()) PrintMessage("Issue \"stop\" first to stop daq\n");
     586  if (daq_state==active) PrintMessage("Issue \"stop\" first to stop daq\n");
    534587  else {
    535588    Exit = true;
     
    540593// Set/get mode of feedback
    541594void DAQReadout::cmd_fmode() {
    542   if(NParam==1) HVFB->GetFBMode();
    543   else if(Match(Param[1],"off")) HVFB->SetFBMode(FB_Off);
    544   else if(Match(Param[1],"active")) HVFB->SetFBMode(FB_Active);
    545   else if(Match(Param[1],"targets")) HVFB->SetFBMode(FB_Targets);
    546   else PrintUsage();
     595  if(Match(Param[1],"off")) HVFB->SetFBMode(FB_Off);
     596  if(Match(Param[1],"active")) HVFB->SetFBMode(FB_Active);
     597  if(Match(Param[1],"targets")) HVFB->SetFBMode(FB_Targets);
     598  HVFB->GetFBMode();
    547599}
    548600
    549601// Set/get current number of events
    550602void DAQReadout::cmd_faverage() {
    551   if(NParam==1) printf("Current number of feedback events: %u   (acting when %u events are reached)\n",
     603  if(NParam==1) PrintMessage("Current number of feedback events: %u   (acting when %u events are reached)\n",
    552604                       HVFB->GetCurrentCount(), HVFB->GetNumAverages());
    553605  else if(atoi(Param[1])>=0) HVFB->SetNumAverages(atoi(Param[1]));
     
    557609// Set/get feedback gain
    558610void DAQReadout::cmd_fgain() {
    559   if(NParam==1) printf("Feedback gain is %.2f\n", HVFB->GetGain());
    560   else if(NParam==2) HVFB->SetGain(atof(Param[1]));
    561   else PrintUsage();
     611  if(NParam==2) HVFB->SetGain(atof(Param[1]));
     612  PrintMessage("Feedback gain is %.2f\n", HVFB->GetGain());
    562613}
    563614
     
    566617  if(NParam==1) HVFB->GetTargets();
    567618  else if(NParam!=5) PrintUsage();
    568   else {
    569     if(atoi(Param[1])>=0 && atoi(Param[1])<NumCMCBoards && atoi(Param[2])>=0 &&
    570        atoi(Param[2])<kNumberOfChips && atoi(Param[3])>=0 && atoi(Param[3])<kNumberOfChannels)
    571          HVFB->SetTarget(atoi(Param[1]),atoi(Param[2]),atoi(Param[3]),atoi(Param[4]));
    572     else PrintMessage("Board, chip or channel number out of range.\n");
    573   }
     619  else for (int i=FirstBoard; i<=LastBoard; i++)
     620         for (int j=0; j<kNumberOfChips; j++)
     621           for (int k=0; k<kNumberOfChannels; k++)
     622             if ((atoi(Param[1])==i || Match(Param[1],"all")) &&
     623                 (atoi(Param[2])==j || Match(Param[2],"all")) &&
     624                 (atoi(Param[3])==k || Match(Param[3],"all")))
     625              HVFB->SetTarget(i,j,k,atof(Param[4]));
    574626}
    575627
     
    577629void DAQReadout::cmd_fresponse() {
    578630  if(NParam==1) HVFB->GetResponse();
    579   else if(atof(Param[1]) && atof(Param[2]))
    580     HVFB->MeasureResponse(atof(Param[1]),atof(Param[2]));
     631  else if(atof(Param[1])) HVFB->MeasureResponse(atof(Param[1]));
    581632  else PrintUsage();
    582633}
     
    599650void DAQReadout::StopDRS() {
    600651  for (int i=FirstBoard; i<=LastBoard; i++) drs->GetBoard(i)->SoftTrigger();
    601 }
    602 
    603 // Read current data
    604 void DAQReadout::ReadandPrintDRSData(int board, int chip, int channel) {
    605 
    606   if (board>LastBoard || board<FirstBoard) {
    607     PrintMessage("Error: Board %d does not exist\n",board);
    608     return;
    609   }
    610   if (channel<0 || channel>kNumberOfChannels-1) {
    611     PrintMessage("Error: Select channel between %d and %d\n",0,kNumberOfChannels-1);
    612     return;
    613   }
    614   if (chip<0 || chip>1) {
    615     PrintMessage("Error: Select chip index between 0 and 1\n");
    616     return;
    617   }
    618   PrintMessage("Waveform from board %d, chip %d, channel %d\n",board,chip,channel);
    619   ReadCalibratedDRSData();
    620  
    621   // Note that all numbers must be separated by exactly one whitespace
    622   // to allow reading from client socket
    623   // The first number is the number of numbers that follow, the second number
    624   // is the sampling frequency in GHz and the third is the conversion factor.
    625   PrintMessage("==START== %d %.2f %.2f ",kNumberOfBins+2,DRSFreq[board],drs->GetBoard(board)->GetPrecision());
    626   for (int k=0; k<kNumberOfBins; k++) PrintMessage("%.1f ", (float) WaveForm[board][chip][channel][k]);
    627   PrintMessage("==END==");
    628   PrintMessage("\n");
    629652}
    630653
     
    650673  for (int i=FirstBoard; i<=LastBoard; i++) {
    651674    (drs->GetBoard(i))->SetCalibrationDirectory(dir);
    652     PrintMessage("Reading response calibration file for board %d from: \"%s\"\n",i,dir);
     675    PrintMessage("Reading response calibration file for board %d from: \"%s\"\n", i, dir);
    653676    for (int Chip=0; Chip<kNumberOfChips; Chip++)
    654       if (drs->GetBoard(i)->GetResponseCalibration()->ReadCalibration(Chip)==false) return false;
    655   }
     677      if (drs->GetBoard(i)->GetResponseCalibration()->ReadCalibration(Chip)==false) {
     678        CalibrationRead = false;
     679        return false;
     680      }
     681  }
     682  CalibrationRead = true;
    656683  return true;
    657684}
     
    735762}
    736763
    737 // Read the frequency of all boards
    738 double DAQReadout::ReadDRSFrequency() {
    739 
    740   double freq = 0;
    741  
    742   if (NumCMCBoards)
    743     for (int i=FirstBoard; i<=LastBoard; i++) {
    744       (drs->GetBoard(i))->ReadFrequency(0, &freq);
    745        PrintMessage("Domino wave of board %d is running at %1.3lf GHz\n",i,freq);
    746     }
    747   else PrintMessage("No DRS boards available\n");
    748 
    749   return freq;
    750 }
    751 
    752 // Set DRS sampling frequency
    753 void DAQReadout::SetDRSFrequency(double freq) {
     764// Set DRS sampling frequency
     765void DAQReadout::SetDRSFrequency(double freq, bool Regulation) {
    754766
    755767  double currentfreq;
    756768
    757   if (NumCMCBoards) {
    758     PrintMessage("Setting frequency without regulation:\n");
    759    
    760     for (int i=FirstBoard; i<=LastBoard; i++) {
    761       drs->GetBoard(i)->SetDebug(1);
    762      
    763       if (drs->GetBoard(i)->SetFrequency(freq)) {
    764         drs->GetBoard(i)->ReadFrequency(0, &currentfreq);
    765         DRSFreq[i] = freq;
    766         PrintMessage("Domino wave of board %d is running at %1.3lf GHz\n",i,currentfreq);
    767       } else {
    768         DRSFreq[i] = 0;
    769         PrintMessage("Warning: domino wave of board %d has changed but not reached the requested value\n",i);
    770       }
    771     }
    772   } 
    773   else PrintMessage("No DRS boards available\n");
    774 }
    775 
    776 // Regulate DRS sampling frequency
    777 void DAQReadout::SetRegulatedDRSFrequency(double freq) {
    778 
    779   double currentfreq;
    780 
    781   if (NumCMCBoards) {
    782     PrintMessage("Setting frequency with regulation:\n");
    783 
    784     for (int i=FirstBoard; i<=LastBoard; i++) {
    785       drs->GetBoard(i)->SetDebug(1);
    786      
    787       if (drs->GetBoard(i)->RegulateFrequency(freq)) {
    788        
    789           drs->GetBoard(i)->ReadFrequency(0, &currentfreq);
    790           PrintMessage("Domino wave of board %d is running at %1.3lf GHz\n",i,currentfreq);
    791           DRSFreq[i] = freq;;
    792       }
    793       else DRSFreq[i] = 0;
    794     }
    795   }
    796   else PrintMessage("No DRS boards available\n");
     769  PrintMessage("Setting frequency %s regulation:\n",Regulation ? "with":"without");
     770  for (int i=FirstBoard; i<=LastBoard; i++) {
     771    drs->GetBoard(i)->SetDebug(1);
     772
     773    if (Regulation ? drs->GetBoard(i)->RegulateFrequency(freq) : drs->GetBoard(i)->SetFrequency(freq)) {
     774      drs->GetBoard(i)->ReadFrequency(0, &currentfreq);
     775      DRSFreq[i] = freq;
     776      PrintMessage("Domino wave of board %d is running at %1.3lf GHz\n",i,currentfreq);
     777    } else {
     778      DRSFreq[i] = 0;
     779      PrintMessage("Warning: Domino wave of board %d has changed but not reached the requested value\n",i);
     780    }
     781  }
    797782}
    798783
     
    811796      }
    812797      closedir(pdir);
    813       sprintf(str,"%s",dir);
     798      snprintf(str,sizeof(str),"%s",dir);
    814799      PrintMessage("Target: \"%s\"\n",str);
    815800    }
     
    858843}
    859844
    860 // Check if DAQ is busy
    861 bool DAQReadout::IsDAQBusy() {
    862 
    863   if (daq_state == active) {
    864     PrintMessage("DAQ is busy\n");
    865     return true;
    866   }
    867   else return false;
    868 }
    869 
    870845// Check if DRS is sampling
    871846bool DAQReadout::IsDRSBusy() {
     
    888863
    889864// Open new raw data file
    890 bool DAQReadout::OpenRawFile(int Part) {
     865bool DAQReadout::OpenRawFile() {
    891866
    892867  time_t rawtime;
    893868  struct tm *timeinfo;
    894   char RunDate[MAX_COM_SIZE], Buffer[MAX_COM_SIZE], SystemCommand[MAX_COM_SIZE];
    895   int TempDescriptor;
     869  char RunDate[MAX_COM_SIZE], Buffer[MAX_COM_SIZE];
    896870 
    897871  // Write run date to status structure
    898   time(&rawtime);
    899   timeinfo = localtime(&rawtime);
    900   sprintf(RunDate,"%d%02d%02d",timeinfo->tm_year + 1900,timeinfo->tm_mon + 1,timeinfo->tm_mday);
     872  time(&rawtime);   timeinfo = localtime(&rawtime);
     873  snprintf(RunDate,sizeof(RunDate), "%d%02d%02d",timeinfo->tm_year+1900,timeinfo->tm_mon + 1,timeinfo->tm_mday);
    901874
    902875  // Create direcory if not existing (ignore error if already existing) and change to it
    903   sprintf(Buffer, "%s/%s", fRawDataPath, RunDate);
     876  snprintf(Buffer, sizeof(Buffer), "%s/%s", fRawDataPath, RunDate);
    904877  if(mkdir(Buffer, S_IRWXU|S_IRWXG)==-1 && errno!=EEXIST) {
    905878    PrintMessage("\rError: Could not create direcory \"%s\" (%s)\n", Buffer, strerror(errno));
     
    907880  }
    908881 
    909   // Determine new run number in directory (only if first file in series) by finding the
    910   // last file in alphabetical order and assuming that run number starts at position 9
    911   if(Part==0) {
    912     char *TmpName = tmpnam(NULL);
    913     sprintf(SystemCommand, "ls -1 %s/*.raw 2>/dev/null|tail -n-1 >%s", Buffer, TmpName);
    914     system(SystemCommand);
    915     if ((TempDescriptor=open(TmpName,O_RDONLY)) == -1) {
    916       PrintMessage("Error: Could not determine last run number (%s)\n",strerror(errno));
    917       return false;
    918     }
    919     memset(Buffer,0,sizeof(Buffer));
    920     read(TempDescriptor, Buffer, sizeof(Buffer));
    921     close(TempDescriptor);
    922     remove(TmpName);
    923     if(sscanf(Buffer, "%*28c%u", &RunNumber) == 1) RunNumber++;
    924     else RunNumber = 0;
    925   }
    926 
    927882  // Generate filename
    928   sprintf(FileName,"%s/%s/%s_%.8d_%s_%c_%d.raw", fRawDataPath, RunDate,
    929     RunDate,RunNumber,Source,daq_runtype_str[daq_runtype][0],Part);
     883  snprintf(FileName,sizeof(FileName),"%s/%s/%s_%.8u_%s_%c_%d.raw", fRawDataPath, RunDate,
     884    RunDate,RunNumber,Source,daq_runtype_str[daq_runtype][0],FileNumber);
    930885 
    931886  //  Open file with rwx right for owner and group, never overwrite file
    932   TempDescriptor = open(FileName,O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IRWXG);
    933   if(TempDescriptor==-1) {
    934     PrintMessage("\rError: Could not open file \"%s\"\n",FileName);
    935     perror("Error");
     887  Rawfile = open(FileName,O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IRWXG);
     888  if(Rawfile==-1) {
     889    PrintMessage("\rError: Could not open file \"%s\" (%s)\n", FileName, strerror(errno));
    936890    return false;
    937891  }
    938   Rawfile = fdopen(TempDescriptor,"w");
    939892  return true;
    940893}
    941894
    942895// Write run header and board structures
    943 void DAQReadout::WriteRunHeader() {
     896bool DAQReadout::WriteRunHeader() {
    944897
    945898  time_t time_now_secs;
    946899  struct tm *time_now;
    947900
    948   RHeader->MagicNum = MAGICNUM_FILE_OPEN;
     901  RHeader->MagicNum = MAGICNUM_OPEN;
    949902  RHeader->DataFormat   = DATA_FORMAT;
     903  RHeader->RunHeaderSize = sizeof(RunHeader);
     904  RHeader->EventHeaderSize = sizeof(EventHeader);
     905  RHeader->BoardStructureSize = sizeof(BoardStructure);
    950906  strcpy(RHeader->DAQVersion,   __DATE__);
     907
    951908  strcpy(RHeader->Source,       Source);
    952909  RHeader->Type = daq_runtype_str[daq_runtype][0];
    953910  RHeader->RunNumber  = RunNumber;
     911  RHeader->FileNumber = FileNumber;
    954912
    955913  time(&time_now_secs);
     
    969927
    970928  RHeader->NCMCBoards = NumCMCBoards==0 && daq_runtype==test ? 1 : (LastBoard - FirstBoard) + 1; 
    971   RHeader->NChips       = kNumberOfChips;
    972   RHeader->NChannels    = kNumberOfChannels;
    973 
    974   RHeader->Offset       = fFirstSample;
    975   RHeader->Samples      = fLastSample - fFirstSample + 1;
    976  
    977   if(fwrite(RHeader, sizeof(RunHeader), 1, Rawfile) != 1) {
     929  RHeader->NChips     = kNumberOfChips;
     930  RHeader->NChannels  = kNumberOfChannels;
     931
     932  RHeader->Offset  = fFirstSample;
     933  RHeader->Samples = fLastSample - fFirstSample + 1;
     934
     935  if(write(Rawfile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
    978936    PrintMessage("Error: Could not write run header, terminating run (%s)\n", strerror(errno));
    979     Stop = true;
    980   }
    981 
     937    return false;
     938  }
     939 
    982940  for (int i=FirstBoard; i<=LastBoard; i++) {
    983     BStruct[i].Index       = i;   
    984941    BStruct[i].SerialNo    = drs->GetBoard(i)->GetCMCSerialNumber();     
    985942    BStruct[i].BoardTemp   = drs->GetBoard(i)->GetTemperature();
     
    990947  // In case no boards are available, dummy data is written for one board structure   
    991948  if (NumCMCBoards == 0) {
    992     LastBoard=0;
    993949    BStruct[0].NomFreq     = 1;
    994950    BStruct[0].ScaleFactor = 0.1;
    995951  }   
    996952
    997   if(fwrite(BStruct, sizeof(BoardStructure), LastBoard-FirstBoard+1, Rawfile) != (unsigned int) (LastBoard-FirstBoard+1)) {
     953  if(write(Rawfile, BStruct, sizeof(BoardStructure)*(LastBoard-FirstBoard+1+(NumCMCBoards==0))) != (ssize_t) sizeof(BoardStructure)*(LastBoard-FirstBoard+1+(NumCMCBoards==0))) {
    998954    PrintMessage("Error: Could not write (all) board structures, terminating run (%s)\n", strerror(errno));
    999     Stop = true;
    1000   }
    1001   if (NumCMCBoards == 0) LastBoard=-1;
     955    return false;
     956  }
     957  return true;
    1002958}
    1003959
    1004960// Update the run header
    1005 void DAQReadout::UpdateRunHeader(unsigned int Events) {
     961bool DAQReadout::UpdateRunHeader(unsigned int Events, bool Error) {
    1006962
    1007963  time_t time_now_secs;
    1008964  struct tm *time_now;
    1009965 
    1010   RHeader->MagicNum = MAGICNUM_FILE_CLOSED;
    1011   RHeader->Events     = Events;
     966  RHeader->MagicNum = Error==false ? MAGICNUM_CLOSED:MAGICNUM_ERROR;
     967  RHeader->Events   = Events;
    1012968
    1013969  time(&time_now_secs);
     
    1021977  RHeader->EndSecond   = time_now->tm_sec;
    1022978
    1023   rewind(Rawfile);
    1024   if(fwrite(RHeader, sizeof(RunHeader), 1, Rawfile) != 1) {
     979  if(lseek(Rawfile,0,SEEK_SET)==-1) {
     980    PrintMessage("Error: Could not rewind file to write updated run header, terminating run (%s)\n", strerror(errno));
     981    return false;
     982  }
     983
     984  if(write(Rawfile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) {
    1025985    PrintMessage("Error: Could not write updated run header, terminating run (%s)\n", strerror(errno));
    1026     Stop = true;
    1027   }
     986    return false;
     987  }
     988  return true;
    1028989}
    1029990
    1030991// Write event header
    1031 void DAQReadout::WriteEventHeader() {
    1032 
    1033   time_t time_now_secs;
    1034   struct tm *time_now;
    1035   struct timezone tz;
    1036   struct timeval actual_time;
    1037 
     992bool DAQReadout::WriteEventHeader() {
     993
     994  struct timeval Time;
     995
     996  gettimeofday(&Time, NULL);
     997 
    1038998  strcpy(EHeader->Name,"EVTH");
    1039  
    1040999  EHeader->EventNumber = NumEvents;
    10411000  EHeader->TriggerType = 0XFFFF;
    1042 
    1043   time(&time_now_secs);
    1044   time_now = localtime(&time_now_secs);
    1045  
    1046   gettimeofday(&actual_time, &tz);
    1047   EHeader->TimeSec = time_now->tm_sec + actual_time.tv_usec/1000000.;
    1048 
    1049   if(fwrite(EHeader, sizeof(EventHeader), 1, Rawfile) != 1) {
     1001  EHeader->TimeSec = Time.tv_sec + (float) Time.tv_usec/1000000.;
     1002
     1003  if(write(Rawfile, EHeader, sizeof(EventHeader)) != sizeof(EventHeader)) {
    10501004    PrintMessage("Error: Could not write event header, terminating run (%s)\n", strerror(errno));
    1051     Stop = true;
    1052   }
     1005    return false;
     1006  }
     1007  return true;
    10531008}
    10541009
     
    10801035
    10811036  memset(Textbuffer, 0, sizeof(Textbuffer)); 
    1082   vsprintf(Textbuffer, Format, ArgumentPointer);
     1037  vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
    10831038 
    10841039  // Print to console and generate new prompt
     
    12051160
    12061161  struct timeval StartTime, StopTime;
    1207   int Filepart;
     1162  int Count;
    12081163  unsigned int EventsInFile;
    1209   unsigned long long RunSize;
    1210    
    1211   Filepart = 0;   RunSize = 0;
     1164  unsigned long long RunSize = 0;
     1165  bool WriteError = false;
     1166  struct iovec DataPart[IOV_MAX];
     1167  ssize_t WriteResult;
     1168  off_t FileSize;
     1169
     1170  m->NumEvents = 0;
     1171  m->FileNumber = 0;
    12121172  m->HVFB->ClearAverages();   
    1213   m->NumEvents = 0;
    12141173  gettimeofday(&StartTime, NULL);
    12151174
     
    12231182
    12241183    // Init run header, open raw file, write run header
    1225     if (!m->OpenRawFile(Filepart)) break;
     1184    if (!m->OpenRawFile()) break;
    12261185    m->PrintMessage("\rData file \"%s\" opened.\n",m->FileName);
    12271186    EventsInFile = 0;
    1228     m->WriteRunHeader();
     1187    FileSize = 0;
     1188    WriteError |= !m->WriteRunHeader();
    12291189   
    12301190    if (m->daq_runtype != test) m->StartDRS();
    12311191
    12321192    // Take data until finished, stopped or file too large   
    1233     while (m->NumEvents<m->NumEventsRequested && !m->Stop &&
    1234       ftell (m->Rawfile)/1024/1024<m->fMaxFileSizeMB) {
     1193    while ((m->NumEvents<m->NumEventsRequested || m->NumEventsRequested==0) &&
     1194      !m->Stop && FileSize/1024/1024<m->fMaxFileSizeMB && !WriteError) {
    12351195
    12361196      if (m->daq_runtype == data) while (m->IsDRSBusy());  // Wait for hardware trigger (if DAQ stopped, DRS will not be busy anymore)
    1237       else if (m->daq_runtype == pedestal) m->StopDRS();      // Wait for software trigger
    1238 
    1239       EventsInFile++;
    1240       m->NumEvents++;   
    1241       m->WriteEventHeader();
     1197      else if (m->daq_runtype == pedestal) m->StopDRS();   // ..or for software trigger
     1198
     1199      EventsInFile++;      m->NumEvents++;     
     1200      WriteError |= !m->WriteEventHeader();
    12421201
    12431202      // Read event data via VME or generate test data (for one board if no boards available)
     
    12511210          *((short *) m->WaveForm+i) = (short) (sin(i/Period)*1000);
    12521211      }
    1253       // Write data to disk
    1254       for (int i=m->FirstBoard; i<=m->LastBoard + (m->NumCMCBoards==0); i++) {
    1255         for (unsigned int k=0; k<m->RHeader->NChips*m->RHeader->NChannels; k++)
    1256           if(fwrite((short *) m->WaveForm[i] + m->RHeader->Offset + k*kNumberOfBins, sizeof(short), m->RHeader->Samples, m->Rawfile) != m->RHeader->Samples) {
    1257             m->PrintMessage("Error: Could not write event data, terminating run ()\n", strerror(errno));
    1258             m->Stop = true;
    1259           }
     1212
     1213      // Write data to disk (using writev() for performance reason)
     1214      Count  = 0;
     1215      for (int i=m->FirstBoard; (i<=m->LastBoard + (m->NumCMCBoards==0)) && !WriteError; i++) {
     1216        for (unsigned int k=0; k<m->RHeader->NChips*m->RHeader->NChannels; k++) {
     1217          DataPart[Count].iov_base = &m->WaveForm[i][k/m->RHeader->NChannels][k%m->RHeader->NChannels][m->RHeader->Offset];
     1218          DataPart[Count++].iov_len = m->RHeader->Samples * sizeof(short);
     1219       
     1220          // Write to disk if either maximum size of DataPart[] array or last loop interation is reached
     1221          if (Count==IOV_MAX || (k==(m->RHeader->NChips*m->RHeader->NChannels-1) && i==(m->LastBoard+(m->NumCMCBoards==0)))) {
     1222            if ((WriteResult=writev(m->Rawfile, DataPart, Count)) != (int) (Count*DataPart[0].iov_len)) {
     1223              if (WriteResult==-1) m->PrintMessage("Error: Could not write event data, terminating run (%s)\n", strerror(errno));
     1224              else m->PrintMessage("Error: Could only write %u out of %u bytes of event data, terminating run\n", WriteResult,Count*DataPart[0].iov_len);
     1225              WriteError = true;
     1226              break;
     1227            }
     1228            Count = 0;
     1229          }
    12601230        }
     1231      }
     1232
     1233      // Update file size
     1234      if((FileSize = lseek(m->Rawfile, 0, SEEK_CUR)) == -1) {
     1235        m->PrintMessage("Error: Could not determine file size, terminating run (%s)\n", strerror(errno));
     1236        WriteError = true;
     1237      }
    12611238      // Call feedback to process event
    12621239      m->HVFB->ProcessEvent();
     
    12641241
    12651242    // Write updated run header, close file
    1266     RunSize += ftell (m->Rawfile);
    1267     m->UpdateRunHeader(EventsInFile);
    1268     fclose(m->Rawfile); 
    1269     m->PrintMessage("Data file closed.\n");
    1270 
    1271     Filepart += 1;
    1272   } while(m->NumEvents < m->NumEventsRequested && !m->Stop);
     1243    RunSize += FileSize;
     1244    WriteError |= !m->UpdateRunHeader(EventsInFile, WriteError);
     1245    if(close(m->Rawfile)==-1) m->PrintMessage("Error: Could not close data file (%s)\n", strerror(errno));
     1246    else m->PrintMessage("Data file closed (size %lu MByte).\n", FileSize/1024/1024);
     1247
     1248    m->FileNumber += 1;
     1249  } while(m->NumEvents<m->NumEventsRequested && !m->Stop && !WriteError);
    12731250
    12741251  m->StopDRS();
    1275 
    1276   m->PrintMessage("\r%s run #%d %s (%d event(s))\n",daq_runtype_str[m->daq_runtype],m->RunNumber,(m->NumEvents == m->NumEventsRequested) ? "completed":"stopped",m->NumEvents);
    1277   if (m->NumEvents>0) {
    1278       gettimeofday(&StopTime, NULL);
    1279       float RunTime = StopTime.tv_sec-StartTime.tv_sec + (StopTime.tv_usec-StartTime.tv_usec)*1e-6;
    1280       m->PrintMessage("Time for run %.2f seconds, trigger rate %.2f Hz.\n", RunTime, m->NumEvents/RunTime);
    1281       m->PrintMessage("Run size %llu MByte, data rate %.1f MByte/s.\n", RunSize/1024/1024, RunSize/1024.0/1024/RunTime);
     1252  if(!WriteError) {
     1253    m->PrintMessage("\rRun #%d (%s) %s, %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],(m->NumEvents == m->NumEventsRequested) ? "completed":"stopped",m->NumEvents);
     1254    m->SlowDataClass->NewEntry("Runinfo");
     1255    m->SlowDataClass->AddToEntry("%d %s %s %d",m->RunNumber,daq_runtype_str[m->daq_runtype],m->Source,m->NumEvents);
     1256  }
     1257  else m->PrintMessage("\rRun #%d (%s) aborted due to error after %d events\n",m->RunNumber,daq_runtype_str[m->daq_runtype],m->NumEvents);
     1258  if (m->NumEvents>0 && !WriteError) {
     1259    gettimeofday(&StopTime, NULL);
     1260    float RunTime = StopTime.tv_sec-StartTime.tv_sec + (StopTime.tv_usec-StartTime.tv_usec)*1e-6;
     1261    m->PrintMessage("Time for run %.2f seconds, trigger rate %.2f Hz.\n", RunTime, m->NumEvents/RunTime);
     1262    m->PrintMessage("Run size %llu MByte, data rate %.1f MByte/s.\n", RunSize/1024/1024, RunSize/1024.0/1024/RunTime);
    12821263  }
    12831264  m->daq_state = stopped;
  • drsdaq/DAQReadout.h

    r27 r36  
    1818#include "HVFeedback.h"
    1919
     20#define RUN_NUM_FILE "/ct3data/LastRunNumber"
    2021#define MAX_PATH 256            // also used for filename length
    2122#define MAX_COM_SIZE 10000
     
    3536    unsigned int CmdNumber;
    3637    FILE *Logfile;   
     38    bool CmdFromSocket;         // Current command issued via socket
    3739    void PrintUsage();
    38        
     40    bool CalibrationRead;
     41       
    3942  public:
    4043    RunHeader*   RHeader;
     
    4346    short (*WaveForm)[kNumberOfChips][kNumberOfChannels][kNumberOfBins];
    4447    pthread_mutex_t control_mutex;
    45     FILE *Rawfile;
     48    int Rawfile;
    4649    class HVFeedback* HVFB;
     50    class SlowData *SlowDataClass;
    4751
    4852    // Configuration data
     
    6266    int NParam;                 // Number of parameters
    6367    const char *Param[MAX_NUM_TOKEN]; // Pointers to parameters
    64     bool CmdFromSocket;         // Current command issued via socket
    6568    int NumCMCBoards;
    6669    int FirstBoard;
     
    7679    unsigned int NumEvents;             // Number of event taken           
    7780    unsigned int NumEventsRequested;    // Number of events requested
    78     unsigned int RunNumber;
     81    unsigned int RunNumber, FileNumber;
    7982    char Source[32];
    8083    char FileName[MAX_PATH];
     
    106109    void StopDRS();
    107110    void StopRun();
    108     bool IsDAQBusy();
    109111    bool IsDRSBusy();
    110112    bool IsDRSFreqSet();
    111     void SetDRSFrequency(double);
    112     void SetRegulatedDRSFrequency(double);
    113     double ReadDRSFrequency();
     113    void SetDRSFrequency(double, bool);
    114114    void CalibrateDRS(char*, double, double);
    115115    void SetDOMINOMode(int);
     
    121121    bool IsCalibrationRead();
    122122    void ReadCalibratedDRSData();
    123     void ReadandPrintDRSData(int, int, int);
    124123    void PrintMessage(int, const char*, ...);
    125124    void PrintMessage(const char*, ...);
    126125    void PrintMessage(int, const char*, va_list);
    127     bool OpenRawFile(int);
    128     void WriteRunHeader();
    129     void UpdateRunHeader(unsigned int);
    130     void WriteEventHeader();
     126    bool OpenRawFile();
     127    bool WriteRunHeader();
     128    bool UpdateRunHeader(unsigned int, bool);
     129    bool WriteEventHeader();
    131130};
    132131
  • drsdaq/HVFeedback.cc

    r27 r36  
    1717
    1818#define MAX_RETRY 5
    19 
     19#define PIXMAP_LOCATION "../config/PixelMap.txt"
     20
     21//
    2022// Constructor: Initialise feedback
     23//
    2124HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) {
    2225  struct sockaddr_in SocketAddress;
    23  
     26  char Filename[MAX_PATH];
     27
    2428  m = DAQClass;
    25   PixMap = new PixelMap("../config/PixelMap.txt", false);
    26  
     29  PixMap = new PixelMap(PIXMAP_LOCATION, false);
     30
     31  snprintf(Filename,sizeof(Filename),"%s/SlowData/", m->fRawDataPath);
     32  SlowDataClass = new SlowData(m, "HVFB", Filename);
     33
    2734  // Read configuration file
    2835  FILE *File;
     
    3239  else {
    3340    printf("Reading feedback configuration file %s\n", Configfile);
    34     ReadCard("LedTrigBoard",       &fLedTrigBoard,      'I', File);
    35     ReadCard("LedTrigChannel",     &fLedTrigChannel,    'I', File);
    36     ReadCard("LedTrigChip",        &fLedTrigChip,       'I', File);
    37     ReadCard("LedTrigSample",      &fLedTrigSample,     'I', File);
    38     ReadCard("LedTrigThreshold",   &fLedTrigThreshold,  'f', File);
    39     ReadCard("LedSignalSample",    &fLedSignalSample,   'I', File);
    40     ReadCard("LedBaselineSample",  &fLedBaselineSample, 'I', File);
    41     ReadCard("DefaultNumAverage",  &fDefaultNumAverage, 'I', File);
    42     ReadCard("HVControlServer",     fHVControlServer,   's', File);
    43     ReadCard("HVControlPort",      &fHVControlPort,     'I', File);
    44     ReadCard("MaxCmdAckDelay",     &fMaxCmdAckDelay,    'I', File);
     41    ReadCard("TrigBoard",           &fLedTrigBoard,      'I', File);
     42    ReadCard("TrigChannel",         &fLedTrigChannel,    'I', File);
     43    ReadCard("TrigChip",            &fLedTrigChip,       'I', File);
     44    ReadCard("TrigSample",          &fLedTrigSample,     'I', File);
     45    ReadCard("TrigThreshold",       &fLedTrigThreshold,  'f', File);
     46    ReadCard("SignalSample",        &fLedSignalSample,   'I', File);
     47    ReadCard("BaselineSample",      &fLedBaselineSample, 'I', File);
     48    ReadCard("IntHalfWidth",        &fIntHalfWidth,      'U', File);
     49    ReadCard("DefaultNumAverage",   &fDefaultNumAverage, 'I', File);
     50    ReadCard("HVControlServer",      fHVControlServer,   's', File);
     51    ReadCard("HVControlPort",       &fHVControlPort,     'I', File);
     52    ReadCard("MaxCmdAckDelay",      &fMaxCmdAckDelay,    'I', File);
    4553    fclose(File);
    4654  }
     
    4856
    4957  // Initialise
    50   Average    = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels];
    51   Response   = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels];
    52   Target     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels];
    53   Buffer     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]; 
    54  
     58  Average    = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     59  Sigma      = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     60  Response   = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     61  Target     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     62  Buffer     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 
     63
     64/*   for (int i=m->FirstBoard; i<=m->LastBoard; i++)
     65    for (int j=0; j<kNumberOfChips; j++)
     66      for (int k=0; k<kNumberOfChannels; k++) {
     67        Response[i][j][k] = 0.0;
     68        Target[i][j][k] = 0.0;
     69      }
     70 */
    5571  Gain = 1;
    5672  SetFBMode(FB_Off);
     
    7793}
    7894
     95//
    7996// Destructor
     97//
    8098HVFeedback::~HVFeedback() {
    8199  if (SocketDescriptor!=-1) {
     
    85103  delete[] Average;     delete[] Response;
    86104  delete[] Target;      delete[] Buffer;
    87   delete PixMap;
    88 }
    89 
    90 
     105  delete SlowDataClass; delete PixMap;
     106}
     107
     108//
    91109// Check if LED trigger present, if yes accumulate feedback data and
    92110// calculate new high voltages if the required number of events is reached.
     111//
    93112bool HVFeedback::ProcessEvent() {
    94   float Correction;
     113  int i,j,k,q;
     114  float Correction, Integral, Difference, EffectiveGain;
    95115 
    96116  // Check for LED trigger channel on given channel and if feedback running
    97117  if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][fLedTrigSample] < fLedTrigThreshold)
    98118    return false;
    99   Count++;
    100119 
    101   // Add signal at LED bin for all channels
    102   for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    103     for (int j=0; j<kNumberOfChips; j++)
    104       for (int k=0; k<kNumberOfChannels; k++)
    105         Average[i][j][k] += (m->WaveForm[i][j][k][fLedSignalSample] - m->WaveForm[i][j][k][fLedBaselineSample])*m->BStruct[i].ScaleFactor;
    106  
     120  // Calculate average signal of LED pulse as integral of signal
     121  for (i=m->FirstBoard; i<=m->LastBoard; i++)
     122    for (j=0; j<kNumberOfChips; j++)
     123      for (k=0; k<kNumberOfChannels; k++) {
     124        for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++)
     125          Integral += (m->WaveForm[i][j][k][fLedSignalSample+q] - m->WaveForm[i][j][k][fLedBaselineSample+q])*m->BStruct[i].ScaleFactor;
     126        Integral /= 2*fIntHalfWidth+1;
     127        Average[i][j][k] += Integral;
     128        Sigma[i][j][k] += pow(Integral,2);
     129      }
     130
     131  if (++Count<NumAverages) return false;
     132
    107133  // Acquired number of event requires action
    108   if (Count==NumAverages) {
    109     for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    110       for (int j=0; j<kNumberOfChips; j++)
    111         for (int k=0; k<kNumberOfChannels; k++) {
    112           Average[i][j][k] /= Count;
    113           switch (FBMode) {
    114             case FB_Active:   // Determine correction from response maxtrix and change voltages
    115               Correction = (Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain;
    116               if(Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty())
    117                 WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction);
    118               break;
    119             case FB_Targets:  // Take average as new targets 
    120               Target[i][j][k] = Average[i][j][k];
    121               break;
    122             case FB_ResponseFirst:  // First point of response measurement done 
    123               Buffer[i][j][k] = Average[i][j][k];
    124               if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), Voltage2);
    125               break;
    126             case FB_ResponseSecond: // Determine response from signal variation
    127               if(Buffer[i][j][k] == Average[i][j][k]) {
    128                 m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k);
    129                 Response[i][j][k] = 0;
    130               }
    131               else Response[i][j][k] = Voltage2/(Buffer[i][j][k]-Average[i][j][k]);
    132               break;
    133             default: break;  // to suppress warning abount not handled enumeration value
    134           }                     
    135         }
    136     switch (FBMode) {
    137       case FB_Active:
    138         m->PrintMessage("HV Feedback: Acted.\n");
    139         break;
    140       case FB_Targets:
    141         m->PrintMessage("HV Feedback: New targets set, switching off.\n");
    142         FBMode = FB_Off;
    143         break;
    144       case FB_ResponseFirst:
    145         FBMode = FB_ResponseSecond;
    146         m->PrintMessage("HV Feedback: Setting second voltage %f for response measurement, acquiring data.\n", Voltage2);
    147         break;
    148       case FB_ResponseSecond:
    149         m->PrintMessage("HV Feedback: Response measurements finished, switching off.\n");
    150         FBMode = FB_Off;
    151         break;
    152       default: break;  // to suppress warning abount not handled enumeration value
    153     }                   
    154     ClearAverages();
    155     return true;
    156   }
    157   else return false;   
    158 }
    159 
     134  switch (FBMode) {
     135    case FB_Active: SlowDataClass->NewEntry("Average");  break;
     136    case FB_Targets: SlowDataClass->NewEntry("Target");  break;
     137    case FB_ResponseSecond: SlowDataClass->NewEntry("Response"); SlowDataClass->AddToEntry("%.3f ",DiffVoltage);  break;
     138    default: break;  // to suppress warning abount not handled enumeration value
     139  }                     
     140
     141  for (i=m->FirstBoard; i<=m->LastBoard; i++)
     142    for (j=0; j<kNumberOfChips; j++)
     143      for (k=0; k<kNumberOfChannels; k++) {
     144        Average[i][j][k] /= Count;
     145        Sigma[i][j][k] = sqrt(Sigma[i][j][k]/Count-pow(Average[i][j][k],2))/sqrt(Count);
     146        switch (FBMode) {
     147          case FB_Active:   // Determine correction from response maxtrix and change voltages
     148            Difference = Target[i][j][k] - Average[i][j][k];
     149            EffectiveGain = Gain*pow(0.5*(1+(Difference/Sigma[i][j][k]-1)/(Difference/Sigma[i][j][k]+1)),2);
     150            Correction = -Difference*Response[i][j][k]*EffectiveGain;
     151            if(Correction!=0 && Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty()) {
     152              printf("Average of board %d, chip %d, channel %d is %.2f +/- %.2f    Correction %.3f\n",i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
     153              SlowDataClass->AddToEntry("%d %d %d %.3f %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
     154              if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n");
     155              else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction);
     156            }
     157            break;
     158          case FB_Targets:  // Take average as new targets 
     159            Target[i][j][k] = Average[i][j][k];
     160            SlowDataClass->AddToEntry("%d %d %d %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k]);
     161            break;
     162          case FB_ResponseFirst:  // First point of response measurement done 
     163            Buffer[i][j][k] = Average[i][j][k];
     164            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage);
     165            break;
     166          case FB_ResponseSecond: // Determine response from signal variation
     167            if(Buffer[i][j][k] == Average[i][j][k]) {
     168              m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k);
     169              Response[i][j][k] = 0;
     170            }
     171            else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]);
     172            SlowDataClass->AddToEntry("%d %d %d %.3f ", i,j,k,Response[i][j][k]);
     173            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2);
     174            break;
     175          default: break;  // to suppress warning abount not handled enumeration value
     176        }                       
     177      }
     178
     179  switch (FBMode) {
     180    case FB_Targets:
     181      m->PrintMessage("HV Feedback: New targets set, switching off.\n");
     182      FBMode = FB_Off;
     183      break;
     184    case FB_ResponseFirst:
     185      FBMode = FB_ResponseSecond;
     186      m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data.\n", DiffVoltage);
     187      break;
     188    case FB_ResponseSecond:
     189      m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off.\n");
     190      FBMode = FB_Off;
     191      break;
     192    default: break;  // to suppress warning abount not handled enumeration value
     193  }
     194  ClearAverages();
     195  return true; 
     196}
     197
     198//
    160199// Clear average values and event counter
     200//
    161201void HVFeedback::ClearAverages() {
    162202  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    163203    for (int j=0; j<kNumberOfChips; j++)
    164       for (int k=0; k<kNumberOfChannels; k++) Average[i][j][k] = 0;
     204      for (int k=0; k<kNumberOfChannels; k++) {
     205        Average[i][j][k] = 0.0;
     206        Sigma[i][j][k] = 0.0;
     207      }
    165208  Count = 0;
    166209}
    167210
     211//
    168212// Number of events to accumulate before correction acts
     213//
    169214void HVFeedback::SetNumAverages(unsigned int Averages) {
    170215  NumAverages = Averages;
    171216}
    172217
     218//
    173219// Get requested number of events
     220//
    174221unsigned int HVFeedback::GetNumAverages() {
    175222  return NumAverages;
    176223}
    177224
     225//
    178226// Set feedback gain
     227//
    179228void HVFeedback::SetGain(float FBGain) {
    180229  Gain = FBGain;
    181230}
    182231
     232//
    183233// Get feedback gain
     234//
    184235float HVFeedback::GetGain() {
    185236  return Gain;
    186237}
    187238
     239//
    188240// Set feedback mode and clear averages
     241//
    189242void HVFeedback::SetFBMode(FBState Mode) {
    190243  if(Mode==FB_ResponseFirst || Mode==FB_ResponseFirst)
     
    196249}
    197250
     251//
    198252// Set feedback mode and clear averages
     253//
    199254FBState HVFeedback::GetFBMode() {
    200255  switch (FBMode) {
     
    208263}
    209264
     265//
    210266// Return current number of events
     267//
    211268unsigned int HVFeedback::GetCurrentCount() {
    212269  return Count;
    213270}
    214271
     272//
    215273// Set target values
     274//
    216275void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) {
    217276  if(Board<m->NumCMCBoards && Chip<kNumberOfChips && Channel<kNumberOfChannels)
     
    220279}
    221280
     281//
    222282// Print target values
     283//
    223284void HVFeedback::GetTargets() {
    224285  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
     
    228289}
    229290
     291//
    230292// Measure response matrix
    231 void HVFeedback::MeasureResponse(float U1, float U2) {
    232 
    233   if (U2 == 0)
    234     m->PrintMessage("HV Feedback: Error, econd voltage must not be zero.\n");
     293//
     294void HVFeedback::MeasureResponse(float U) {
     295
     296  if (U==0) m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n");
    235297  else {
    236298    for (int i=m->FirstBoard; i<=m->LastBoard; i++)
     
    238300        for (int k=0; k<kNumberOfChannels-2; k++) {
    239301          if(PixMap->DRS_to_Pixel(i,j,k).empty()) m->PrintMessage("Could not find pixel ID of board %d, chip %d, channel %d\n",i,j,k);
    240           else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), U1);
     302          else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2);
    241303        }
    242     Voltage1 = U1;   Voltage2 = U2;
     304    DiffVoltage = U;
    243305    FBMode = FB_ResponseFirst;
    244306    ClearAverages(); 
    245     m->PrintMessage("HV Feedback: Setting first voltage  %f for response measurement, acquiring data.\n",U1);
    246   }
    247 }
    248 
     307    m->PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2);
     308  }
     309}
     310
     311//
    249312// Print response values
     313//
    250314void HVFeedback::GetResponse() {
    251315  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    252316    for (int j=0; j<kNumberOfChips; j++)
    253317      for (int k=0; k<kNumberOfChannels; k++)
    254          m->PrintMessage("Board %d, chip %d, channel %d: %f\n",i,j,k,Response[i][j][k]);
    255 }
    256 
     318         m->PrintMessage("Board %d, chip %d, channel %d: %.3f\n",i,j,k,Response[i][j][k]);
     319}
     320
     321//
    257322// Write commmand to socket
     323//
    258324bool HVFeedback::WriteHVCommand(const char *Format, ...) {
    259325  char Textbuffer[MAX_COM_SIZE];
     
    263329  do {
    264330    va_list ArgumentPointer;  va_start(ArgumentPointer, Format);
    265     vsprintf(Textbuffer, Format, ArgumentPointer);
    266 
    267     printf("%s", Textbuffer);
     331    vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
     332
    268333    // Write command to socket
    269334    if(write(SocketDescriptor, Textbuffer, strlen(Textbuffer)+1)!=(int) strlen(Textbuffer)+1) {
     
    295360}
    296361
     362//
    297363// Print feedback configuration
     364//
    298365void HVFeedback::PrintConfig() {
    299366  m->PrintMessage("LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
    300367        "LedTrigSample: %d\tLedTrigThreshold: %.2f\n"
    301368        "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n"
    302         "HVControlServer: %s\tHVControlPort: %d\n"
     369        "IntHalfWidth:%u\tHVControlServer: %s\tHVControlPort: %d\n"
    303370        "MaxCmdAckDelay: %d\n",
    304371    fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample,
    305372    fLedTrigThreshold, fLedSignalSample, fLedBaselineSample,
    306     fDefaultNumAverage, fHVControlServer, fHVControlPort, fMaxCmdAckDelay);
    307 }
     373    fDefaultNumAverage, fIntHalfWidth, fHVControlServer, fHVControlPort, fMaxCmdAckDelay);
     374}
  • drsdaq/HVFeedback.h

    r27 r36  
    88#include "RawDataCTX.h"
    99#include "DAQReadout.h"
     10#include "SlowData.h"
    1011
    1112enum FBState {FB_Off, FB_Active, FB_Targets, FB_ResponseFirst, FB_ResponseSecond};
     
    1415
    1516    class DAQReadout *m;
    16     class PixelMap *PixMap;   
     17    class PixelMap *PixMap;
     18    class SlowData *SlowDataClass;   
    1719    FBState FBMode;
    1820   
    1921    float (*Average)[kNumberOfChips][kNumberOfChannels];
     22    float (*Sigma)[kNumberOfChips][kNumberOfChannels];
    2023    float (*Response)[kNumberOfChips][kNumberOfChannels];
    2124    float (*Target)[kNumberOfChips][kNumberOfChannels];
     
    2629   
    2730    float Gain;                 // Feedback gain
    28     float Voltage1, Voltage2;   // for response measurement     
     31    float DiffVoltage;          // for response measurement     
    2932    int SocketDescriptor;
    3033    char TextBuf[BUF_LENGTH];
     
    3740    int fLedSignalSample;
    3841    int fLedBaselineSample;
     42    unsigned int fIntHalfWidth;
    3943    int fDefaultNumAverage;
    4044    char fHVControlServer[BUF_LENGTH];
    4145    int fHVControlPort;
    4246    int fMaxCmdAckDelay;
    43                  
     47
    4448  public:
    4549    HVFeedback(class DAQReadout*, char*);
     
    5660    FBState GetFBMode();
    5761    unsigned int GetCurrentCount();
    58     void MeasureResponse(float, float);
     62    void MeasureResponse(float);
    5963    void GetResponse();
    6064    void ClearAverages();
  • drsdaq/History.txt

    r31 r36  
    13132/4/2009    Intoduced check for magic number in RawDataCTX.cc
    14143/4/2009    Added frequency and scale factor transmission to socket protocol
     156/4/2009    Allowed reading of data via read command also while DAQ is active.
     1622/4/2009   Included sizes of RunHeader, EventHeader and BoardStructure in
     17            RunHeader and changed some data widths in RunHeader to U32 to
     18            increase compatibility with Magic raw data format. Unique run
     19            numbers are now generated using the file LastRunNumber.
     2028/4/2009   Raw file writing uses now writev() and is changed entirely to
     21            Linux system calls instead of C++ library functions. Introduced
     22            new magic number that indicates an error while writing. More
     23            extensive error checking for I/O functions. Requesting zero events
     24            will let run go until stopped manually. Feedback writes slow data.
     2529/4/2009   DAQ writes run summary to slow data file.
  • drsdaq/Makefile

    r22 r36  
    88VMECTRL = -DCT_VME
    99
    10 #CC     = g++           # Compiler to use
     10CC      = g++           # Compiler to use
    1111
    12 SOURCES = HVFeedback.cc DAQReadout.cc RawDataCTX.cc ../pixelmap/Pixel.cc ../pixelmap/PixelMap.cc DRS/DRS.cc DRS/mxml.c DRS/strlcpy.c drsdaq.cpp
     12SOURCES = HVFeedback.cc DAQReadout.cc RawDataCTX.cc SlowData.cc ../pixelmap/Pixel.cc ../pixelmap/PixelMap.cc DRS/DRS.cc DRS/mxml.c DRS/strlcpy.c drsdaq.cpp
    1313OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
    1414
    15 SOBJECTS = RawDataCTX
    1615INCDIRS   = -I. -IDRS -I../pixelmap
    1716
     
    3130drsdaq: $(OBJECTS)
    3231        $(CC) $(CPPFLAGS) -o $@ $(OBJECTS) $(LIBS)
    33         $(CC) -shared -Wl,-soname,$(SOBJECTS).so -o $(SOBJECTS).so $(SOBJECTS).o -lc
    3432
    3533clean:
    36         @rm -f $(OBJECTS) $(SOBJECTS).so
     34        @rm -f $(OBJECTS)
    3735        @rm -f *.d
    3836        @rm -f *~
  • drsdaq/RawDataCTX.cc

    r28 r36  
    4343  }
    4444  // Check magic number of run header
    45   if (RHeader->MagicNum!=MAGICNUM_FILE_OPEN && RHeader->MagicNum!=MAGICNUM_FILE_CLOSED) {
     45  if (RHeader->MagicNum!=MAGICNUM_OPEN && RHeader->MagicNum!=MAGICNUM_CLOSED && RHeader->MagicNum!=MAGICNUM_ERROR) {
    4646    if(!Silent) printf("Error: Magic number of run header incorrect\n");
    4747    fclose(Rawfile);
     
    6262  // If requested, print run header (including board structures) to file
    6363  if(fptr != NULL) {
    64     int RAhour, RAmin, RAsec, DEChour, DECmin, DECsec;
    65 
    66     fprintf(fptr, "Magic number      %x\n", RHeader->MagicNum);
    67     fprintf(fptr, "Data format:      %d\n", RHeader->DataFormat);
     64    fprintf(fptr, "Magic number          %x (%s)\n", RHeader->MagicNum, RHeader->MagicNum==MAGICNUM_CLOSED?"OK":(RHeader->MagicNum==MAGICNUM_OPEN?"File not closed":"Error"));
     65    fprintf(fptr, "Data format:          %d\n", RHeader->DataFormat);
     66    fprintf(fptr, "Run header size:      %d\n", RHeader->RunHeaderSize);
     67    fprintf(fptr, "Event header size:    %d\n", RHeader->EventHeaderSize);
     68    fprintf(fptr, "Board structure size: %d\n", RHeader->BoardStructureSize);
     69   
    6870    fprintf(fptr, "DAQ compilation:  %s\n", RHeader->DAQVersion);         
    6971    fprintf(fptr, "Source:           %s\n", RHeader->Source);
    7072    fprintf(fptr, "Run type:         %c\n", RHeader->Type);
    7173    fprintf(fptr, "Run number:       %u\n", RHeader->RunNumber);
     74    fprintf(fptr, "File number:      %u\n", RHeader->FileNumber);
    7275    fprintf(fptr, "Events:           %u\n", RHeader->Events);
    7376    fprintf(fptr, "CMC Boards:       %u\n", RHeader->NCMCBoards);
     
    7780    fprintf(fptr, "Offset:           %d\n", RHeader->Offset);
    7881
    79     RAsec   = (int) (RHeader->SourceRA)%60;
    80     RAmin   = (int) (RHeader->SourceRA/60)%60;
    81     RAhour  = (int) (RHeader->SourceRA/3600);
    82     DECsec  = (int) (RHeader->SourceDEC)%60;
    83     DECmin  = (int) (RHeader->SourceDEC/60)%60;
    84     DEChour = (int) (RHeader->SourceDEC/3600);
    85 
    86     fprintf(fptr, "Source RA:        %f (%d %d %d)\n", RHeader->SourceRA, RAhour, RAmin, RAsec);
    87     fprintf(fptr, "Source DEC:       %f (%d %d %d)\n", RHeader->SourceDEC, DEChour, DECmin, DECsec);
    88 
    89     RAsec   = (int) (RHeader->TelescopeRA)%60;
    90     RAmin   = (int) (RHeader->TelescopeRA/60)%60;
    91     RAhour  = (int) (RHeader->TelescopeRA/3600);
    92     DECsec  = (int) (RHeader->TelescopeDEC)%60;
    93     DECmin  = (int) (RHeader->TelescopeDEC/60)%60;
    94     DEChour = (int) (RHeader->TelescopeDEC/3600);
    95 
    96     fprintf(fptr, "Telescope RA:     %f (%d %d %d)\n", RHeader->TelescopeRA, RAhour, RAmin, RAsec);
    97     fprintf(fptr, "Telescope DEC:    %f (%d %d %d)\n", RHeader->TelescopeDEC, DEChour, DECmin, DECsec);
     82    fprintf(fptr, "Source RA:        %f\n", RHeader->SourceRA);
     83    fprintf(fptr, "Source DEC:       %f\n", RHeader->SourceDEC);
     84    fprintf(fptr, "Telescope RA:     %f\n", RHeader->TelescopeRA);
     85    fprintf(fptr, "Telescope DEC:    %f\n", RHeader->TelescopeDEC);
    9886
    9987    fprintf(fptr, "Start year:       %u\n", RHeader->StartYear);
  • drsdaq/RawDataCTX.h

    r22 r36  
    2020#define DATA_FORMAT 1
    2121
    22 #define I8      char
    23 #define U8      unsigned char
    24 #define I16     short
    25 #define U16     unsigned short
    26 #define I32     int
    27 #define U32     unsigned int
    28 #define F32     float
     22typedef char I8;
     23typedef unsigned char U8;
     24typedef short I16;
     25typedef unsigned short U16;
     26typedef int I32;
     27typedef unsigned int U32;
     28typedef float F32;
    2929
    30 #define MAGICNUM_FILE_OPEN 0xe0e1    // Magic number for run header while file open
    31 #define MAGICNUM_FILE_CLOSED 0xe0e0  //    ... and when file is closed
     30#define MAGICNUM_OPEN 0xe0e1    // Magic number for run header while file open
     31#define MAGICNUM_CLOSED 0xe0e0  //    ... and when file is closed
     32#define MAGICNUM_ERROR 0xe0e2   //    ... and when an error occurred
    3233
    3334// Error codes
     
    3940// Run header
    4041typedef struct {
    41   U16 MagicNum;
    42   U16 DataFormat;       // Increasing whenever header format changes
     42  U32 MagicNum;
     43  U32 DataFormat;       // Increasing whenever header format changes
     44
     45  U32 RunHeaderSize;
     46  U32 EventHeaderSize;
     47  U32 BoardStructureSize;
     48
    4349  I8  DAQVersion[12];   // contains result of __DATE__ macro
     50
    4451  I8  Source[16];
    4552  I8  Type;          // run type (char): pedestal, data, ...
     53
    4654  U32 RunNumber;
     55  U32 FileNumber;
    4756 
    48   U16 StartYear;
    49   U8 StartMonth;
    50   U8 StartDay;
    51   U8 StartHour;
    52   U8 StartMinute;
    53   U8 StartSecond;
     57  U32 StartYear;
     58  U32 StartMonth;
     59  U32 StartDay;
     60  U32 StartHour;
     61  U32 StartMinute;
     62  U32 StartSecond;
    5463 
    55   U16 EndYear;
    56   U8 EndMonth;
    57   U8 EndDay;
    58   U8 EndHour;
    59   U8 EndMinute;
    60   U8 EndSecond;
     64  U32 EndYear;
     65  U32 EndMonth;
     66  U32 EndDay;
     67  U32 EndHour;
     68  U32 EndMinute;
     69  U32 EndSecond;
    6170
    6271  F32 SourceRA;
     
    6574  F32 TelescopeDEC;
    6675 
    67   U32 Events;                     // Number of events in the run
     76  U32 Events;                     // Number of events in the file
    6877  U32 NCMCBoards;                 // Number of used boards
    6978  U32 NChips;                     // Number of DRS chips per board
     
    7584// Board structure
    7685typedef struct {
    77   I32 Index;       // Index number (data written in this order)
    7886  I32 SerialNo;    // Board serial number
    7987  F32 NomFreq;     // Nominal sampling frequency [GHz]
  • drsdaq/drsdaq.cpp

    r22 r36  
    7575  signal(SIGTERM, &CrashHandler);
    7676  signal(SIGINT, &CrashHandler);
     77  signal(SIGHUP, &CrashHandler);
    7778   
    7879  // Construct main instance
Note: See TracChangeset for help on using the changeset viewer.