- Timestamp:
- 05/07/09 09:16:29 (16 years ago)
- Location:
- drsdaq
- Files:
-
- 2 added
- 1 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq
- Property svn:ignore
-
old new 2 2 DRSDAQ.log 3 3 Dep.d 4 4 calib
-
- Property svn:ignore
-
drsdaq/DAQReadout.cc
r31 r36 10 10 11 11 #include "DAQReadout.h" 12 #include "SlowData.h" 12 13 13 14 static const char* daq_state_str[] = {"active", "stopped"}; … … 22 23 {{"board", &DAQReadout::cmd_board, true, "<i> [j] | <all>" ,"Address board i, boards i-j, all boards"}, 23 24 {"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)"}, 25 26 {"calib", &DAQReadout::cmd_calib, true, "<t_f> <c_f> [dir]", "Response calibration"}, 26 27 {"trigger", &DAQReadout::cmd_trigger, true, "<on|off>", "Hardware trigger on or off"}, … … 28 29 {"wmode", &DAQReadout::cmd_wmode, true, "<0|1>", "Set DRS wave mode"}, 29 30 {"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)"}, 32 33 {"take", &DAQReadout::cmd_take, false, "<d|p|t> [n] [source]", "Start run (data, pedestal or test) with n events"}, 33 34 {"events", &DAQReadout::cmd_events, false, "", "Number of events in current run"}, … … 46 47 {"faverage", &DAQReadout::cmd_faverage, false, "[n]", "Set ot get number of averages for feedback"}, 47 48 {"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"}, 50 51 {"fconfig", &DAQReadout::cmd_fconfig, false, "", "Print feedback configuration"}, 51 52 {"help", &DAQReadout::cmd_help, false, "", "Print help"}}; … … 61 62 62 63 time(&StartTime); // Start time of DAQ 63 Rawfile = NULL;64 64 65 65 // 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; 70 71 NumEvents = 0; 71 72 NumEventsRequested = 100; … … 73 74 FirstBoard = 0; 74 75 LastBoard = -1; 75 s printf(Source,"DUMMY");76 snprintf(Source,sizeof(Source),"DUMMY"); 76 77 77 78 // Read configuration file … … 82 83 else { 83 84 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); 86 87 ReadCard("RotateWave", &fRotateWave, 'I', File); 87 88 ReadCard("FirstSample", &fFirstSample, 'I', File); … … 101 102 } 102 103 103 // Open log file 104 // Open log file and print configuration 104 105 if ((Logfile = fopen(fLogFile, "a")) == NULL) 105 106 fprintf(stderr,"Warning: Could not open log file '%s'\n", fLogFile); 106 107 else PrintMessage(MsgToLog,"********** Logging started **********\n"); 107 108 108 cmd_config(); 109 109 110 110 // Create DRS instance and perform initial scan 111 drs 111 drs = new DRS(); 112 112 drs->SetFirstVMESlot(fFirstVMESlot); 113 113 drs->SetLastVMESlot(fLastVMESlot); 114 114 drs->InitialScan(); 115 115 116 RHeader 117 EHeader 118 DRSFreq 116 RHeader = new RunHeader; 117 EHeader = new EventHeader; 118 DRSFreq = new float [drs->GetNumberOfBoards()]; 119 119 120 120 // Scan for DRS boards … … 135 135 WaveForm = new short [NumCMCBoards == 0 ? 1:NumCMCBoards][kNumberOfChips][kNumberOfChannels][kNumberOfBins]; 136 136 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) 138 138 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); 139 144 } 140 145 … … 144 149 145 150 DAQReadout::~DAQReadout() { 151 delete SlowDataClass; 146 152 delete RHeader; delete EHeader; 147 153 delete drs; delete HVFB; … … 176 182 for(CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++) 177 183 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"); 179 185 else if(CommandList[CmdNumber].NeedNotBusy && NumCMCBoards==0) PrintMessage("No mezzanine boards available\n"); 180 186 else (this->*CommandList[CmdNumber].CommandPointer)(); … … 189 195 time_t ActualT; 190 196 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); 192 198 } 193 199 194 200 // Print disk space 195 201 void 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)); 197 203 } 198 204 … … 217 223 void DAQReadout::cmd_take() { 218 224 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"); 227 228 return; 228 229 } 230 if (!IsDRSFreqSet()) return; 231 if (!CalibrationRead && !ReadCalibration()) { 232 PrintMessage("Cannot start run if response calibration not read.\n"); 233 return; 234 } 235 } 229 236 230 237 if (Match(Param[1],"data")) { … … 244 251 } 245 252 246 if (NParam==3 && atoi(Param[2])) NumEventsRequested = atoi(Param[2]);253 if (NParam==3) NumEventsRequested = atoi(Param[2]); 247 254 if (NParam==4) { 248 if(atoi(Param[2]))NumEventsRequested = atoi(Param[2]);255 NumEventsRequested = atoi(Param[2]); 249 256 strcpy(Source, Param[3]); 250 257 } 251 258 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 252 279 if ((pthread_create(&thread_DAQ, NULL, (void * (*)(void *)) DAQ,(void *) this)) != 0) 253 280 perror("pthread_create failed with DAQ thread"); … … 295 322 } 296 323 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 } 302 328 else PrintMessage("No DRS boards available\n"); 303 329 } … … 305 331 // Stop DAQ 306 332 void 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(); 309 335 if (IsDRSBusy()) { 310 336 StopDRS(); … … 313 339 } 314 340 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 316 346 void 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"); 319 349 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"); 326 378 } 327 379 … … 387 439 // Set DRS sampling frequency 388 440 void DAQReadout::cmd_freq() { 389 if (NParam ==3 && atof(Param[1]) && atoi(Param[2]))390 Set RegulatedDRSFrequency(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 } 393 445 else PrintUsage(); 394 446 } … … 510 562 } 511 563 else PrintMessage("Cannot address board(s), out of range.\n"); 564 CalibrationRead = false; 512 565 } 513 566 … … 516 569 char Buffer[MAX_COM_SIZE]; 517 570 for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) { 518 s printf(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); 520 573 } 521 PrintMessage( MsgToConsole|MsgToSocket,".<command> Execute shell command\n\n"574 PrintMessage(CmdFromSocket ? MsgToSocket:MsgToConsole,".<command> Execute shell command\n\n" 522 575 "Items in <> are mandatory, in [] optional, | indicates mutual exclusive or.\n" 523 576 "Test data can also be written if no DRS boards are available.\n" … … 531 584 return; 532 585 } 533 if ( IsDAQBusy()) PrintMessage("Issue \"stop\" first to stop daq\n");586 if (daq_state==active) PrintMessage("Issue \"stop\" first to stop daq\n"); 534 587 else { 535 588 Exit = true; … … 540 593 // Set/get mode of feedback 541 594 void 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(); 547 599 } 548 600 549 601 // Set/get current number of events 550 602 void 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", 552 604 HVFB->GetCurrentCount(), HVFB->GetNumAverages()); 553 605 else if(atoi(Param[1])>=0) HVFB->SetNumAverages(atoi(Param[1])); … … 557 609 // Set/get feedback gain 558 610 void 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()); 562 613 } 563 614 … … 566 617 if(NParam==1) HVFB->GetTargets(); 567 618 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])); 574 626 } 575 627 … … 577 629 void DAQReadout::cmd_fresponse() { 578 630 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])); 581 632 else PrintUsage(); 582 633 } … … 599 650 void DAQReadout::StopDRS() { 600 651 for (int i=FirstBoard; i<=LastBoard; i++) drs->GetBoard(i)->SoftTrigger(); 601 }602 603 // Read current data604 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 whitespace622 // to allow reading from client socket623 // The first number is the number of numbers that follow, the second number624 // 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");629 652 } 630 653 … … 650 673 for (int i=FirstBoard; i<=LastBoard; i++) { 651 674 (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); 653 676 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; 656 683 return true; 657 684 } … … 735 762 } 736 763 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 765 void DAQReadout::SetDRSFrequency(double freq, bool Regulation) { 754 766 755 767 double currentfreq; 756 768 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, ¤tfreq); 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, ¤tfreq); 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, ¤tfreq); 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 } 797 782 } 798 783 … … 811 796 } 812 797 closedir(pdir); 813 s printf(str,"%s",dir);798 snprintf(str,sizeof(str),"%s",dir); 814 799 PrintMessage("Target: \"%s\"\n",str); 815 800 } … … 858 843 } 859 844 860 // Check if DAQ is busy861 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 870 845 // Check if DRS is sampling 871 846 bool DAQReadout::IsDRSBusy() { … … 888 863 889 864 // Open new raw data file 890 bool DAQReadout::OpenRawFile( int Part) {865 bool DAQReadout::OpenRawFile() { 891 866 892 867 time_t rawtime; 893 868 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]; 896 870 897 871 // 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); 901 874 902 875 // Create direcory if not existing (ignore error if already existing) and change to it 903 s printf(Buffer, "%s/%s", fRawDataPath, RunDate);876 snprintf(Buffer, sizeof(Buffer), "%s/%s", fRawDataPath, RunDate); 904 877 if(mkdir(Buffer, S_IRWXU|S_IRWXG)==-1 && errno!=EEXIST) { 905 878 PrintMessage("\rError: Could not create direcory \"%s\" (%s)\n", Buffer, strerror(errno)); … … 907 880 } 908 881 909 // Determine new run number in directory (only if first file in series) by finding the910 // last file in alphabetical order and assuming that run number starts at position 9911 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 927 882 // Generate filename 928 s printf(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); 930 885 931 886 // 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)); 936 890 return false; 937 891 } 938 Rawfile = fdopen(TempDescriptor,"w");939 892 return true; 940 893 } 941 894 942 895 // Write run header and board structures 943 voidDAQReadout::WriteRunHeader() {896 bool DAQReadout::WriteRunHeader() { 944 897 945 898 time_t time_now_secs; 946 899 struct tm *time_now; 947 900 948 RHeader->MagicNum = MAGICNUM_ FILE_OPEN;901 RHeader->MagicNum = MAGICNUM_OPEN; 949 902 RHeader->DataFormat = DATA_FORMAT; 903 RHeader->RunHeaderSize = sizeof(RunHeader); 904 RHeader->EventHeaderSize = sizeof(EventHeader); 905 RHeader->BoardStructureSize = sizeof(BoardStructure); 950 906 strcpy(RHeader->DAQVersion, __DATE__); 907 951 908 strcpy(RHeader->Source, Source); 952 909 RHeader->Type = daq_runtype_str[daq_runtype][0]; 953 910 RHeader->RunNumber = RunNumber; 911 RHeader->FileNumber = FileNumber; 954 912 955 913 time(&time_now_secs); … … 969 927 970 928 RHeader->NCMCBoards = NumCMCBoards==0 && daq_runtype==test ? 1 : (LastBoard - FirstBoard) + 1; 971 RHeader->NChips 972 RHeader->NChannels 973 974 RHeader->Offset 975 RHeader->Samples 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)) { 978 936 PrintMessage("Error: Could not write run header, terminating run (%s)\n", strerror(errno)); 979 Stop = true;980 } 981 937 return false; 938 } 939 982 940 for (int i=FirstBoard; i<=LastBoard; i++) { 983 BStruct[i].Index = i;984 941 BStruct[i].SerialNo = drs->GetBoard(i)->GetCMCSerialNumber(); 985 942 BStruct[i].BoardTemp = drs->GetBoard(i)->GetTemperature(); … … 990 947 // In case no boards are available, dummy data is written for one board structure 991 948 if (NumCMCBoards == 0) { 992 LastBoard=0;993 949 BStruct[0].NomFreq = 1; 994 950 BStruct[0].ScaleFactor = 0.1; 995 951 } 996 952 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))) { 998 954 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; 1002 958 } 1003 959 1004 960 // Update the run header 1005 void DAQReadout::UpdateRunHeader(unsigned int Events) {961 bool DAQReadout::UpdateRunHeader(unsigned int Events, bool Error) { 1006 962 1007 963 time_t time_now_secs; 1008 964 struct tm *time_now; 1009 965 1010 RHeader->MagicNum = MAGICNUM_FILE_CLOSED;1011 RHeader->Events 966 RHeader->MagicNum = Error==false ? MAGICNUM_CLOSED:MAGICNUM_ERROR; 967 RHeader->Events = Events; 1012 968 1013 969 time(&time_now_secs); … … 1021 977 RHeader->EndSecond = time_now->tm_sec; 1022 978 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)) { 1025 985 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; 1028 989 } 1029 990 1030 991 // 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 992 bool DAQReadout::WriteEventHeader() { 993 994 struct timeval Time; 995 996 gettimeofday(&Time, NULL); 997 1038 998 strcpy(EHeader->Name,"EVTH"); 1039 1040 999 EHeader->EventNumber = NumEvents; 1041 1000 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)) { 1050 1004 PrintMessage("Error: Could not write event header, terminating run (%s)\n", strerror(errno)); 1051 Stop = true; 1052 } 1005 return false; 1006 } 1007 return true; 1053 1008 } 1054 1009 … … 1080 1035 1081 1036 memset(Textbuffer, 0, sizeof(Textbuffer)); 1082 vs printf(Textbuffer, Format, ArgumentPointer);1037 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer); 1083 1038 1084 1039 // Print to console and generate new prompt … … 1205 1160 1206 1161 struct timeval StartTime, StopTime; 1207 int Filepart;1162 int Count; 1208 1163 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; 1212 1172 m->HVFB->ClearAverages(); 1213 m->NumEvents = 0;1214 1173 gettimeofday(&StartTime, NULL); 1215 1174 … … 1223 1182 1224 1183 // Init run header, open raw file, write run header 1225 if (!m->OpenRawFile( Filepart)) break;1184 if (!m->OpenRawFile()) break; 1226 1185 m->PrintMessage("\rData file \"%s\" opened.\n",m->FileName); 1227 1186 EventsInFile = 0; 1228 m->WriteRunHeader(); 1187 FileSize = 0; 1188 WriteError |= !m->WriteRunHeader(); 1229 1189 1230 1190 if (m->daq_runtype != test) m->StartDRS(); 1231 1191 1232 1192 // 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) { 1235 1195 1236 1196 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(); 1242 1201 1243 1202 // Read event data via VME or generate test data (for one board if no boards available) … … 1251 1210 *((short *) m->WaveForm+i) = (short) (sin(i/Period)*1000); 1252 1211 } 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 } 1260 1230 } 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 } 1261 1238 // Call feedback to process event 1262 1239 m->HVFB->ProcessEvent(); … … 1264 1241 1265 1242 // 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); 1273 1250 1274 1251 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); 1282 1263 } 1283 1264 m->daq_state = stopped; -
drsdaq/DAQReadout.h
r27 r36 18 18 #include "HVFeedback.h" 19 19 20 #define RUN_NUM_FILE "/ct3data/LastRunNumber" 20 21 #define MAX_PATH 256 // also used for filename length 21 22 #define MAX_COM_SIZE 10000 … … 35 36 unsigned int CmdNumber; 36 37 FILE *Logfile; 38 bool CmdFromSocket; // Current command issued via socket 37 39 void PrintUsage(); 38 40 bool CalibrationRead; 41 39 42 public: 40 43 RunHeader* RHeader; … … 43 46 short (*WaveForm)[kNumberOfChips][kNumberOfChannels][kNumberOfBins]; 44 47 pthread_mutex_t control_mutex; 45 FILE *Rawfile;48 int Rawfile; 46 49 class HVFeedback* HVFB; 50 class SlowData *SlowDataClass; 47 51 48 52 // Configuration data … … 62 66 int NParam; // Number of parameters 63 67 const char *Param[MAX_NUM_TOKEN]; // Pointers to parameters 64 bool CmdFromSocket; // Current command issued via socket65 68 int NumCMCBoards; 66 69 int FirstBoard; … … 76 79 unsigned int NumEvents; // Number of event taken 77 80 unsigned int NumEventsRequested; // Number of events requested 78 unsigned int RunNumber ;81 unsigned int RunNumber, FileNumber; 79 82 char Source[32]; 80 83 char FileName[MAX_PATH]; … … 106 109 void StopDRS(); 107 110 void StopRun(); 108 bool IsDAQBusy();109 111 bool IsDRSBusy(); 110 112 bool IsDRSFreqSet(); 111 void SetDRSFrequency(double); 112 void SetRegulatedDRSFrequency(double); 113 double ReadDRSFrequency(); 113 void SetDRSFrequency(double, bool); 114 114 void CalibrateDRS(char*, double, double); 115 115 void SetDOMINOMode(int); … … 121 121 bool IsCalibrationRead(); 122 122 void ReadCalibratedDRSData(); 123 void ReadandPrintDRSData(int, int, int);124 123 void PrintMessage(int, const char*, ...); 125 124 void PrintMessage(const char*, ...); 126 125 void PrintMessage(int, const char*, va_list); 127 bool OpenRawFile( int);128 voidWriteRunHeader();129 void UpdateRunHeader(unsigned int);130 voidWriteEventHeader();126 bool OpenRawFile(); 127 bool WriteRunHeader(); 128 bool UpdateRunHeader(unsigned int, bool); 129 bool WriteEventHeader(); 131 130 }; 132 131 -
drsdaq/HVFeedback.cc
r27 r36 17 17 18 18 #define MAX_RETRY 5 19 19 #define PIXMAP_LOCATION "../config/PixelMap.txt" 20 21 // 20 22 // Constructor: Initialise feedback 23 // 21 24 HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) { 22 25 struct sockaddr_in SocketAddress; 23 26 char Filename[MAX_PATH]; 27 24 28 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 27 34 // Read configuration file 28 35 FILE *File; … … 32 39 else { 33 40 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); 45 53 fclose(File); 46 54 } … … 48 56 49 57 // 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 */ 55 71 Gain = 1; 56 72 SetFBMode(FB_Off); … … 77 93 } 78 94 95 // 79 96 // Destructor 97 // 80 98 HVFeedback::~HVFeedback() { 81 99 if (SocketDescriptor!=-1) { … … 85 103 delete[] Average; delete[] Response; 86 104 delete[] Target; delete[] Buffer; 87 delete PixMap;88 } 89 90 105 delete SlowDataClass; delete PixMap; 106 } 107 108 // 91 109 // Check if LED trigger present, if yes accumulate feedback data and 92 110 // calculate new high voltages if the required number of events is reached. 111 // 93 112 bool HVFeedback::ProcessEvent() { 94 float Correction; 113 int i,j,k,q; 114 float Correction, Integral, Difference, EffectiveGain; 95 115 96 116 // Check for LED trigger channel on given channel and if feedback running 97 117 if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][fLedTrigSample] < fLedTrigThreshold) 98 118 return false; 99 Count++;100 119 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 107 133 // 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 // 160 199 // Clear average values and event counter 200 // 161 201 void HVFeedback::ClearAverages() { 162 202 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 163 203 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 } 165 208 Count = 0; 166 209 } 167 210 211 // 168 212 // Number of events to accumulate before correction acts 213 // 169 214 void HVFeedback::SetNumAverages(unsigned int Averages) { 170 215 NumAverages = Averages; 171 216 } 172 217 218 // 173 219 // Get requested number of events 220 // 174 221 unsigned int HVFeedback::GetNumAverages() { 175 222 return NumAverages; 176 223 } 177 224 225 // 178 226 // Set feedback gain 227 // 179 228 void HVFeedback::SetGain(float FBGain) { 180 229 Gain = FBGain; 181 230 } 182 231 232 // 183 233 // Get feedback gain 234 // 184 235 float HVFeedback::GetGain() { 185 236 return Gain; 186 237 } 187 238 239 // 188 240 // Set feedback mode and clear averages 241 // 189 242 void HVFeedback::SetFBMode(FBState Mode) { 190 243 if(Mode==FB_ResponseFirst || Mode==FB_ResponseFirst) … … 196 249 } 197 250 251 // 198 252 // Set feedback mode and clear averages 253 // 199 254 FBState HVFeedback::GetFBMode() { 200 255 switch (FBMode) { … … 208 263 } 209 264 265 // 210 266 // Return current number of events 267 // 211 268 unsigned int HVFeedback::GetCurrentCount() { 212 269 return Count; 213 270 } 214 271 272 // 215 273 // Set target values 274 // 216 275 void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) { 217 276 if(Board<m->NumCMCBoards && Chip<kNumberOfChips && Channel<kNumberOfChannels) … … 220 279 } 221 280 281 // 222 282 // Print target values 283 // 223 284 void HVFeedback::GetTargets() { 224 285 for (int i=m->FirstBoard; i<=m->LastBoard; i++) … … 228 289 } 229 290 291 // 230 292 // 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 bezero.\n");293 // 294 void HVFeedback::MeasureResponse(float U) { 295 296 if (U==0) m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n"); 235 297 else { 236 298 for (int i=m->FirstBoard; i<=m->LastBoard; i++) … … 238 300 for (int k=0; k<kNumberOfChannels-2; k++) { 239 301 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); 241 303 } 242 Voltage1 = U1; Voltage2 = U2;304 DiffVoltage = U; 243 305 FBMode = FB_ResponseFirst; 244 306 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 // 249 312 // Print response values 313 // 250 314 void HVFeedback::GetResponse() { 251 315 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 252 316 for (int j=0; j<kNumberOfChips; j++) 253 317 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 // 257 322 // Write commmand to socket 323 // 258 324 bool HVFeedback::WriteHVCommand(const char *Format, ...) { 259 325 char Textbuffer[MAX_COM_SIZE]; … … 263 329 do { 264 330 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 268 333 // Write command to socket 269 334 if(write(SocketDescriptor, Textbuffer, strlen(Textbuffer)+1)!=(int) strlen(Textbuffer)+1) { … … 295 360 } 296 361 362 // 297 363 // Print feedback configuration 364 // 298 365 void HVFeedback::PrintConfig() { 299 366 m->PrintMessage("LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n" 300 367 "LedTrigSample: %d\tLedTrigThreshold: %.2f\n" 301 368 "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n" 302 " HVControlServer: %s\tHVControlPort: %d\n"369 "IntHalfWidth:%u\tHVControlServer: %s\tHVControlPort: %d\n" 303 370 "MaxCmdAckDelay: %d\n", 304 371 fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample, 305 372 fLedTrigThreshold, fLedSignalSample, fLedBaselineSample, 306 fDefaultNumAverage, f HVControlServer, fHVControlPort, fMaxCmdAckDelay);307 } 373 fDefaultNumAverage, fIntHalfWidth, fHVControlServer, fHVControlPort, fMaxCmdAckDelay); 374 } -
drsdaq/HVFeedback.h
r27 r36 8 8 #include "RawDataCTX.h" 9 9 #include "DAQReadout.h" 10 #include "SlowData.h" 10 11 11 12 enum FBState {FB_Off, FB_Active, FB_Targets, FB_ResponseFirst, FB_ResponseSecond}; … … 14 15 15 16 class DAQReadout *m; 16 class PixelMap *PixMap; 17 class PixelMap *PixMap; 18 class SlowData *SlowDataClass; 17 19 FBState FBMode; 18 20 19 21 float (*Average)[kNumberOfChips][kNumberOfChannels]; 22 float (*Sigma)[kNumberOfChips][kNumberOfChannels]; 20 23 float (*Response)[kNumberOfChips][kNumberOfChannels]; 21 24 float (*Target)[kNumberOfChips][kNumberOfChannels]; … … 26 29 27 30 float Gain; // Feedback gain 28 float Voltage1, Voltage2;// for response measurement31 float DiffVoltage; // for response measurement 29 32 int SocketDescriptor; 30 33 char TextBuf[BUF_LENGTH]; … … 37 40 int fLedSignalSample; 38 41 int fLedBaselineSample; 42 unsigned int fIntHalfWidth; 39 43 int fDefaultNumAverage; 40 44 char fHVControlServer[BUF_LENGTH]; 41 45 int fHVControlPort; 42 46 int fMaxCmdAckDelay; 43 47 44 48 public: 45 49 HVFeedback(class DAQReadout*, char*); … … 56 60 FBState GetFBMode(); 57 61 unsigned int GetCurrentCount(); 58 void MeasureResponse(float , float);62 void MeasureResponse(float); 59 63 void GetResponse(); 60 64 void ClearAverages(); -
drsdaq/History.txt
r31 r36 13 13 2/4/2009 Intoduced check for magic number in RawDataCTX.cc 14 14 3/4/2009 Added frequency and scale factor transmission to socket protocol 15 6/4/2009 Allowed reading of data via read command also while DAQ is active. 16 22/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. 20 28/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. 25 29/4/2009 DAQ writes run summary to slow data file. -
drsdaq/Makefile
r22 r36 8 8 VMECTRL = -DCT_VME 9 9 10 #CC = g++ # Compiler to use10 CC = g++ # Compiler to use 11 11 12 SOURCES = HVFeedback.cc DAQReadout.cc RawDataCTX.cc ../pixelmap/Pixel.cc ../pixelmap/PixelMap.cc DRS/DRS.cc DRS/mxml.c DRS/strlcpy.c drsdaq.cpp12 SOURCES = 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 13 13 OBJECTS = $(addsuffix .o, $(basename $(SOURCES))) 14 14 15 SOBJECTS = RawDataCTX16 15 INCDIRS = -I. -IDRS -I../pixelmap 17 16 … … 31 30 drsdaq: $(OBJECTS) 32 31 $(CC) $(CPPFLAGS) -o $@ $(OBJECTS) $(LIBS) 33 $(CC) -shared -Wl,-soname,$(SOBJECTS).so -o $(SOBJECTS).so $(SOBJECTS).o -lc34 32 35 33 clean: 36 @rm -f $(OBJECTS) $(SOBJECTS).so34 @rm -f $(OBJECTS) 37 35 @rm -f *.d 38 36 @rm -f *~ -
drsdaq/RawDataCTX.cc
r28 r36 43 43 } 44 44 // 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) { 46 46 if(!Silent) printf("Error: Magic number of run header incorrect\n"); 47 47 fclose(Rawfile); … … 62 62 // If requested, print run header (including board structures) to file 63 63 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 68 70 fprintf(fptr, "DAQ compilation: %s\n", RHeader->DAQVersion); 69 71 fprintf(fptr, "Source: %s\n", RHeader->Source); 70 72 fprintf(fptr, "Run type: %c\n", RHeader->Type); 71 73 fprintf(fptr, "Run number: %u\n", RHeader->RunNumber); 74 fprintf(fptr, "File number: %u\n", RHeader->FileNumber); 72 75 fprintf(fptr, "Events: %u\n", RHeader->Events); 73 76 fprintf(fptr, "CMC Boards: %u\n", RHeader->NCMCBoards); … … 77 80 fprintf(fptr, "Offset: %d\n", RHeader->Offset); 78 81 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); 98 86 99 87 fprintf(fptr, "Start year: %u\n", RHeader->StartYear); -
drsdaq/RawDataCTX.h
r22 r36 20 20 #define DATA_FORMAT 1 21 21 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 22 typedef char I8; 23 typedef unsigned char U8; 24 typedef short I16; 25 typedef unsigned short U16; 26 typedef int I32; 27 typedef unsigned int U32; 28 typedef float F32; 29 29 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 32 33 33 34 // Error codes … … 39 40 // Run header 40 41 typedef 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 43 49 I8 DAQVersion[12]; // contains result of __DATE__ macro 50 44 51 I8 Source[16]; 45 52 I8 Type; // run type (char): pedestal, data, ... 53 46 54 U32 RunNumber; 55 U32 FileNumber; 47 56 48 U 16StartYear;49 U 8StartMonth;50 U 8StartDay;51 U 8StartHour;52 U 8StartMinute;53 U 8StartSecond;57 U32 StartYear; 58 U32 StartMonth; 59 U32 StartDay; 60 U32 StartHour; 61 U32 StartMinute; 62 U32 StartSecond; 54 63 55 U 16EndYear;56 U 8EndMonth;57 U 8EndDay;58 U 8EndHour;59 U 8EndMinute;60 U 8EndSecond;64 U32 EndYear; 65 U32 EndMonth; 66 U32 EndDay; 67 U32 EndHour; 68 U32 EndMinute; 69 U32 EndSecond; 61 70 62 71 F32 SourceRA; … … 65 74 F32 TelescopeDEC; 66 75 67 U32 Events; // Number of events in the run76 U32 Events; // Number of events in the file 68 77 U32 NCMCBoards; // Number of used boards 69 78 U32 NChips; // Number of DRS chips per board … … 75 84 // Board structure 76 85 typedef struct { 77 I32 Index; // Index number (data written in this order)78 86 I32 SerialNo; // Board serial number 79 87 F32 NomFreq; // Nominal sampling frequency [GHz] -
drsdaq/drsdaq.cpp
r22 r36 75 75 signal(SIGTERM, &CrashHandler); 76 76 signal(SIGINT, &CrashHandler); 77 signal(SIGHUP, &CrashHandler); 77 78 78 79 // Construct main instance
Note:
See TracChangeset
for help on using the changeset viewer.