50 #define POLL_TRIES 100 53 #define MAX_FILE_SIZE 4294967296ll 56 #define PKT_HEAD_LEN 8 59 #define MAX_PKT_DATA (MAX_ORPH_DATA - PKT_HEAD_LEN) 67 bool IsNumeric(
const std::string &input_,
const std::string &prefix_,
const std::string &msg_){
68 for(
size_t i = 0; i < input_.size(); i++){
69 if((input_[i] < 0x30 || input_[i] > 0x39) && input_[i] != 0x2D && input_[i] != 0x2E){
70 if(!msg_.empty()) std::cout << msg_ <<
" (" << input_ <<
").\n";
77 std::vector<std::string>
chan_params = {
"TRIGGER_RISETIME",
"TRIGGER_FLATTOP",
"TRIGGER_THRESHOLD",
"ENERGY_RISETIME",
"ENERGY_FLATTOP",
"TAU",
"TRACE_LENGTH",
78 "TRACE_DELAY",
"VOFFSET",
"XDT",
"BASELINE_PERCENT",
"EMIN",
"BINFACTOR",
"CHANNEL_CSRA",
"CHANNEL_CSRB",
"BLCUT",
79 "ExternDelayLen",
"ExtTrigStretch",
"ChanTrigStretch",
"FtrigoutDelay",
"FASTTRIGBACKLEN"};
81 std::vector<std::string>
mod_params = {
"MODULE_CSRA",
"MODULE_CSRB",
"MODULE_FORMAT",
"MAX_EVENTS",
"SYNCH_WAIT",
"IN_SYNCH",
"SLOW_FILTER_RANGE",
82 "FAST_FILTER_RANGE",
"MODULE_NUMBER",
"TrigConfig0",
"TrigConfig1",
"TrigConfig2",
"TrigConfig3"};
85 "startacq",
"startvme",
"stopacq",
"stopvme",
"timedrun",
"acq",
"shm",
"spill",
86 "hup",
"prefix",
"fdir",
"title",
"runnum",
"oform",
"close",
"reboot",
"stats",
90 "pmread",
"pwrite",
"pmwrite",
"adjust_offsets",
"find_tau",
"toggle",
91 "toggle_bit",
"csr_test",
"bit_test",
"get_traces"});
94 "debug",
"quiet",
"quit",
"help",
"version"});
120 #if defined(USE_ROOT) && defined(USE_DAMM) 125 #elif defined(USE_ROOT) 127 #elif defined(USE_DAMM) 142 if(!
mca){
return false; }
170 sys_message_head(
" POLL: "),
178 run_ctrl_exit(false),
185 insert_wall_clock(true),
188 show_module_rates(false),
196 output_directory(
"./"),
197 filename_prefix(
"run"),
198 output_title(
"PIXIE data file"),
204 total_spill_chunks(0)
210 int startScheduler = sched_getscheduler(0);
211 if(startScheduler == SCHED_BATCH){
214 else if(startScheduler == SCHED_OTHER){
233 unsigned short revision, adcBits, adcMsps;
234 unsigned int serialNumber;
236 std::cout <<
"Module " << std::right << std::setw(2) <<
mod <<
": " <<
237 "Serial Number " << std::right << std::setw(4) << serialNumber <<
", " <<
238 "Rev " << std::hex << std::uppercase << revision << std::dec <<
" " <<
239 "(" << revision <<
"), " <<
240 adcBits <<
"-bit " << adcMsps <<
" MS/s " <<
247 if(
init){
return false; }
257 if(!
pif->
Init()){
return false; }
313 if(!
init){
return false; }
351 std::cout <<
"|- No file is open.\n";
396 std::cout <<
"|- A file is already open!\n";
409 std::cout <<
"|- Failed to open output file! Check that the path is correct.\n";
434 static bool firstTime =
true;
435 static char synchString[] =
"IN_SYNCH";
436 static char waitString[] =
"SYNCH_WAIT";
438 bool hadError =
false;
468 if(current_filesize + (std::streampos)(4*nWords + 65552) >
MAX_FILE_SIZE){
471 std::cout <<
sys_message_head <<
"Maximum ifile size reached. New output file will be created.\n";
472 std::cout << sys_message_head <<
"Current filesize is " << current_filesize + (std::streampos)65552 <<
" bytes.\n";
477 if (!
is_quiet) std::cout <<
"Writing " << nWords <<
" words.\n";
484 static const unsigned int maxShmSizeL = 4050;
485 static const unsigned int maxShmSize = maxShmSizeL *
sizeof(
word_t);
488 unsigned int nBufs = nWords / maxShmSizeL;
489 unsigned int wordsLeft = nWords % maxShmSizeL;
491 unsigned int totalBufs = nBufs + 1 + ((wordsLeft != 0) ? 1 : 0);
493 if (
debug_mode) std::cout <<
"Broadcasting " << totalBufs <<
" pacman buffers.\n";
498 for(
size_t buf=0; buf < nBufs; buf++){
503 pWrite[1] = totalBufs;
505 memcpy(&pWrite[3], &data[buf * maxShmSizeL], maxShmSize);
512 if (wordsLeft != 0) {
515 pWrite[1] = totalBufs;
517 memcpy(&pWrite[3], &data[nBufs * maxShmSizeL],
518 wordsLeft *
sizeof(
word_t) );
527 pWrite[1] = totalBufs;
528 pWrite[2] = totalBufs - 1;
537 int shm_data[maxShmSizeL+2];
538 unsigned int num_net_chunks = nWords / maxShmSizeL;
539 unsigned int num_net_remain = nWords % maxShmSizeL;
540 if(num_net_remain != 0){ num_net_chunks++; }
542 unsigned int net_chunk = 1;
543 unsigned int words_bcast = 0;
544 if(
debug_mode){ std::cout <<
" debug: Splitting " << nWords <<
" words into network spill of " << num_net_chunks <<
" chunks (fragment = " << num_net_remain <<
" words)\n"; }
546 while(words_bcast < nWords){
547 if(nWords - words_bcast > maxShmSizeL){
548 memcpy(&shm_data[0], &net_chunk, 4);
549 memcpy(&shm_data[1], &num_net_chunks, 4);
550 memcpy(&shm_data[2], &data[words_bcast], maxShmSize);
552 words_bcast += maxShmSizeL;
555 memcpy(&shm_data[0], &net_chunk, 4);
556 memcpy(&shm_data[1], &num_net_chunks, 4);
557 memcpy(&shm_data[2], &data[words_bcast], (nWords-words_bcast)*4);
559 words_bcast += nWords-words_bcast;
571 const int BufEnd=0xFFFFFFFF;
572 short int status, cont_pkt;
586 if(size <= MAX_PKT_DATA){
594 if(status < 0){ std::cout <<
Display::WarningStr(
"[WARNING]") <<
": Error sending UDP message to pacman."; }
605 if(size > MAX_PKT_DATA){
614 *((
unsigned short *)(bufptr+
PKT_HEAD_LEN+6)) = cont_pkt;
616 *((
int *)(bufptr+4)) = bytes+8;
619 if(status < 0){ std::cout <<
Display::WarningStr(
"[WARNING]") <<
": Error sending UDP message to pacman."; }
629 std::cout <<
" Help:\n";
631 std::cout <<
" run - Start data acquisition and start recording data to disk\n";
632 std::cout <<
" stop - Stop data acqusition and stop recording data to disk\n";
633 std::cout <<
" startacq (startvme) - Start data acquisition\n";
634 std::cout <<
" stopacq (stopvme) - Stop data acquisition\n";
635 std::cout <<
" timedrun <seconds> - Run for the specified number of seconds\n";
636 std::cout <<
" acq (shm) - Run in \"shared-memory\" mode\n";
637 std::cout <<
" spill (hup) - Force dump of current spill\n";
638 std::cout <<
" prefix [name] - Set the output filename prefix (default='run_#.ldf')\n";
639 std::cout <<
" fdir [path] - Set the output file directory (default='./')\n";
640 std::cout <<
" title [runTitle] - Set the title of the current run (default='PIXIE Data File)\n";
641 std::cout <<
" runnum [number] - Set the number of the current run (default=0)\n";
642 std::cout <<
" oform [0|1|2] - Set the format of the output file (default=0)\n";
643 std::cout <<
" reboot - Reboot PIXIE crate\n";
644 std::cout <<
" stats [time] - Set the time delay between statistics dumps (default=-1)\n";
645 std::cout <<
" mca [root|damm] [time] [filename] - Use MCA to record data for debugging purposes\n";
647 std::cout <<
" dump [filename] - Dump pixie settings to file (default='Fallback.set')\n";
648 std::cout <<
" pread <mod> <chan> <param> - Read parameters from individual PIXIE channels\n";
649 std::cout <<
" pmread <mod> <param> - Read parameters from PIXIE modules\n";
650 std::cout <<
" pwrite <mod> <chan> <param> <val> - Write parameters to individual PIXIE channels\n";
651 std::cout <<
" pmwrite <mod> <param> <val> - Write parameters to PIXIE modules\n";
652 std::cout <<
" adjust_offsets <module> - Adjusts the baselines of a pixie module\n";
653 std::cout <<
" find_tau <module> <channel> - Finds the decay constant for an active pixie channel\n";
654 std::cout <<
" toggle <module> <channel> <bit> - Toggle any of the 19 CHANNEL_CSRA bits for a pixie channel\n";
655 std::cout <<
" toggle_bit <mod> <chan> <param> <bit> - Toggle any bit of any parameter of 32 bits or less\n";
656 std::cout <<
" csr_test <number> - Output the CSRA parameters for a given integer\n";
657 std::cout <<
" bit_test <num_bits> <number> - Display active bits in a given integer up to 32 bits long\n";
658 std::cout <<
" get_traces <mod> <chan> [threshold] - Get traces for all channels in a specified module\n";
659 std::cout <<
" status - Display system status information\n";
660 std::cout <<
" thresh [threshold] - Modify or display the current polling threshold.\n";
661 std::cout <<
" debug - Toggle debug mode flag (default=false)\n";
662 std::cout <<
" quiet - Toggle quiet mode flag (default=false)\n";
663 std::cout <<
" quit - Close the program\n";
664 std::cout <<
" help (h) - Display this dialogue\n";
665 std::cout <<
" version (v) - Display Poll2 version information\n";
670 std::cout <<
" Valid Pixie16 channel parameters:\n";
671 for(
unsigned int i = 0; i < chan_params.size(); i++){
672 std::cout <<
" " << chan_params[i] <<
"\n";
678 std::cout <<
" Valid Pixie16 module parameters:\n";
679 for(
unsigned int i = 0; i < mod_params.size(); i++){
680 std::cout <<
" " << mod_params[i] <<
"\n";
694 std::cout <<
sys_message_head <<
"Warning! Cannot run acquisition while MCA program is running\n";
731 std::stringstream output;
744 std::cout <<
" Poll Run Status:\n";
749 std::cout <<
" Shared memory - " <<
yesno(
shm_mode) << std::endl;
756 else{ std::cout <<
" Pacman mode - " <<
yesno(
pac_mode) << std::endl; }
759 std::cout <<
"\n Poll Options:\n";
767 std::cout <<
" Initialized - " <<
yesno(
init) << std::endl;
779 std::cout <<
sys_message_head <<
"Searching for traces from mod = " << mod_ <<
", chan = " << chan_ <<
" above threshold = " << thresh_ <<
".\n";
780 std::cout <<
sys_message_head <<
"Allocating " << (trace_size+module_size)*
sizeof(
unsigned short) <<
" bytes of memory for pixie traces.\n";
784 unsigned short *trace_data =
new unsigned short[trace_size];
785 unsigned short *module_data =
new unsigned short[module_size];
786 memset(trace_data, 0,
sizeof(
unsigned short)*trace_size);
787 memset(module_data, 0,
sizeof(
unsigned short)*module_size);
789 GetTraces gtraces(module_data, module_size, trace_data, trace_size, thresh_);
792 if(!gtraces.
GetStatus()){ std::cout << sys_message_head <<
"Failed to find trace above threshold in " << gtraces.
GetAttempts() <<
" attempts!\n"; }
793 else{ std::cout << sys_message_head <<
"Found trace above threshold in " << gtraces.
GetAttempts() <<
" attempts.\n"; }
795 std::cout <<
" Baselines:\n";
797 if(
channel == (
unsigned)chan_){ std::cout <<
"\033[0;33m"; }
799 else{ std::cout <<
" " <<
channel <<
": "; }
802 if(
channel == (
unsigned)chan_){ std::cout <<
"\033[0m"; }
805 std::ofstream get_traces_out(
"/tmp/traces.dat");
806 if(!get_traces_out.good()){ std::cout << sys_message_head <<
"Could not open /tmp/traces.dat!\n"; }
809 get_traces_out <<
"time";
812 else{ get_traces_out <<
"\tC" <<
channel; }
814 get_traces_out << std::endl;
817 for(
size_t index = 0; index < trace_size; index++){
818 get_traces_out << index;
820 get_traces_out <<
"\t" << module_data[(
channel * trace_size) + index];
822 get_traces_out << std::endl;
824 std::cout << sys_message_head <<
"Traces written to '/tmp/traces.dat'." << std::endl;
826 get_traces_out.close();
829 delete[] module_data;
840 if (arg.find_first_not_of(
"-0123456789:") != std::string::npos)
return false;
842 size_t delimeterPos = arg.find(
':');
844 start = std::stoi(arg.substr(0, delimeterPos));
846 if (delimeterPos != std::string::npos) {
847 stop = std::stoi(arg.substr(delimeterPos + 1));
848 if (start < 0 || stop < 0 || start > stop)
return false;
852 catch (
const std::invalid_argument &ia) {
863 std::string cmd =
"", arg;
893 if(pacman_command.
Data[0] == 0x11){
894 std::cout <<
"RECV PACMAN COMMAND 0x11 (INIT_ACQ)\n";
895 pacman_command.
Data[0] = 0x00;
897 else if(pacman_command.
Data[0] == 0x22){
898 std::cout <<
"RECV PACMAN COMMAND 0x22 (START_ACQ)\n";
900 else{ pacman_command.
Data[0] = 0x00; }
903 else if(pacman_command.
Data[0] == 0x33){
904 std::cout <<
"RECV PACMAN COMMAND 0x33 (STOP_ACQ)\n";
906 else{ pacman_command.
Data[0] = 0x00; }
909 else if(pacman_command.
Data[0] == 0x44){
910 std::cout <<
"RECV PACMAN COMMAND 0x44 (STATUS_ACQ)\n";
911 pacman_command.
Data[0] = 0x00;
914 else if(pacman_command.
Data[0] == 0x55){
915 std::cout <<
"RECV PACMAN COMMAND 0x55 (PAC_FILE)\n";
916 pacman_command.
Data[0] = 0x00;
918 else if(pacman_command.
Data[0] == 0x66){
919 std::cout <<
"RECV PACMAN COMMAND 0x66 (HOST)\n";
920 pacman_command.
Data[0] = 0x00;
922 else if(pacman_command.
Data[0] == 0x77){
923 std::cout <<
"RECV PACMAN COMMAND 0x77 (ZERO_CLK)\n";
924 pacman_command.
Data[0] = 0x00;
927 std::cout <<
"RECV PACMAN COMMAND 0x" << std::hex << (int)pacman_command.
Data[0] << std::dec <<
" (?)\n";
928 pacman_command.
Data[0] = 0x00;
937 if(cmd ==
"_SIGSEGV_"){
942 else if(cmd ==
"CTRL_D"){
943 std::cout <<
sys_message_head <<
"Received EOF (ctrl-d) signal. Exiting...\n";
946 else if(cmd ==
"CTRL_C"){
949 std::cout <<
" Stopping MCA...\n";
953 std::cout <<
" Ignoring signal.\n";
957 else if(cmd ==
"CTRL_Z"){
958 std::cout <<
sys_message_head <<
"Warning! Received SIGTSTP (ctrl-z) signal.\n";
962 if (cmd.find(
"\t") != std::string::npos) {
966 else if (arg.find(
"\t") != std::string::npos) {
967 if(cmd ==
"pread" || cmd ==
"pwrite")
969 else if(cmd ==
"pmread" || cmd ==
"pmwrite")
971 else if(cmd ==
"toggle")
977 if(cmd ==
""){
continue; }
979 std::vector<std::string> arguments;
980 unsigned int p_args =
split_str(arg, arguments);
985 if(cmd ==
"quit" || cmd ==
"exit"){
994 else if(cmd ==
"kill"){
1003 else if(cmd ==
"help" || cmd ==
"h"){
help(); }
1004 else if(cmd ==
"version" || cmd ==
"v"){
1010 else if(cmd ==
"status"){
1013 else if(cmd ==
"thresh"){
1020 else if(cmd ==
"dump"){
1021 std::ofstream ofile;
1024 ofile.open(arg.c_str());
1026 std::cout <<
sys_message_head <<
"Failed to open output file '" << arg <<
"'\n";
1032 ofile.open(
"./Fallback.set");
1034 std::cout <<
sys_message_head <<
"Failed to open output file './Fallback.set'\n";
1043 for(
unsigned int param = 0; param < chan_params.size(); param++){
1044 forChannel<std::string>(
pif, -1, -1, chanReader, chan_params[param]);
1048 for(
unsigned int param = 0; param < mod_params.size(); param++){
1052 if(p_args >= 1){ std::cout <<
sys_message_head <<
"Successfully wrote output parameter file '" << arg <<
"'\n"; }
1053 else{ std::cout <<
sys_message_head <<
"Successfully wrote output parameter file './Fallback.set'\n"; }
1056 else if(cmd ==
"pwrite" || cmd ==
"pmwrite"){
1058 std::cout <<
sys_message_head <<
"Warning! Cannot edit pixie parameters while acquisition is running\n\n";
1062 if(cmd ==
"pwrite"){
1063 if(p_args > 0 && arguments.at(0) ==
"help"){
pchan_help(); }
1064 else if(p_args >= 4){
1065 int modStart, modStop;
1067 std::cout <<
"ERROR: Invalid module argument: '" << arguments.at(0) <<
"'\n";
1070 int chStart, chStop;
1072 std::cout <<
"ERROR: Invalid channel argument: '" << arguments.at(1) <<
"'\n";
1077 std::string &valueStr = arguments.at(3);
1078 if (valueStr.find_last_not_of(
"+-eE0123456789.") != std::string::npos &&
1079 !((valueStr.find(
"0x") == 0 || valueStr.find(
"0X") == 0) &&
1080 valueStr.find_first_not_of(
"0123456789abcdefABCDEF", 2) == std::string::npos) ) {
1081 std::cout <<
"ERROR: Invalid parameter value: '" << valueStr <<
"'\n";
1086 try { value = std::stod(valueStr); }
1087 catch (
const std::invalid_argument &ia) {
1088 std::cout <<
"ERROR: Invalid parameter value: '" << valueStr <<
"'\n";
1094 for (
int mod = modStart;
mod <= modStop;
mod++) {
1095 for (
int ch = chStart;
ch <= chStop;
ch++) {
1104 std::cout <<
sys_message_head <<
"Invalid number of parameters to pwrite\n";
1105 std::cout << sys_message_head <<
" -SYNTAX- pwrite <module> <channel> <parameter> <value>\n";
1108 else if(cmd ==
"pmwrite"){
1109 if(p_args > 0 && arguments.at(0) ==
"help"){
pmod_help(); }
1110 else if(p_args >= 3){
1111 int modStart, modStop;
1113 std::cout <<
"ERROR: Invalid module argument: '" << arguments.at(0) <<
"'\n";
1118 std::string &valueStr = arguments.at(2);
1119 if (valueStr.find_last_not_of(
"0123456789") != std::string::npos &&
1120 !((valueStr.find(
"0x") == 0 || valueStr.find(
"0X") == 0) &&
1121 valueStr.find_first_not_of(
"0123456789abcdefABCDEF", 2) == std::string::npos) ) {
1122 std::cout <<
"ERROR: Invalid parameter value: '" << valueStr <<
"'\n";
1129 try { value = (
unsigned int) std::stod(valueStr); }
1130 catch (
const std::invalid_argument &ia) {
1131 std::cout <<
"ERROR: Invalid parameter value: '" << valueStr <<
"'\n";
1137 for (
int mod = modStart;
mod <= modStop;
mod++) {
1145 std::cout <<
sys_message_head <<
"Invalid number of parameters to pmwrite\n";
1146 std::cout << sys_message_head <<
" -SYNTAX- pmwrite <module> <parameter> <value>\n";
1150 else if(cmd ==
"pread" || cmd ==
"pmread"){
1152 std::cout <<
sys_message_head <<
"Warning! Cannot view pixie parameters while acquisition is running\n\n";
1157 if(p_args > 0 && arguments.at(0) ==
"help"){
pchan_help(); }
1158 else if(p_args >= 3){
1159 int modStart, modStop;
1161 std::cout <<
"ERROR: Invalid module argument: '" << arguments.at(0) <<
"'\n";
1164 int chStart, chStop;
1166 std::cout <<
"ERROR: Invalid channel argument: '" << arguments.at(1) <<
"'\n";
1171 for (
int mod = modStart;
mod <= modStop;
mod++) {
1172 for (
int ch = chStart;
ch <= chStop;
ch++) {
1178 std::cout <<
sys_message_head <<
"Invalid number of parameters to pread\n";
1179 std::cout << sys_message_head <<
" -SYNTAX- pread <module> <channel> <parameter>\n";
1182 else if(cmd ==
"pmread"){
1183 if(p_args > 0 && arguments.at(0) ==
"help"){
pmod_help(); }
1184 else if(p_args >= 2){
1185 int modStart, modStop;
1187 std::cout <<
"ERROR: Invalid module argument: '" << arguments.at(0) <<
"'\n";
1192 for (
int mod = modStart;
mod <= modStop;
mod++) {
1197 std::cout <<
sys_message_head <<
"Invalid number of parameters to pmread\n";
1198 std::cout << sys_message_head <<
" -SYNTAX- pread <module> <parameter>\n";
1202 else if(cmd ==
"adjust_offsets"){
1204 std::cout <<
sys_message_head <<
"Warning! Cannot edit pixie parameters while acquisition is running\n\n";
1209 int modStart, modStop;
1211 std::cout <<
"ERROR: Invalid module argument: '" << arguments.at(0) <<
"'\n";
1217 for (
int mod = modStart;
mod <= modStop;
mod++) {
1223 std::cout <<
sys_message_head <<
"Invalid number of parameters to adjust_offsets\n";
1224 std::cout << sys_message_head <<
" -SYNTAX- adjust_offsets <module>\n";
1227 else if(cmd ==
"find_tau"){
1229 std::cout <<
sys_message_head <<
"Warning! Cannot edit pixie parameters while acquisition is running\n\n";
1236 int mod = atoi(arguments.at(0).c_str());
1237 int ch = atoi(arguments.at(1).c_str());
1243 std::cout <<
sys_message_head <<
"Invalid number of parameters to find_tau\n";
1244 std::cout << sys_message_head <<
" -SYNTAX- find_tau <module> <channel>\n";
1247 else if(cmd ==
"toggle"){
1249 std::cout <<
sys_message_head <<
"Warning! Cannot edit pixie parameters while acquisition is running\n\n";
1256 int modStart, modStop;
1258 std::cout <<
"ERROR: Invalid module argument: '" << arguments.at(0) <<
"'\n";
1261 int chStart, chStop;
1263 std::cout <<
"ERROR: Invalid channel argument: '" << arguments.at(1) <<
"'\n";
1268 std::string dum_str =
"CHANNEL_CSRA";
1270 for (
int mod = modStart;
mod <= modStop;
mod++) {
1271 for (
int ch = chStart;
ch <= chStop;
ch++) {
1280 std::cout <<
sys_message_head <<
"Invalid number of parameters to toggle\n";
1281 std::cout << sys_message_head <<
" -SYNTAX- toggle <module> <channel> <CSRA bit>\n";
1285 else if(cmd ==
"toggle_bit"){
1287 std::cout <<
sys_message_head <<
"Warning! Cannot edit pixie parameters while acquisition is running\n\n";
1297 flipper.
SetBit(arguments.at(3));
1299 if(
forChannel(
pif, atoi(arguments.at(0).c_str()), atoi(arguments.at(1).c_str()), flipper, arguments.at(2))){
1304 std::cout <<
sys_message_head <<
"Invalid number of parameters to toggle_any\n";
1305 std::cout << sys_message_head <<
" -SYNTAX- toggle_any <module> <channel> <parameter> <bit>\n";
1308 else if(cmd ==
"csr_test"){
1312 std::string &valueStr = arguments.at(0);
1313 if (valueStr.find_last_not_of(
"0123456789") != std::string::npos &&
1314 !((valueStr.find(
"0x") == 0 || valueStr.find(
"0X") == 0) &&
1315 valueStr.find_first_not_of(
"0123456789abcdefABCDEF", 2) == std::string::npos) ) {
1316 std::cout <<
"ERROR: Invalid parameter value: '" << valueStr <<
"'\n";
1322 try { value = (
unsigned int) std::stod(valueStr); }
1323 catch (
const std::invalid_argument &ia) {
1324 std::cout <<
"ERROR: Invalid parameter value: '" << valueStr <<
"'\n";
1331 std::cout <<
sys_message_head <<
"Invalid number of parameters to csr_test\n";
1332 std::cout << sys_message_head <<
" -SYNTAX- csr_test <number>\n";
1335 else if(cmd ==
"bit_test"){
1340 std::vector<std::string> empty_vector;
1341 flipper.
Test((
unsigned int)atoi(arguments.at(0).c_str()), std::strtoul(arguments.at(1).c_str(), NULL, 0), empty_vector);
1344 std::cout <<
sys_message_head <<
"Invalid number of parameters to bit_test\n";
1345 std::cout << sys_message_head <<
" -SYNTAX- bit_test <num_bits> <number>\n";
1348 else if(cmd ==
"get_traces"){
1350 std::cout <<
sys_message_head <<
"Warning! Cannot view live traces while acquisition is running\n\n";
1357 int mod = atoi(arguments.at(0).c_str());
1358 int chan = atoi(arguments.at(1).c_str());
1360 if(mod < 0 || chan < 0){
1361 std::cout <<
sys_message_head <<
"Error! Must select one module and one channel to trigger on!\n";
1365 std::cout <<
sys_message_head <<
"Error! Invalid module specification (" << mod <<
")!\n";
1368 else if(chan > NUMBER_OF_CHANNELS){
1369 std::cout <<
sys_message_head <<
"Error! Invalid channel specification (" << chan <<
")!\n";
1373 int trace_threshold = 0;
1377 trace_threshold = atoi(arguments.at(2).c_str());
1378 if(trace_threshold < 0){
1380 trace_threshold = 0;
1388 std::cout <<
sys_message_head <<
"Invalid number of parameters to get_traces\n";
1389 std::cout << sys_message_head <<
" -SYNTAX- get_traces <mod> <chan> [threshold]\n";
1392 else if(cmd ==
"quiet"){
1402 else if(cmd ==
"debug"){
1418 else if(cmd ==
"timedrun"){
1420 double runSeconds = strtod(arg.c_str(), NULL);
1427 std::cout <<
sys_message_head <<
"Invalid number of parameters to timedrun\n";
1428 std::cout << sys_message_head <<
" -SYNTAX- timedrun <seconds>\n";
1431 else if(cmd ==
"startacq" || cmd ==
"startvme"){
1434 else if(cmd ==
"stop" || cmd ==
"stopacq" || cmd ==
"stopvme"){
1437 else if(cmd ==
"shm"){
1447 else if(cmd ==
"reboot"){
1455 else if(cmd ==
"hup" || cmd ==
"spill"){
1460 else if(cmd ==
"fdir"){
1481 std::cout <<
sys_message_head <<
"Next file will be '" << filename <<
"'.\n";
1484 else if (cmd ==
"prefix") {
1505 else if(cmd ==
"title"){
1512 if (arg.find_first_of(
'"') == 0 && arg.find_last_of(
'"') == arg.length() - 1)
1522 else if(cmd ==
"runnum"){
1539 std::cout <<
sys_message_head <<
"Next file will be '" << filename <<
"'.\n";
1542 else if(cmd ==
"oform"){
1544 int format = atoi(arg.c_str());
1545 if(format == 0 || format == 1 || format == 2){
1548 if(output_format == 1){ std::cout <<
" Warning! This output format is experimental and is not recommended for data taking\n"; }
1549 else if(output_format == 2){ std::cout <<
" Warning! This output format is experimental and is not recommended for data taking\n"; }
1553 std::cout <<
sys_message_head <<
"Unknown output file format ID '" << format <<
"'\n";
1554 std::cout <<
" Available file formats include:\n";
1555 std::cout <<
" 0 - .ldf (HRIBF) file format (default)\n";
1556 std::cout <<
" 1 - .pld (PIXIE) file format (experimental)\n";
1557 std::cout <<
" 2 - .root file format (slow, not recommended)\n";
1563 else if(cmd ==
"mca" || cmd ==
"MCA"){
1569 std::cout <<
sys_message_head <<
"Warning! Cannot run MCA program while acquisition is running\n\n";
1574 std::string type = arguments.at(0);
1593 else{ std::cout <<
sys_message_head <<
"Unknown command '" << cmd <<
"'\n"; }
1595 else{ std::cout <<
sys_message_head <<
"Unknown command '" << cmd <<
"'\n"; }
1605 time_t acqStartTime;
1618 printf(
"Press Enter key to continue...");
1629 else{ std::cout <<
sys_message_head <<
"Performing infinite MCA data run. Type \"stop\" to quit\n"; }
1681 time(&acqStartTime);
1683 else std::cout <<
"Acq";
1684 std::cout <<
" started on " << ctime(&acqStartTime);
1691 std::cout <<
sys_message_head <<
"Failed to start list mode run. Try rebooting PIXIE\n";
1707 if(
runTime > 0.0 && difftime(currentTime, acqStartTime) >=
runTime)
1733 std::stringstream leader;
1734 leader <<
"Run end status in module " <<
mod;
1752 else std::cout <<
"Acq";
1753 std::cout <<
" stopped on " << ctime(¤tTime);
1778 std::cout <<
"Run Control exited\n";
1782 std::stringstream status;
1816 static std::vector< std::pair<double, double> > xiaRates(16, std::make_pair<double, double>(0,0));
1823 for (
int ch=0;
ch< numChPerMod;
ch++)
1836 std::vector<word_t> nWords(
n_cards);
1838 std::vector<word_t>::iterator maxWords;
1841 for (
unsigned int timeout = 0; timeout <
POLL_TRIES; timeout++){
1847 maxWords = std::max_element(nWords.begin(), nWords.end());
1855 size_t dataWords = 0;
1863 fifoData[dataWords++] = 2;
1864 fifoData[dataWords++] =
mod;
1867 else if (nWords[
mod] < 0) {
1868 std::cout <<
Display::WarningStr(
"Number of FIFO words less than 0") <<
" in module " <<
mod << std::endl;
1870 fifoData[dataWords++] = 2;
1871 fifoData[dataWords++] =
mod;
1879 <<
" size: " << nWords[
mod] <<
"/" 1889 fifoData[dataWords++] =
mod;
1897 std::cout <<
Display::ErrorStr() <<
" Unable to read " << nWords[
mod] <<
" from module " << mod <<
"\n";
1905 std::cout <<
"Read " << nWords[
mod] <<
" words from module " <<
mod;
1907 std::cout <<
" and stored " <<
partialEvents[
mod].size() <<
" partial event words";
1908 std::cout <<
" to buffer position " << dataWords << std::endl;
1917 size_t parseWords = dataWords;
1919 word_t eventSize = 0, prevEventSize = 0;
1921 while (parseWords < dataWords + nWords[mod]) {
1924 word_t slotRead = ((fifoData[parseWords] & 0xF0) >> 4);
1925 word_t chanRead = (fifoData[parseWords] & 0xF);
1926 eventSize = ((fifoData[parseWords] & 0x7FFE2000) >> 17);
1927 bool virtualChannel = ((fifoData[parseWords] & 0x20000000) != 0);
1929 if( slotRead != slotExpected ){
1931 <<
" not the same as slot expected " 1932 << slotExpected << std::endl;
1935 if (chanRead < 0 || chanRead > 15) {
1936 std::cout <<
Display::ErrorStr() <<
" Channel read (" << chanRead <<
") not valid!\n";
1951 parseWords += eventSize;
1952 prevEventSize = eventSize;
1957 if (parseWords > dataWords + nWords[mod]) {
1958 word_t missingWords = parseWords - dataWords - nWords[
mod];
1959 word_t partialSize = eventSize - missingWords;
1960 if (
debug_mode) std::cout <<
"Partial event " << partialSize <<
"/" << eventSize <<
" words!\n";
1963 for(
unsigned short i=0;i< partialSize;i++)
1964 partialEvents[mod].push_back(fifoData[parseWords - eventSize + i]);
1967 nWords[
mod] -= partialSize;
1970 else if (parseWords < dataWords + nWords[mod]) {
1972 std::cout <<
Display::ErrorStr() <<
" Parsing indicated corrupted data for module " << mod <<
".\n";
1973 std::cout <<
"| Parsing failed at " << parseWords - dataWords <<
"/" << nWords[
mod]
1974 <<
" (" << parseWords <<
"/" << dataWords + nWords[
mod] <<
") words into FIFO." << std::endl;
1977 std::cout <<
"|\n| Event prior to parsing error (" << prevEventSize <<
" words):";
1978 std::cout << std::hex << std::setfill(
'1');
1979 for(
size_t i=0;i< prevEventSize;i++) {
1980 if (i%5 == 0) std::cout << std::endl <<
"| ";
1981 std::cout <<
"0x" << std::right << std::setw(8) << std::setfill(
'0');
1982 std::cout << fifoData[parseWords - prevEventSize + i] <<
" ";
1984 std::cout << std::dec << std::setfill(
' ') << std::endl;
1987 std::cout <<
"|\n| Event at parsing error (" << eventSize <<
" words):";
1988 size_t outputSize = eventSize;
1989 if (eventSize > 50) {
1991 std::cout <<
"\n| (Truncated at " << outputSize <<
" words.)";
1993 std::cout << std::hex << std::setfill(
'0');
1994 for(
size_t i=0;i< outputSize;i++) {
1995 if (i%5 == 0) std::cout << std::endl <<
"| ";
1996 std::cout <<
"0x" << std::right << std::setw(8) << std::setfill(
'0');
1997 std::cout << fifoData[parseWords + i] <<
" ";
1999 std::cout << std::dec << std::setfill(
' ') << std::endl;
2003 word_t nextEventSize = 0;
2004 if (parseWords + eventSize < dataWords + nWords[mod]) {
2005 nextEventSize = ((fifoData[parseWords + eventSize] & 0x7FFE2000) >> 17);
2007 std::cout <<
"|\n| Event after parsing error (" << nextEventSize <<
" words):";
2010 outputSize = nextEventSize;
2011 if (eventSize > 50) outputSize = 50;
2012 if (parseWords + eventSize + outputSize >= dataWords + nWords[mod])
2013 outputSize = dataWords + nWords[
mod] - (parseWords + eventSize);
2014 if (outputSize != nextEventSize)
2015 std::cout <<
"\n| (Truncated at " << outputSize <<
" words.)";
2017 std::cout << std::hex << std::setfill(
'0');
2018 for(
size_t i=0;i< outputSize;i++) {
2019 if (i%5 == 0) std::cout << std::endl <<
"| ";
2020 std::cout <<
"0x" << std::right << std::setw(8);
2021 std::cout << fifoData[parseWords + eventSize + i] <<
" ";
2023 std::cout << std::dec << std::setfill(
' ') << std::endl <<
"|\n";
2031 fifoData[dataWords - 2] = nWords[
mod] + 2;
2033 dataWords += nWords[
mod];
2039 lastSpillTime = spillTime;
2049 if (!
is_quiet ||
debug_mode) std::cout <<
"Writing/Broadcasting " << dataWords <<
" words.\n";
2064 int power = std::log10(size);
2065 std::stringstream output;
2066 output << std::setprecision(3);
2067 if (power >= 9) output << size/pow(1024,3) <<
"GB";
2068 else if (power >= 6) output << size/pow(1024,2) <<
"MB";
2069 else if (power >= 3) output << size/1024 <<
"kB";
2070 else output <<
" " << size <<
"B";
2071 return output.str();
2075 std::string
pad_string(
const std::string &input_,
unsigned int length_){
2076 std::string output = input_;
2077 for(
unsigned int i = input_.size(); i <= length_; i++){
2083 std::string
yesno(
bool value_){
2084 if(value_){
return "Yes"; }
#define POLL2_SOCKET_DATE
bool GetStatistics(unsigned short mod)
void TabComplete(const std::string &input_, const std::vector< std::string > &possibilities_)
Handle tab complete functionality.
void Close()
Close the socket.
std::string WarningStr(const std::string &str="[WARNING]")
std::vector< word_t > * partialEvents
A vector to store the partial events.
std::string output_directory
Time to run the acquisition, in seconds.
Server * server
UDP client for network access.
bool Init(bool offlineMode=false)
bool Initialize(PixieInterface *pif_)
static const std::vector< std::string > pollStatusCommands_
std::string InfoStr(const std::string &str="[INFO]")
bool record_data
Set to true when the command is given to stop a run.
bool RemovePresetRunLength(int mod)
std::string sys_message_head
The main pixie interface pointer.
void CommandControl()
Main control loop for handling user input.
bool GetSlots(const char *slotF=NULL)
int DataSize
Sequence number for reliable transport.
bool do_reboot
Set to true if data is to be recorded to disk.
std::vector< std::string > mod_params
static size_t GetTraceLength(void)
#define HRIBF_BUFFERS_VERSION
static const char Reset[]
#define HRIBF_BUFFERS_DATE
void show_status()
Display run status information.
unsigned int split_str(std::string str, std::vector< std::string > &args, char delimiter=' ')
Split a string about some delimiter.
StatsHandler * statsHandler
void Close()
Close the socket.
std::vector< std::string > commands_
PixieInterface * pif
UDP server to listen for pacman commands.
double lastSpillTime
Time when the acquistion was started.
bool do_start_acq
Set to true when the program is exiting.
static size_t GetNumberChannels(void)
Controls the poll2 command interpreter and data acquisition system.
void LeaderPrint(const std::string &str)
Provides network connectivity for poll2.
int write_data(word_t *data, unsigned int nWords)
Write a data spill to disk.
void SetThreshWords(const size_t &thresh_)
void pause(bool &flag)
Disrupt ncurses while boolean is true.
int RecvMessage(char *message_, size_t length_)
double GetInputCountRate(int mod, int chan)
double GetTotalDataRate()
bool kill_all
Command line message header.
int SendMessage(char *message_, size_t length_)
bool do_stop_acq
Set to true when the command is given to start a run.
bool WriteSglModPar(const char *name, word_t val, int mod)
float GetBaseline(size_t chan_)
static const int statsInterval_
The amount time between scaler reads in seconds.
unsigned long CheckFIFOWords(unsigned short mod)
bool Test(unsigned int num_bits_, unsigned int input_, const std::vector< std::string > &text_)
void flush()
Dump all text in the stream to the output screen.
bool start_run(const bool &record_=true, const double &time_=-1.0)
Start a data recording run.
bool ReadFIFOWords(word_t *buf, unsigned long nWords, unsigned short mod, bool verbose=false)
void SetUseRoot(bool state_=true)
int Write(char *data_, unsigned int nWords_)
Write nWords_ of data to the file.
bool ReadFIFO()
Routine to read Pixie FIFOs.
unsigned int total_spill_chunks
Total number of poll data spill chunks sent over the network.
void get_traces(int mod_, int chan_, int thresh_=0)
Acquire raw traces from a pixie module.
void help()
Data packet for class shared-memory broadcast.
static const std::vector< std::string > toggle_names
static const std::vector< std::string > runControlCommands_
void SetDumpInterval(double interval)
Set the amount of time between scalers dumps in seconds.
bool Boot(int mode=0x7f, bool useWorkingSetFile=false)
void SetXiaRates(int mod, std::vector< std::pair< double, double >> *xiaRates)
Set the ICR and OCR from the XIA module.
bool acq_running
Force poll2 to dump the current data spill.
void SetTotalTime(int totalTime_)
#define CTERMINAL_VERSION
void show_thresh()
Display polling threshold.
Library to handle all aspects of a stand-alone command line interface.
bool IsNumeric(const std::string &input_, const std::string &prefix_, const std::string &msg_)
#define POLL2_CORE_VERSION
unsigned int next_run_num
Set with 'htit' command.
unsigned int udp_sequence
Pacman related variables.
void SetCSRAbit(std::string bit_)
std::string pad_string(const std::string &input_, unsigned int length_)
Pad a string with periods until it is the specified length_.
bool Init(const char *address_, int port_)
unsigned int GetRunNumber()
bool GetModuleInfo(const unsigned short &mod, unsigned short *rev, unsigned int *serNum, unsigned short *adcBits, unsigned short *adcMsps)
std::string GetNextFileName(unsigned int &run_num_, std::string prefix, std::string output_dir, bool continueRun=false)
Return the filename of the next output file.
static const std::vector< std::string > paramControlCommands_
void CSRAtest(unsigned int input_)
void PrintModuleInfo()
Prints the information about each module.
bool Close()
Close the sockets, any open files, and clean up.
bool init
Pacman shared-memory mode.
bool had_error
Set to true when run_command exits.
void broadcast_data(word_t *data, unsigned int nWords)
Broadcast a data spill onto the network.
int BufLen
The data to be transmitted.
std::vector< std::string > chan_params
bool CheckRunStatus(void)
void broadcast_pac_data()
Broadcast a data spill onto the network in the classic pacman format.
MCA_args mca_args
Set to true when the "mca" command is received.
bool stop_run()
Stop an active data recording run.
unsigned char Data[MAX_ORPH_DATA]
Number of useable bytes in Data.
Poll()
Default constructor.
void ReadScalers()
Routine to read Pixie scalers.
void pmod_help()
Print help dialogue for reading/writing pixie module parameters.
virtual bool Step()
Update the MCA histograms.
bool SaveDSPParameters(const char *fn=NULL)
void SetBit(unsigned int bit_)
bool force_spill
Set to true when the user tells POLL to reboot PIXIE.
PixieInterface::word_t word_t
virtual bool IsOpen()
Check if the histogram construction was successful.
void pchan_help()
Print help dialogue for reading/writing pixie channel parameters.
bool pac_mode
New style shared-memory mode.
PollOutputFile output_file
std::string output_title
Set with 'ouf' command.
int SendMessage(char *message_, size_t length_)
std::string GetCurrentFilename()
Get the name of the current output file.
bool run_ctrl_exit
Set to true when run_command is recieving data from PIXIE.
float GetMaximum(size_t chan_)
short GetSlotNumber(int mod) const
void SetStatus(std::string status, unsigned short line=0)
Set the status message.
void SetDebugMode(bool debug_=true)
Toggle debug mode.
void CloseFile(float total_run_time_=0.0)
Write the footer and close the file.
bool CloseOutputFile(const bool continueRun=false)
Close the current output file, if one is open.
int SendPacket(Client *cli_)
std::string ErrorStr(const std::string &str="[ERROR]")
void Clear()
Clear the stats.
bool SplitParameterArgs(const std::string &arg, int &start, int &stop)
Splits the arguments to pread and pwrite on a colon delimeter.
bool OpenOutputFile(bool continueRun=false)
Opens a new file if no file is currently open.
void UpdateStatus()
Routine to update the status message.
bool Init(int port_, int sec_=10, int usec_=0)
Initialize the serv object and open a specified port. Returns false if the socket fails to open or th...
unsigned char Data[4 *(4050+4)]
Continuation flag for large events.
void SetBasename(std::string basename_)
bool SetFileFormat(unsigned int format_)
Set the output file format.
#define EXTERNAL_FIFO_LENGTH
int TotalEvents
Number of useable bytes in Data.
std::string OkayStr(const std::string &str="[OK]")
std::string yesno(bool value_)
Return a string containing "yes" for value_==true and "no" for value_==false.
bool IsOpen()
Return true if an output file is open and writable and false otherwise.
unsigned int output_format
Set with 'hnum' command.
bool OpenNewFile(std::string title_, unsigned int &run_num_, std::string prefix, std::string output_dir="./", bool continueRun=false)
Close the current file, if one is open, and open a new file for data output.
#define POLL2_SOCKET_VERSION
bool StartHistogramRun(unsigned short mode=NEW_RUN)
bool StartListModeRun(unsigned short listMode=LIST_MODE_RUN, unsigned short runMode=NEW_RUN)
void Close(PixieInterface *pif_)
double GetRunTime()
Return the length of time the MCA has been running.
void RunControl()
Main acquisition control loop for handling data acq.
std::string filename_prefix
Set with 'fdir' command.
void AddEvent(unsigned int mod, unsigned int ch, size_t size, int delta_=1)
bool forChannel(PixieInterface *pif, int mod, int ch, PixieFunction< T > &f, T par)
double GetOutputCountRate(int mod, int chan)
unsigned short Events
Total number of events.
std::string humanReadable(double size)
Convert a rate number to more useful form.
bool Initialize()
Initialize the poll object.
double usGetTime(double par)
static const char DkYellow[]
int current_file_num
Set with 'oform' command.
unsigned short Cont
Number of events in this packet.
bool AddTime(double dtime)
std::string GetCommand(std::string &args, const int &prev_cmd_return_=0)
Wait for the user to input a command.
bool synch_mods()
Set IN_SYNCH and SYNCH_WAIT parameters on all modules.
bool boot_fast
Structure to hold arguments for MCA program.
std::streampos GetFilesize()
Get the size of the current file, in bytes.
bool forModule(PixieInterface *pif, int mod, PixieFunction< T > &f, T par)
unsigned short GetNumberCards(void) const
double GetTotalTime()
Return the total run time.