Changeset 10113


Ignore:
Timestamp:
01/21/11 15:46:15 (12 years ago)
Author:
ogrimm
Message:
Event thread informed through pipe of new incoming data
Location:
fact/FADctrl
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • fact/FADctrl/FAD.cc

    r10103 r10113  
    5959  EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str());
    6060
     61  // Create pipe for data exchange
     62  if (pipe(Pipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno));
     63
    6164  // DIM console service used in PrintMessage()
    6265  ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
     
    9598  int Ret;
    9699
     100  // Close pipe (will make read() on pipe in DIM service thread return)
     101  if (close(Pipe[0]) == -1) Message(ERROR, "close() on Pipe[0] failed in FAD::~FAD() (%s)", strerror(errno));;
     102  if (close(Pipe[1]) == -1) Message(ERROR, "close() on Pipe[1] failed in FAD::~FAD() (%s)", strerror(errno));;
     103
    97104  // Wait for DIM service thread to quit
    98105  if (pthread_equal(Thread, pthread_self()) == 0) {
     
    105112  delete Command;
    106113  delete ConsoleOut;
    107   free(ConsoleText);
     114  free(ConsoleText); 
    108115}
    109116
     
    186193
    187194//
    188 // Switch which sockets are used to send data away
    189 // case parameter is: "com" - command mode is enabled.
    190 //      thus only socket 0 is used
    191 // case parameter is: "daq" - daq mode is enabled
    192 //      thus only sockets 1 - 7 are used.
     195// Switch socket mode
     196// "com" - command mode (only socket 0 is used)
     197// "daq" - daq mode (only sockets 1 - 7 are used)
    193198//
    194 //      note: socket 0 is always used to issue commands
     199//      Note that socket 0 is always used to issue commands
    195200//
    196201void FAD::cmd_socketmode() {
     
    275280        }
    276281  }
    277     if (Match(Parameter[1],"enable")) PrintMessage("all active boards accept now incoming triggers\n");
     282
     283  if (Match(Parameter[1],"enable")) PrintMessage("all active boards accept now incoming triggers\n");
    278284  else if (Match(Parameter[1],"disable")) PrintMessage("no active board accepts any incoming trigger anymore.\n");
    279285 // else PrintUsage();
     
    485491               
    486492                // Check if correct number of items
    487                 if (Items.size() != NChips*NChannels*NBins*2 + 3) {
     493                if (Items.size() != NChips*NChannels*NBins*3 + 3) {
    488494                  PrintMessage("Error, data format invalid\n", Parameter[1].c_str());
    489495                  return;
     
    500506                          Boards[Brd]->Baseline[i][j][k] = atoi(Items[Count++].c_str());
    501507                          Boards[Brd]->Gain[i][j][k] = atof(Items[Count++].c_str());
     508                          Boards[Brd]->SecondaryBaseline[i][j][k] = atof(Items[Count++].c_str());
    502509                        }
    503510                  }
     
    571578
    572579        PrintMessage("Board #%d - %s (%sactive)    Communication %s\n", i, Boards[i]->Name, Boards[i]->Active ? "":"in", Boards[i]->CommError ? "ERROR":"OK");
     580        PrintMessage("Board ID %d               Firmware revision %d\n", S.BoardID, S.FirmwareRevision);
    573581        PrintMessage("DAC %d %d %d %d   %d %d %d %d\n", S.DAC[0], S.DAC[1], S.DAC[2], S.DAC[3], S.DAC[4], S.DAC[5], S.DAC[6], S.DAC[7] );
    574582        PrintMessage("Temperature %.2f %.2f %.2f %.2f", S.Temp[0], S.Temp[1], S.Temp[2], S.Temp[3]);
     
    585593                    GetBoard(i)->GetBoardSerialNumber(),
    586594                    GetBoard(i)->GetFirmwareVersion(),
    587                     GetBoard(i)->GetTemperature(),
    588595                    ACalibTemp[i]);
    589596
     
    660667          break;
    661668        }
    662     else PrintMessage("%-28s%s\n", Buffer, CommandList[i].Help);
     669    else {
     670        if (strlen(Buffer) < 25) PrintMessage("%-25s%s\n", Buffer, CommandList[i].Help);
     671        else PrintMessage("%s\n%-25s%s\n", Buffer, "", CommandList[i].Help);
     672        }
    663673        free(Buffer);
    664674  }
     
    704714  unsigned short DACCmd[] = {htons(CMD_Write | (BADDR_DAC + 1)), 0, htons(CMD_Write | (BADDR_DAC + 2)), 0, htons(CMD_Write | (BADDR_DAC + 3)), 0};
    705715
    706   /* Procedure
    707 
    708   5. Issue single trigger and verify settings
    709   ...
    710   11. Secondary calibration
    711 */
    712 
    713716  PrintMessage("Staring amplitude calibration of all active boards (%d events)\n"
    714717                           "   Note: No input signals must be connected\n", NumCalibEvents);
     
    720723  }
    721724
    722   // Initialise settings for calibration
     725  // ====== Part A: Baseline measurement =====
     726
     727  // Initialise settings for baseline measurement
    723728  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
    724729
     
    729734        Status.push_back(Boards[Brd]->GetStatus());
    730735       
    731         // Disarm first, in order to change ROI & DAC settings
    732         //Boards[Brd]->Send(CMD_TRIGGERS_OFF);
    733 
    734736    // Set all ROI to 1024
    735737        Boards[Brd]->Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short));
    736738
    737     // Set first DAC value
     739    // Set DAC values and start accumulation
    738740    DACCmd[1] = htons(0);
    739741    DACCmd[3] = htons(0);
     
    741743        Boards[Brd]->Send(DACCmd, sizeof(DACCmd));
    742744
    743         // Switch off SCLK
    744         //Boards[Brd]->Send(CMD_SCLK_OFF);
    745 
    746         // Arm again, in order to take data
    747         //Boards[Brd]->Send(CMD_TRIGGERS_ON);
    748 
    749 
    750         // Start accumulation
    751     Boards[Brd]->AccumulateSum(NumCalibEvents);
     745    Boards[Brd]->AccumulateSum(NumCalibEvents, true);   
    752746  }
    753747
     
    762756  }
    763757
     758  // Determine baseline
    764759  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
    765         // Determine baseline
    766760        for (unsigned int i=0; i<NChips; i++) for (unsigned int j=0; j<NChannels; j++) {
    767761          for (unsigned int k=0; k<NBins; k++) {
     
    769763          }
    770764        }
    771 
    772         // Switch on SCLK
    773         Boards[Brd]->Send(CMD_SCLK_ON);
    774 
    775         // Disarm first, in order to change ROI & DAC settings
    776         //Boards[Brd]->Send(CMD_TRIGGERS_OFF);
    777 
    778         // Set second DAC value
     765  }
     766  PrintMessage("Baseline measurement finished, next is gain measurement\n");
     767
     768  // ====== Part B: Gain measurement =====
     769
     770  // Set new DAC values and start accumulation
     771  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
    779772        DACCmd[1] = htons(50000);
    780773        DACCmd[3] = htons(50000);
     
    782775        Boards[Brd]->Send(DACCmd, sizeof(DACCmd));
    783776
    784         // Switch off SCLK
    785         //Boards[Brd]->Send(CMD_SCLK_OFF);
    786 
    787         // Arm again
    788         //Boards[Brd]->Send(CMD_TRIGGERS_ON);
    789 
    790         // Start accumulation
    791     Boards[Brd]->AccumulateSum(NumCalibEvents);
     777    Boards[Brd]->AccumulateSum(NumCalibEvents, true);   
    792778  }
    793779
     
    801787        }
    802788  }
    803 
    804   // Stop triggering, write back original ROI and DAC settings
     789 
     790  // Determine gain
    805791  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
    806         // Switch on SCLK
    807         Boards[Brd]->Send(CMD_SCLK_ON);
     792        for (unsigned int i=0; i<NChips; i++) for (unsigned int j=0; j<NChannels; j++) {
     793          for (unsigned int k=0; k<NBins; k++) {
     794                Boards[Brd]->Gain[i][j][k] = (Boards[Brd]->Sum[i][j][k] / NumCalibEvents)-Boards[Brd]->Baseline[i][j][k];
     795          }
     796        }
     797  }
     798  PrintMessage("Gain measurement finished, next is secondary calibration\n");
     799
     800  // ====== Part C: Secondary calibration =====
     801
     802  // Initialise settings for secondary calibration and start accumulation
     803  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
     804    DACCmd[1] = htons(0);
     805    DACCmd[3] = htons(0);
     806    DACCmd[5] = htons(0);
     807        Boards[Brd]->Send(DACCmd, sizeof(DACCmd));
     808
     809    Boards[Brd]->AccumulateSum(NumCalibEvents, false); 
     810  }
     811
     812  // Wait until data for all boards taken
     813  Done = false;
     814  while (!Done && !Cancel) {
     815    usleep(300000);
     816        for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
     817          Done = true;
     818          if (Boards[Brd]->Active && Boards[Brd]->DoSum) Done = false;
     819        }
     820  }
     821
     822  // Determine secondary calibration
     823  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
     824        for (unsigned int i=0; i<NChips; i++) for (unsigned int j=0; j<NChannels; j++) {
     825          for (unsigned int k=0; k<NBins; k++) {
     826                Boards[Brd]->SecondaryBaseline[i][j][k] = Boards[Brd]->Sum[i][j][k] / (double) NumCalibEvents;
     827          }
     828        }
     829  }
     830
     831  // ===== Part D: Finish calibration =====
     832 
     833  // Write back original ROI and DAC settings
     834  for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
    808835
    809836        // Determine gain
     
    866893          for (unsigned int j=0; j<NChannels; j++) {
    867894                for (unsigned int k=0; k<NBins; k++) {
    868                   fprintf(File, "%d %lf ", Boards[Brd]->Baseline[i][j][k], Boards[Brd]->Gain[i][j][k]);
     895                  fprintf(File, "%d %lf %lf ", Boards[Brd]->Baseline[i][j][k], Boards[Brd]->Gain[i][j][k], Boards[Brd]->SecondaryBaseline[i][j][k]);
    869896                }
    870897          }
     
    894921  struct timeval Time;
    895922  struct timeval LastUpdate;
    896   bool Update;
    897923  struct FADBoard::BoardStatus S;
    898924  double Temp;
     925  string IDString;
     926  char Buffer[100];
     927  int Ret;
    899928
    900929  gettimeofday(&LastUpdate, NULL);
     
    943972  // Update loop
    944973  while (!ExitRequest) {
    945     usleep(EventUpdateDelay*1e6);
    946 
     974    // Wait for data from TCP/IP reading threads
     975    if ((Ret=read(Pipe[0], Buffer, sizeof(Buffer))) == -1) Message(FATAL, "read() from Pipe[0] failed in FAD::EventThread() (%s)", strerror(errno));
     976        IDString = string(Buffer, Ret);
     977       
    947978        // Update run and event header with current time
    948979        gettimeofday(&Time, NULL);     
     
    955986        EHeader->Microsecond = Time.tv_usec;
    956987
    957         // Check boards for new data since last update
    958         Update = false;
     988        // Check all boards that have new data
    959989        for (unsigned int Brd=0; Brd<Boards.size(); Brd++) {
     990          // Identify board
     991          if (IDString.find(Boards[Brd]->Name) == string::npos) continue;
     992
     993          // Fill M0 BoardStructure             
    960994          S = Boards[Brd]->GetStatus();
    961           if (S.Update.tv_sec>LastUpdate.tv_sec || ((S.Update.tv_sec==LastUpdate.tv_sec) && (S.Update.tv_usec>LastUpdate.tv_usec))) {
    962 
    963                 Update = true;
    964 
    965                 // Fill M0 BoardStructure               
    966                 BStruct[Brd]->SerialNo = S.BoardID;
    967                 BStruct[Brd]->NomFreq = 2;
    968                 BStruct[Brd]->BoardTemp = 0;       
    969                 for (unsigned int i=0; i<NTemp; i++) BStruct[Brd]->BoardTemp += S.Temp[i]/NTemp;
    970                 BStruct[Brd]->ScaleFactor = 1/2.048;     
    971 
    972                 // Update event header with ID and Type of current board
    973                 EHeader->EventNumber = S.TriggerID;
    974                 EHeader->TriggerType = S.TriggerType;
    975 
    976                 // Write trigger cells
    977                 for(unsigned int i=0; i<NChips; i++) TriggerCell[Brd*NChips+i] = (int) S.TriggerCell[i];
    978 
    979                 // Write channel data (stored in 12 bit signed twis complement with out-of-range-bit and leading zeroes)
    980                 int Count = 0;
    981                 memset(Data, 0, Boards.size()*NChips*NChannels*NBins*sizeof(short));
    982 
    983                 Boards[Brd]->Lock();
    984                 for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) {
    985                   for (int i=0; i<S.ROI[Chip][Chan]; i++) {
    986                         if (Boards[Brd]->ACalibTime == -1) Data[Count++] = Boards[Brd]->Data[Chip][Chan][i];
    987                         else {
    988                       Temp = (Boards[Brd]->Data[Chip][Chan][i] - Boards[Brd]->Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]);
    989                           Temp *= Boards[Brd]->Gain[Chip][Chan][0]/Boards[Brd]->Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
    990                           Data[Count++] = (short) Temp;
    991                         }
     995          BStruct[Brd]->SerialNo = S.BoardID;
     996          BStruct[Brd]->NomFreq = 2;
     997          BStruct[Brd]->BoardTemp = 0;       
     998          for (unsigned int i=0; i<NTemp; i++) BStruct[Brd]->BoardTemp += S.Temp[i]/NTemp;
     999          BStruct[Brd]->ScaleFactor = 1/2.048;     
     1000
     1001          // Update event header with ID and Type of current board
     1002          EHeader->EventNumber = S.TriggerID;
     1003          EHeader->TriggerType = S.TriggerType;
     1004
     1005          // Write trigger cells
     1006          for(unsigned int i=0; i<NChips; i++) TriggerCell[Brd*NChips+i] = (int) S.TriggerCell[i];
     1007
     1008          // Write channel data (stored in 12 bit signed twis complement with out-of-range-bit and leading zeroes)
     1009          int Count = 0;
     1010          memset(Data, 0, Boards.size()*NChips*NChannels*NBins*sizeof(short));
     1011
     1012          Boards[Brd]->Lock();
     1013          for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) {
     1014                for (int i=0; i<S.ROI[Chip][Chan]; i++) {
     1015                  if (Boards[Brd]->ACalibTime == -1) Data[Count++] = Boards[Brd]->Data[Chip][Chan][i];
     1016                  else {
     1017                    Temp = (Boards[Brd]->Data[Chip][Chan][i] - Boards[Brd]->Baseline[Chip][Chan][(i+S.TriggerCell[Chip])%NBins]);
     1018                        Temp *= Boards[Brd]->Gain[Chip][Chan][0]/Boards[Brd]->Gain[Chip][Chan][(i+S.TriggerCell[Chip])%NBins];
     1019                        //Temp -= Boards[Brd]->SecondaryBaseline[Chip][Chan][i];
     1020                        Data[Count++] = (short) Temp;
    9921021                  }
    993                   Count += NBins - S.ROI[Chip][Chan];
    9941022                }
    995                 Boards[Brd]->Unlock();
     1023                Count += NBins - S.ROI[Chip][Chan];
    9961024          }
    997         }
    998 
    999         if (Update) {
     1025          Boards[Brd]->Unlock();
     1026        }
     1027
     1028        // Check if DIM service should be updated
     1029        if ((Time.tv_sec-LastUpdate.tv_sec)*1e6 + Time.tv_usec-LastUpdate.tv_usec > EventUpdateDelay*1e6) {
    10001030          gettimeofday(&LastUpdate, NULL);
    10011031          EventService->updateService(EventData, EventSize);
  • fact/FADctrl/FAD.h

    r10103 r10113  
    6262    ~FAD();
    6363
    64                 void cmd_exit();                        void cmd_help();
    65                 void cmd_board();                       void cmd_status();
    66                 void cmd_acalib();              void cmd_serial();
    67                 void cmd_trigger();     void cmd_socketmode();
    68                 void cmd_srclk();                       void cmd_sclk();
    69                 void cmd_dwrite();              void cmd_domino();
    70                 void cmd_wmode();                       void cmd_rmode();
    71                 void cmd_dmode();                       void cmd_dac();
    72                 void cmd_roi();                         void cmd_address();
    73                 void cmd_phase();                       void cmd_send();
    74                 void cmd_cancel();              void cmd_update();
     64        void cmd_exit();                void cmd_help();
     65        void cmd_board();               void cmd_status();
     66        void cmd_acalib();              void cmd_serial();
     67        void cmd_trigger();     void cmd_socketmode();
     68        void cmd_srclk();               void cmd_sclk();
     69        void cmd_dwrite();              void cmd_domino();
     70        void cmd_wmode();               void cmd_rmode();
     71        void cmd_dmode();               void cmd_dac();
     72        void cmd_roi();                 void cmd_address();
     73        void cmd_phase();               void cmd_send();
     74        void cmd_cancel();              void cmd_update();
    7575
    7676    void EnableDomino();
     
    8282    bool ReadCalibration();
    8383    void PrintMessage(const char*, ...);
     84       
     85        int Pipe[2];
    8486};
    8587
  • fact/FADctrl/FADBoard.cc

    r10101 r10113  
    8989  int Ret;
    9090
    91   // Cancel thread and wait for it to quit
     91  // Cancel thread (if it did not quit already) and wait for it to quit
    9292  if (pthread_equal(Thread, pthread_self()) == 0) {
    93         if ((Ret = pthread_cancel(Thread)) != 0) m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
     93        if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
    9494        if ((Ret = pthread_join(Thread, NULL)) != 0) m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
    9595  }
     
    164164// Initiate average
    165165//
    166 void FADBoard::AccumulateSum(unsigned int n) {
     166void FADBoard::AccumulateSum(unsigned int n, bool Rotate) {
    167167
    168168  if (!Active) return;
    169169 
    170170  Lock();
     171  SumPhysPipeline = Rotate;
    171172  memset(Sum, 0, sizeof(Sum));
    172173  NumForSum = n;
     
    253254          // Extract ID and type information
    254255          Status.BoardID = ntohl(Header->board_id);
     256          Status.FirmwareRevision = ntohl(Header->version_no);
    255257          Status.TriggerID = ntohl(Header->local_trigger_id);
    256258          Status.TriggerType = ntohs(Header->local_trigger_type);
     
    287289                for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) {
    288290                  for (int i=0; i<Status.ROI[Chip][Chan]; i++) {
    289                         Sum[Chip][Chan][(i+Status.TriggerCell[Chip]) % NBins] += Data[Chip][Chan][i];
     291                        if (SumPhysPipeline) Sum[Chip][Chan][(i+Status.TriggerCell[Chip]) % NBins] += Data[Chip][Chan][i];
     292                        else Sum[Chip][Chan][i] = Data[Chip][Chan][i]-Baseline[Chip][Chan][(i-Status.TriggerCell[Chip]) % NBins];
    290293                  }
    291294                }
     
    312315        else printf("End package flag incorrect, removing corrupt event\n");
    313316
     317        // Inform event thread of new data
     318        if (write(m->Pipe[1], Name, strlen(Name)+1) == -1) {
     319          m->Message(m->ERROR, "write() to Pipe[1] failed in class FADBoard (%s)", strerror(errno));
     320          m->ExitRequest = true;
     321        }
     322
    314323        // Remove event data from internal buffer
    315324        memmove(Buffer, Buffer+Length, Pos-Length);
  • fact/FADctrl/FADBoard.h

    r10101 r10113  
    4242        struct BoardStatus {
    4343          unsigned short BoardID;
     44          unsigned short FirmwareRevision;
    4445          unsigned long TriggerID;
    4546          unsigned char TriggerType;
     
    5455        short Baseline[NChips][NChannels][NBins];
    5556        double Gain[NChips][NChannels][NBins];
     57        double SecondaryBaseline[NChips][NChannels][NBins];
    5658        float ACalibTemp;
    5759        time_t ACalibTime;
     
    6062        unsigned int NumForSum;
    6163        bool DoSum;
     64        bool SumPhysPipeline;
    6265
    6366        void Send(const void *, size_t);
    6467        void Send(unsigned short);
    6568        struct BoardStatus GetStatus();
    66         void AccumulateSum(unsigned int);
     69        void AccumulateSum(unsigned int, bool);
    6770        void Lock();
    6871        void Unlock();
  • fact/FADctrl/History.txt

    r10101 r10113  
    445/1/2011        First version of amplitude calibration (no secondary calibration, yet). New 'socketmode' command.
    5513/1/2011       Amplitude calibration data is written to text file.
     619/1/2011       Implemented secondary calibration.
     721/1/2011       DIM event thread now informed through pipe of new data
Note: See TracChangeset for help on using the changeset viewer.