- Timestamp:
- 01/24/11 08:47:21 (14 years ago)
- Location:
- fact/FADctrl
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/FADctrl/FAD.cc
r10113 r10114 32 32 {"address", &FAD::cmd_address, true, 2, "<range> <value>", "Set addresses in range to value"}, 33 33 {"send", &FAD::cmd_send, true, 1, "<value>", "Send arbitrary data to board"}, 34 {"take", &FAD::cmd_take, true, 1, "<n> <dir>", "Start run with n events, write to directory"}, 34 35 {"acalib", &FAD::cmd_acalib, true, 0, "[n|invalidate|file]", "Perform or read amplitude calibration (n events)"}, 35 36 //{"wmode", &FAD::cmd_wmode, 0, "<run|stop>", "Domino wave running or stopped during read out"}, 36 37 //{"rmode", &FAD::cmd_rmode, 0, "<first|stop>", "Readout start at first bin or stop position (DRS4)"}, 37 38 //{"dmode", &FAD::cmd_dmode, 0, "<single|continuous>", "Domino wave single shot or continuous"}, 38 {"cancel", &FAD::cmd_cancel, false, 0, "", "Cancel current operation "},39 {"cancel", &FAD::cmd_cancel, false, 0, "", "Cancel current operation/run"}, 39 40 {"update", &FAD::cmd_update, false, 1, "<sec>", "Minimum delay between updates to DIM event service"}, 40 41 {"socketmode", &FAD::cmd_socketmode, true, 1, "<com|daq>", "Choose which Sockets are used for data transmission"}, … … 57 58 MainThread = pthread_self(); 58 59 Mode = idle; 60 Datafile = -1; 59 61 EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str()); 60 62 … … 450 452 451 453 // 454 // Start data run 455 // 456 void FAD::cmd_take() { 457 458 time_t Time = time(NULL); 459 struct tm *T = localtime(&Time); 460 char Filename[500]; 461 462 // Set number of requested events 463 NumEventsRequested = atoi(Parameter[1].c_str()); 464 NumEvents = 0; 465 466 // Open file with rwx right for owner and group, never overwrite file 467 snprintf(Filename, sizeof(Filename),"%s/%d%02d%02dT%02d%02d%02d.raw", Parameter[2].c_str(), T->tm_year+1900, T->tm_mon+1, T->tm_mday, T->tm_hour, T->tm_min, T->tm_sec); 468 469 Datafile = open(Filename,O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); 470 if(Datafile == -1) { 471 PrintMessage("Error: Could not open file \"%s\" (%s)\n", Filename, strerror(errno)); 472 return; 473 } 474 475 // Start run 476 Mode = datarun; 477 PrintMessage("Starting run with %d events, filename '%s'\n", NumEventsRequested, Filename); 478 } 479 480 // 452 481 // Amplitude calibration 453 482 // … … 684 713 void FAD::cmd_cancel() { 685 714 715 static char Stop[] = "stop"; 716 686 717 if (Mode == idle) PrintMessage("Nothing to cancel\n"); 687 718 else { 719 // Inform event thread to stop run in case datarun active 720 if (write(Pipe[1], Stop, strlen(Stop)+1) == -1) { 721 Message(ERROR, "write() to Pipe[1] failed in FAD::cmd_cancel() (%s)", strerror(errno)); 722 } 723 Cancel = true; 688 724 PrintMessage("Requested cancelation of current operation\n"); 689 Cancel = true;690 725 } 691 726 } … … 915 950 916 951 // 917 // DIM event service update thread (publishes M0 format)952 // Event thread (publishes/writes M0 format) 918 953 // 919 954 void FAD::EventThread() { 920 955 921 struct timeval Time ;956 struct timeval Time, RunStart; 922 957 struct timeval LastUpdate; 923 958 struct FADBoard::BoardStatus S; 959 vector<unsigned long> EventNumbers(Boards.size()); 924 960 double Temp; 925 961 string IDString; 926 962 char Buffer[100]; 927 963 int Ret; 964 unsigned long long FileSize = 0; 928 965 929 966 gettimeofday(&LastUpdate, NULL); 930 967 RunStart = LastUpdate; // only to avoid 'uninitialized' warning from compiler 968 931 969 // Create DIM event data service 932 970 int EventSize = sizeof(RunHeader)+ Boards.size()*sizeof(BoardStructure)+sizeof(EventHeader) + Boards.size()*(NChips*NChannels*NBins*sizeof(short) + NChips*sizeof(int)); … … 945 983 946 984 // M0 RunHeader 947 RHeader->MagicNum = 0xE0E0; 948 RHeader->DataFormat = 1; 985 RHeader->DataFormat = DATA_FORMAT; 949 986 RHeader->RunHeaderSize = sizeof(RunHeader); 950 987 RHeader->EventHeaderSize = sizeof(EventHeader); … … 954 991 955 992 RHeader->Type = 0; // Run type: 0=data, 1=pedestal, 3=test 956 RHeader->Events = 1;957 993 958 994 RHeader->RunNumber = -1; 959 995 RHeader->FileNumber = 0; 960 snprintf(RHeader->Description, sizeof(RHeader->Description), "FADctrl _Event");996 snprintf(RHeader->Description, sizeof(RHeader->Description), "FADctrl"); 961 997 962 998 RHeader->NBoards = Boards.size(); … … 965 1001 RHeader->Samples = NBins; // Always full pipeline 966 1002 RHeader->Offset = 0; 967 RHeader->NBytes = 2;1003 RHeader->NBytes = sizeof(short); 968 1004 969 1005 // M0 EventHeader … … 977 1013 978 1014 // Update run and event header with current time 979 gettimeofday(&Time, NULL); 1015 gettimeofday(&Time, NULL); 1016 1017 RHeader->MagicNum = MAGICNUM_CLOSED; 1018 RHeader->EndSecond = Time.tv_sec; 1019 RHeader->EndMicrosecond = Time.tv_usec; 1020 1021 EHeader->Second = Time.tv_sec; 1022 EHeader->Microsecond = Time.tv_usec; 1023 1024 // Close data file if requested or requested number of events reached 1025 if((IDString.find("stop")!=string::npos || NumEvents==NumEventsRequested) && Mode==datarun) { 1026 1027 // Update run header 1028 RHeader->Events = NumEvents; 1029 RHeader->StartSecond = RunStart.tv_sec; 1030 RHeader->StartMicrosecond = RunStart.tv_usec; 1031 1032 if (lseek(Datafile, 0, SEEK_SET) == -1) { 1033 PrintMessage("Error: Could not rewind file to write updated run header (%s)\n", strerror(errno)); 1034 } 1035 else if (write(Datafile, RHeader, sizeof(RunHeader)) != sizeof(RunHeader)) { 1036 PrintMessage("Error: Could not write updated run header (%s)\n", strerror(errno)); 1037 } 1038 1039 // Close data file and terminate run 1040 if(close(Datafile) == -1) PrintMessage("Error: Could not close data file (%s)\n", strerror(errno)); 1041 else PrintMessage("Data file closed (size %.1f MByte).\n", FileSize/1024.0/1024); 1042 1043 Datafile = -1; 1044 Mode = idle; 1045 } 1046 1047 // These values might have changed while close file 980 1048 RHeader->StartSecond = Time.tv_sec; 981 1049 RHeader->StartMicrosecond = Time.tv_usec; 982 RHeader->EndSecond = Time.tv_sec; 983 RHeader->EndMicrosecond = Time.tv_usec; 984 985 EHeader->Second = Time.tv_sec; 986 EHeader->Microsecond = Time.tv_usec; 1050 RHeader->Events = 1; 987 1051 988 1052 // Check all boards that have new data … … 1003 1067 EHeader->TriggerType = S.TriggerType; 1004 1068 1069 // Register event number for data writing below 1070 EventNumbers[Brd] = S.TriggerID; 1071 1005 1072 // Write trigger cells 1006 1073 for(unsigned int i=0; i<NChips; i++) TriggerCell[Brd*NChips+i] = (int) S.TriggerCell[i]; 1007 1074 1008 // Write channel data ( stored in12 bit signed twis complement with out-of-range-bit and leading zeroes)1075 // Write channel data (12 bit signed twis complement with out-of-range-bit and leading zeroes) 1009 1076 int Count = 0; 1010 1077 memset(Data, 0, Boards.size()*NChips*NChannels*NBins*sizeof(short)); … … 1023 1090 Count += NBins - S.ROI[Chip][Chan]; 1024 1091 } 1092 1093 // Inform TCP/IP thread that data has been processed 1094 Boards[Brd]->Continue = true; 1025 1095 Boards[Brd]->Unlock(); 1026 } 1096 1097 if ((Ret = pthread_cond_signal(&Boards[Brd]->CondVar)) != 0) { 1098 Message(FATAL, "pthread_cond_signal() failed (%s)", strerror(Ret)); 1099 } 1100 } // Loop over boards 1027 1101 1028 1102 // Check if DIM service should be updated … … 1031 1105 EventService->updateService(EventData, EventSize); 1032 1106 } 1107 1108 // ===== Data writing === 1109 1110 if (Mode != datarun) continue; 1111 1112 // Check if all event numbers are the same 1113 bool Same = true; 1114 for (unsigned int i=0; i<Boards.size(); i++) { 1115 if (Boards[i]->Active && EventNumbers[i] != EventNumbers[0]) Same = false; 1116 } 1117 if (!Same) continue; 1118 1119 // Write also run header if this is the first event 1120 int Offset; 1121 if (NumEvents == 0) { 1122 RHeader->MagicNum = MAGICNUM_OPEN; 1123 RunStart = Time; 1124 Offset = 0; 1125 FileSize = 0; 1126 } 1127 else Offset = sizeof(RunHeader) + Boards.size()*sizeof(BoardStructure); 1128 1129 // Write data to file 1130 if(write(Datafile, EventData+Offset, EventSize-Offset) != (ssize_t) EventSize-Offset) { 1131 PrintMessage("Error: Could not write all data to file, terminating run (%s)\n", strerror(errno)); 1132 1133 // Close file if error 1134 if (close(Datafile) == -1) PrintMessage("Error: Could not close data file (%s)\n", strerror(errno)); 1135 Datafile = -1; 1136 Mode = idle; 1137 continue; 1138 } 1139 1140 NumEvents++; 1141 FileSize += EventSize-Offset; 1142 1143 printf("Wrote event %d\n", NumEvents-1); 1033 1144 } 1034 1145 -
fact/FADctrl/FAD.h
r10113 r10114 17 17 #include <sys/time.h> 18 18 #include <limits> 19 #include <fcntl.h> 19 20 20 21 #include "FADBoard.h" … … 23 24 const char CALIB_DIRECTORY[] = "~/"; 24 25 25 enum ModeType {idle, acalib, tcalib};26 enum ModeType {idle, datarun, acalib}; 26 27 27 28 class FAD: public EvidenceServer { … … 44 45 float EventUpdateDelay; 45 46 47 int Datafile; 48 int NumEvents; // Number of event taken 49 int NumEventsRequested; // Number of events requested 46 50 int NumCalibEvents; 47 51 … … 73 77 void cmd_phase(); void cmd_send(); 74 78 void cmd_cancel(); void cmd_update(); 79 void cmd_take(); 75 80 76 81 void EnableDomino(); -
fact/FADctrl/FADBoard.cc
r10113 r10114 19 19 InitOK = false; 20 20 Active = true; 21 Continue = true; 21 22 CommError = false; 22 23 ACalibTime = -1; … … 72 73 } 73 74 75 // Initialise condition variable for synchronization 76 if ((Ret = pthread_cond_init(&CondVar, NULL)) != 0) { 77 m->Message(m->ERROR, "pthread_cond_init() failed (%s)", strerror(Ret)); 78 return; 79 } 80 74 81 // Create thread that receives data 75 82 if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) { … … 93 100 if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret)); 94 101 if ((Ret = pthread_join(Thread, NULL)) != 0) m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret)); 102 } 103 104 // Delete condition variable 105 if ((Ret = pthread_cond_destroy(&CondVar)) != 0) { 106 m->Message(m->ERROR, "pthread_cond_destroy() failed in ~FADBoard (%s)", strerror(Ret)); 95 107 } 96 108 … … 187 199 ssize_t Result; 188 200 struct BoardStatus PrevStatus; 201 int Ret; 189 202 190 203 memset(&PrevStatus, 0, sizeof(PrevStatus)); … … 249 262 // Lock to avoid concurrent access in GetStatus() 250 263 Lock(); 264 265 // Wait until event thread processed the previous data 266 while (!Continue) { 267 if ((Ret = pthread_cond_wait(&CondVar, &Mutex)) != 0) { 268 m->Message(m->ERROR, "pthread_cond_wait() failed (%s)", strerror(Ret)); 269 } 270 } 251 271 252 272 gettimeofday(&Status.Update, NULL); … … 297 317 } 298 318 319 Continue = false; 299 320 Unlock(); 300 321 -
fact/FADctrl/FADBoard.h
r10113 r10114 75 75 bool CommError; 76 76 bool Active; 77 bool Continue; 78 pthread_cond_t CondVar; 77 79 }; 78 80 -
fact/FADctrl/History.txt
r10113 r10114 6 6 19/1/2011 Implemented secondary calibration. 7 7 21/1/2011 DIM event thread now informed through pipe of new data 8 23/1/2011 Data can be written to disk in M0 format
Note:
See TracChangeset
for help on using the changeset viewer.