Changeset 10113
- Timestamp:
- 01/21/11 15:46:15 (14 years ago)
- Location:
- fact/FADctrl
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/FADctrl/FAD.cc
r10103 r10113 59 59 EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str()); 60 60 61 // Create pipe for data exchange 62 if (pipe(Pipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno)); 63 61 64 // DIM console service used in PrintMessage() 62 65 ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) ""); … … 95 98 int Ret; 96 99 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 97 104 // Wait for DIM service thread to quit 98 105 if (pthread_equal(Thread, pthread_self()) == 0) { … … 105 112 delete Command; 106 113 delete ConsoleOut; 107 free(ConsoleText); 114 free(ConsoleText); 108 115 } 109 116 … … 186 193 187 194 // 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) 193 198 // 194 // note:socket 0 is always used to issue commands199 // Note that socket 0 is always used to issue commands 195 200 // 196 201 void FAD::cmd_socketmode() { … … 275 280 } 276 281 } 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"); 278 284 else if (Match(Parameter[1],"disable")) PrintMessage("no active board accepts any incoming trigger anymore.\n"); 279 285 // else PrintUsage(); … … 485 491 486 492 // Check if correct number of items 487 if (Items.size() != NChips*NChannels*NBins* 2+ 3) {493 if (Items.size() != NChips*NChannels*NBins*3 + 3) { 488 494 PrintMessage("Error, data format invalid\n", Parameter[1].c_str()); 489 495 return; … … 500 506 Boards[Brd]->Baseline[i][j][k] = atoi(Items[Count++].c_str()); 501 507 Boards[Brd]->Gain[i][j][k] = atof(Items[Count++].c_str()); 508 Boards[Brd]->SecondaryBaseline[i][j][k] = atof(Items[Count++].c_str()); 502 509 } 503 510 } … … 571 578 572 579 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); 573 581 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] ); 574 582 PrintMessage("Temperature %.2f %.2f %.2f %.2f", S.Temp[0], S.Temp[1], S.Temp[2], S.Temp[3]); … … 585 593 GetBoard(i)->GetBoardSerialNumber(), 586 594 GetBoard(i)->GetFirmwareVersion(), 587 GetBoard(i)->GetTemperature(),588 595 ACalibTemp[i]); 589 596 … … 660 667 break; 661 668 } 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 } 663 673 free(Buffer); 664 674 } … … 704 714 unsigned short DACCmd[] = {htons(CMD_Write | (BADDR_DAC + 1)), 0, htons(CMD_Write | (BADDR_DAC + 2)), 0, htons(CMD_Write | (BADDR_DAC + 3)), 0}; 705 715 706 /* Procedure707 708 5. Issue single trigger and verify settings709 ...710 11. Secondary calibration711 */712 713 716 PrintMessage("Staring amplitude calibration of all active boards (%d events)\n" 714 717 " Note: No input signals must be connected\n", NumCalibEvents); … … 720 723 } 721 724 722 // Initialise settings for calibration 725 // ====== Part A: Baseline measurement ===== 726 727 // Initialise settings for baseline measurement 723 728 for (unsigned int Brd=0; Brd<Boards.size(); Brd++) { 724 729 … … 729 734 Status.push_back(Boards[Brd]->GetStatus()); 730 735 731 // Disarm first, in order to change ROI & DAC settings732 //Boards[Brd]->Send(CMD_TRIGGERS_OFF);733 734 736 // Set all ROI to 1024 735 737 Boards[Brd]->Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short)); 736 738 737 // Set first DAC value739 // Set DAC values and start accumulation 738 740 DACCmd[1] = htons(0); 739 741 DACCmd[3] = htons(0); … … 741 743 Boards[Brd]->Send(DACCmd, sizeof(DACCmd)); 742 744 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); 752 746 } 753 747 … … 762 756 } 763 757 758 // Determine baseline 764 759 for (unsigned int Brd=0; Brd<Boards.size(); Brd++) { 765 // Determine baseline766 760 for (unsigned int i=0; i<NChips; i++) for (unsigned int j=0; j<NChannels; j++) { 767 761 for (unsigned int k=0; k<NBins; k++) { … … 769 763 } 770 764 } 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++) { 779 772 DACCmd[1] = htons(50000); 780 773 DACCmd[3] = htons(50000); … … 782 775 Boards[Brd]->Send(DACCmd, sizeof(DACCmd)); 783 776 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); 792 778 } 793 779 … … 801 787 } 802 788 } 803 804 // Stop triggering, write back original ROI and DAC settings789 790 // Determine gain 805 791 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++) { 808 835 809 836 // Determine gain … … 866 893 for (unsigned int j=0; j<NChannels; j++) { 867 894 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]); 869 896 } 870 897 } … … 894 921 struct timeval Time; 895 922 struct timeval LastUpdate; 896 bool Update;897 923 struct FADBoard::BoardStatus S; 898 924 double Temp; 925 string IDString; 926 char Buffer[100]; 927 int Ret; 899 928 900 929 gettimeofday(&LastUpdate, NULL); … … 943 972 // Update loop 944 973 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 947 978 // Update run and event header with current time 948 979 gettimeofday(&Time, NULL); … … 955 986 EHeader->Microsecond = Time.tv_usec; 956 987 957 // Check boards for new data since last update 958 Update = false; 988 // Check all boards that have new data 959 989 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 960 994 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; 992 1021 } 993 Count += NBins - S.ROI[Chip][Chan];994 1022 } 995 Boards[Brd]->Unlock();1023 Count += NBins - S.ROI[Chip][Chan]; 996 1024 } 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) { 1000 1030 gettimeofday(&LastUpdate, NULL); 1001 1031 EventService->updateService(EventData, EventSize); -
fact/FADctrl/FAD.h
r10103 r10113 62 62 ~FAD(); 63 63 64 void cmd_exit();void cmd_help();65 void cmd_board();void cmd_status();66 67 68 void cmd_srclk();void cmd_sclk();69 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 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(); 75 75 76 76 void EnableDomino(); … … 82 82 bool ReadCalibration(); 83 83 void PrintMessage(const char*, ...); 84 85 int Pipe[2]; 84 86 }; 85 87 -
fact/FADctrl/FADBoard.cc
r10101 r10113 89 89 int Ret; 90 90 91 // Cancel thread and wait for it to quit91 // Cancel thread (if it did not quit already) and wait for it to quit 92 92 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)); 94 94 if ((Ret = pthread_join(Thread, NULL)) != 0) m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret)); 95 95 } … … 164 164 // Initiate average 165 165 // 166 void FADBoard::AccumulateSum(unsigned int n ) {166 void FADBoard::AccumulateSum(unsigned int n, bool Rotate) { 167 167 168 168 if (!Active) return; 169 169 170 170 Lock(); 171 SumPhysPipeline = Rotate; 171 172 memset(Sum, 0, sizeof(Sum)); 172 173 NumForSum = n; … … 253 254 // Extract ID and type information 254 255 Status.BoardID = ntohl(Header->board_id); 256 Status.FirmwareRevision = ntohl(Header->version_no); 255 257 Status.TriggerID = ntohl(Header->local_trigger_id); 256 258 Status.TriggerType = ntohs(Header->local_trigger_type); … … 287 289 for (unsigned int Chip=0; Chip<NChips; Chip++) for (unsigned int Chan=0; Chan<NChannels; Chan++) { 288 290 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]; 290 293 } 291 294 } … … 312 315 else printf("End package flag incorrect, removing corrupt event\n"); 313 316 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 314 323 // Remove event data from internal buffer 315 324 memmove(Buffer, Buffer+Length, Pos-Length); -
fact/FADctrl/FADBoard.h
r10101 r10113 42 42 struct BoardStatus { 43 43 unsigned short BoardID; 44 unsigned short FirmwareRevision; 44 45 unsigned long TriggerID; 45 46 unsigned char TriggerType; … … 54 55 short Baseline[NChips][NChannels][NBins]; 55 56 double Gain[NChips][NChannels][NBins]; 57 double SecondaryBaseline[NChips][NChannels][NBins]; 56 58 float ACalibTemp; 57 59 time_t ACalibTime; … … 60 62 unsigned int NumForSum; 61 63 bool DoSum; 64 bool SumPhysPipeline; 62 65 63 66 void Send(const void *, size_t); 64 67 void Send(unsigned short); 65 68 struct BoardStatus GetStatus(); 66 void AccumulateSum(unsigned int );69 void AccumulateSum(unsigned int, bool); 67 70 void Lock(); 68 71 void Unlock(); -
fact/FADctrl/History.txt
r10101 r10113 4 4 5/1/2011 First version of amplitude calibration (no secondary calibration, yet). New 'socketmode' command. 5 5 13/1/2011 Amplitude calibration data is written to text file. 6 19/1/2011 Implemented secondary calibration. 7 21/1/2011 DIM event thread now informed through pipe of new data
Note:
See TracChangeset
for help on using the changeset viewer.