PAASS
Software suite to Acquire and Analyze Data from Pixie16
poll2.cpp
Go to the documentation of this file.
1 // poll2.cpp
2 // Cory R. Thornsberry
3 // Jan. 21st, 2015
4 //
5 // This program is designed as a replacement of the POLL program for reading
6 // VANDLE data from PIXIE-16 crates. The old POLL program relied on a connection
7 // to PACMAN in order to recieve commands whereas this is a stand-alone program
8 // with a built-in command line interface. The .ldf file format is retained, but
9 // this program does not split buffers to fit into the HRIBF standard buffer.
10 // Data is also not transmitted onto a socket (except for shm). Instead, .ldf
11 // files are generated by this program directly.
12 
13 #include <iostream>
14 #include <thread>
15 #include <utility>
16 #include <map>
17 #include <getopt.h>
18 #include <string.h>
19 
20 #include <sys/stat.h> //For directory manipulation
21 
22 #include "poll2_core.h"
23 #include "Display.h"
24 #include "CTerminal.h"
25 
26 /* Print help dialogue for command line options. */
27 void help(const char *progName_){
28  std::cout << "\n SYNTAX: " << progName_ << " [options]\n";
29  std::cout << " --alarm (-a) [e-mail] | Call the alarm script with a given e-mail (or no argument)\n";
30  std::cout << " --fast (-f) | Fast boot (false by default)\n";
31  std::cout << " --verbose (-v) | Run quietly (false by default)\n";
32  std::cout << " --no-wall-clock | Do not insert the wall clock in the data stream\n";
33  std::cout << " --rates | Display module rates in quiet mode (false by defualt)\n";
34  std::cout << " --thresh (-t) <num> | Sets FIFO read threshold to num% full (50% by default)\n";
35  std::cout << " --zero | Zero clocks on each START_ACQ (false by default)\n";
36  std::cout << " --debug (-d) | Set debug mode to true (false by default)\n";
37  std::cout << " --pacman (-p) | Use classic poll operation for use with Pacman.\n";
38  std::cout << " --help (-h) | Display this help dialogue.\n\n";
39 }
40 
41 void start_run_control(Poll *poll_){
42  poll_->RunControl();
43 }
44 
45 void start_cmd_control(Poll *poll_){
46  poll_->CommandControl();
47 }
48 
49 int main(int argc, char *argv[]){
50  // Read the FIFO when it is this full
51  unsigned int threshPercent = 50;
52  std::string alarmArgument = "";
53 
54  struct option longOpts[] = {
55  { "alarm", optional_argument, NULL, 'a' },
56  { "fast", no_argument, NULL, 'f' },
57  { "verbose", no_argument, NULL, 'v' },
58  { "no-wall-clock", no_argument, NULL, 0 },
59  { "rates", no_argument, NULL, 0 },
60  { "thresh", required_argument, NULL, 't' },
61  { "zero", no_argument, NULL, 0 },
62  { "debug", no_argument, NULL, 'd' },
63  { "pacman", no_argument, NULL, 'p' },
64  { "help", no_argument, NULL, 'h' },
65  { "prefix", no_argument, NULL, 0 },
66  { "?", no_argument, NULL, 0 },
67  { NULL, no_argument, NULL, 0 }
68  };
69 
70  // Main object
71  Poll poll;
72  poll.SetQuietMode();
73 
74  int idx = 0;
75  int retval = 0;
76 
77  //getopt_long is not POSIX compliant. It is provided by GNU. This may mean
78  //that we are not compatable with some systems. If we have enough
79  //complaints we can either change it to getopt, or implement our own class.
80  while ( (retval = getopt_long(argc, argv, "afvt:dph", longOpts, &idx)) != -1) {
81  switch(retval) {
82  case 'a':
83  alarmArgument = optarg;
84  poll.SetSendAlarm();
85  break;
86  case 'f':
87  poll.SetBootFast();
88  break;
89  case 'v':
90  poll.SetQuietMode(false);
91  break;
92  case 't' :
93  threshPercent = atoi(optarg);
94  if(threshPercent <= 0){
95  std::cout << Display::ErrorStr() << " Failed to set threshold level to (" << threshPercent << ")!\n";
96  return 1;
97  }
98  break;
99  case 'd':
100  poll.SetDebugMode();
101  break;
102  case 'p':
103  poll.SetPacmanMode();
104  break;
105  case 'h' :
106  help(argv[0]);
107  return 0;
108  case 0 :
109  if(strcmp("prefix", longOpts[idx].name) == 0 ) { // --prefix
110  std::cout << INSTALL_PREFIX <<"\n";
111  return 0;
112  }
113  else if(strcmp("no-wall-clock", longOpts[idx].name) == 0 ) { // --no-wall-clock
114  poll.SetWallClock();
115  }
116  else if(strcmp("rates", longOpts[idx].name) == 0 ) { // --rates
117  poll.SetShowRates();
118  }
119  else if(strcmp("zero", longOpts[idx].name) == 0 ) { // --zero
120  poll.SetZeroClocks();
121  }
122  break;
123  case '?' :
124  help(argv[0]);
125  return 1;
126  default :
127  break;
128  }//switch(retval)
129  }//while
130 
131  if(!poll.Initialize()){ return 1; }
132 
133  // Main interactive terminal.
134  Terminal poll_term;
135 
136  std::string poll2Dir = getenv("HOME");
137  if (!mkdir(poll2Dir.append("/.poll2/").c_str(), S_IRWXU)) {
138  if (errno == EEXIST)
139  std::cout << Display::ErrorStr() << "Unable to create poll2 settings directory '" << poll2Dir << "'!\n";
140  }
141 
142  // Initialize the terminal before doing anything else;
143  poll_term.Initialize();
144 
145  std::cout << "\n######### ##### #### #### ########\n";
146  std::cout << " ## ## ## ## ## ## ## ##\n";
147  std::cout << " ## ## ## ## ## ## ##\n";
148  std::cout << " ## ## ## ## ## ## ##\n";
149  std::cout << " ####### ## ## ## ## ##\n";
150  std::cout << " ## ## ## ## ## ##\n";
151  std::cout << " ## ## ## ## ## ##\n";
152  std::cout << " ## ## ## ## ## ##\n";
153  std::cout << " ## ## ## ## ## ## ## ##\n";
154  std::cout << "#### ##### ######### ######### ###########\n";
155 
156  std::cout << "\n POLL2 v" << POLL2_CORE_VERSION << "\n";
157  std::cout << " == == == == == \n\n";
158 
159  poll_term.SetCommandHistory(poll2Dir + "poll2.cmd");
160  poll_term.SetPrompt(Display::InfoStr("POLL2 $ ").c_str());
161  poll_term.AddStatusWindow();
162  poll_term.EnableTabComplete();
163  poll_term.SetLogFile(poll2Dir + "poll2.log");
164  if (poll.GetPacmanMode()) poll_term.EnableTimeout();
165 
166  poll.PrintModuleInfo();
167 
168  poll.SetThreshWords(EXTERNAL_FIFO_LENGTH * threshPercent / 100.0);
169  std::cout << "Using FIFO threshold of " << threshPercent << "% (" << poll.GetThreshWords() << "/" << EXTERNAL_FIFO_LENGTH << " words).\n";
170 
171 #ifdef PIF_REVA
172  std::cout << "Using Pixie16 revision A\n";
173 #elif (defined PIF_REVD)
174  std::cout << "Using Pixie16 revision D\n";
175 #elif (defined PIF_REVF)
176  std::cout << "Using Pixie16 revision F\n";
177 #else
178  std::cout << "Using unknown Pixie16 revision!!!\n";
179 #endif
180 
181  if(poll.GetPacmanMode()){ std::cout << "Using pacman mode!\n"; }
182  std::cout << std::endl;
183 
184  poll.SetTerminal(&poll_term);
185 
186  if(poll.GetSendAlarm()){
187  Display::LeaderPrint("Sending alarms to");
188  if(alarmArgument.empty()){ std::cout << Display::InfoStr("DEFAULT") << std::endl; }
189  else { std::cout << Display::WarningStr(alarmArgument) << std::endl; }
190  }
191 
192  // Start the run control thread
193  std::cout << pad_string("Starting run control thread", 49);
194  std::thread runctrl(start_run_control, &poll);
195  std::cout << Display::OkayStr() << std::endl;
196 
197  // Start the command control thread. This needs to be the last thing we do to
198  // initialize, so the user cannot enter commands before setup is complete
199  std::cout << pad_string("Starting command thread", 49);
200  std::thread comctrl(start_cmd_control, &poll);
201  std::cout << Display::OkayStr() << std::endl << std::endl;
202 
203  // Synchronize the threads and wait for completion
204  comctrl.join();
205  runctrl.join();
206 
207  // Close the output file, if one is open
208  poll.Close();
209 
210  // Close the terminal.
211  poll_term.Close();
212 
213  //Reprint the leader as the carriage was returned
214  Display::LeaderPrint(std::string("Running poll2 v").append(POLL2_CORE_VERSION));
215  std::cout << Display::OkayStr("[Done]") << std::endl;
216 
217  return 0;
218 }
bool GetPacmanMode()
Definition: poll2_core.h:298
std::string WarningStr(const std::string &str="[WARNING]")
Definition: Display.cpp:73
void EnableTimeout(float timeout=0.5)
Enable a timeout while waiting fro a command.
Definition: CTerminal.cpp:728
void start_cmd_control(Poll *poll_)
Definition: poll2.cpp:45
std::string InfoStr(const std::string &str="[INFO]")
Definition: Display.cpp:55
void SetCommandHistory(std::string filename, bool overwrite=false)
Set the command filename for storing previous commands.
Definition: CTerminal.cpp:607
void start_run_control(Poll *poll_)
Definition: poll2.cpp:41
void CommandControl()
Main control loop for handling user input.
void help(const char *progName_)
Definition: poll2.cpp:27
bool SetLogFile(std::string logFileName)
Specify the log file to append.
Definition: CTerminal.cpp:703
void Close()
Close the window and restore control to the terminal.
Definition: CTerminal.cpp:1093
Controls the poll2 command interpreter and data acquisition system.
void LeaderPrint(const std::string &str)
Definition: Display.cpp:28
void SetQuietMode(bool input_=true)
Definition: poll2_core.h:260
void SetPrompt(const char *input_)
Set the command prompt.
Definition: CTerminal.cpp:614
void SetThreshWords(const size_t &thresh_)
Definition: poll2_core.h:276
int main(int argc, char *argv[])
Definition: poll2.cpp:49
void AddStatusWindow(unsigned short numLines=1)
Initalizes a status window under the input temrinal.
Definition: CTerminal.cpp:307
void SetDebugMode(bool input_=true)
Definition: poll2_core.h:268
void SetSendAlarm(bool input_=true)
Definition: poll2_core.h:262
Library to handle all aspects of a stand-alone command line interface.
#define POLL2_CORE_VERSION
Definition: poll2_core.h:27
std::string pad_string(const std::string &input_, unsigned int length_)
Pad a string with periods until it is the specified length_.
void SetWallClock(bool input_=true)
Definition: poll2_core.h:258
size_t GetThreshWords()
Definition: poll2_core.h:302
bool GetSendAlarm()
Definition: poll2_core.h:288
void SetShowRates(bool input_=true)
Definition: poll2_core.h:264
void PrintModuleInfo()
Prints the information about each module.
Definition: poll2_core.cpp:231
bool Close()
Close the sockets, any open files, and clean up.
Definition: poll2_core.cpp:311
void SetBootFast(bool input_=true)
Definition: poll2_core.h:256
void SetZeroClocks(bool input_=true)
Definition: poll2_core.h:266
std::string ErrorStr(const std::string &str="[ERROR]")
Definition: Display.cpp:46
void SetPacmanMode(bool input_=true)
Definition: poll2_core.h:272
void EnableTabComplete(bool enable=true)
Enable tab auto complete functionlity.
Definition: CTerminal.cpp:717
#define EXTERNAL_FIFO_LENGTH
std::string OkayStr(const std::string &str="[OK]")
Definition: Display.cpp:64
void Initialize()
Initialize the terminal interface.
Definition: CTerminal.cpp:548
void RunControl()
Main acquisition control loop for handling data acq.
bool Initialize()
Initialize the poll object.
Definition: poll2_core.cpp:246
void SetTerminal(Terminal *term)
Set the terminal pointer.
Definition: poll2_core.h:279