Example #1
0
int main(int argc, char *argv[]){
	if(argc >= 2 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)){ // A stupid way to do this... for now.
		Unpacker *temp_core = GetCore();
		help(argv[0], temp_core);
		delete temp_core;
		return 0;
	}
	else if(argc >= 2 && (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-v") == 0)){ // Display version information
		std::cout << " " << PROG_NAME << "-------v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n";
		std::cout << " |hribf_buffers-v" << HRIBF_BUFFERS_VERSION << " (" << HRIBF_BUFFERS_DATE << ")\n";
		std::cout << " |CTerminal-----v" << CTERMINAL_VERSION << " (" << CTERMINAL_DATE << ")\n";
		std::cout << " |poll2_socket--v" << POLL2_SOCKET_VERSION << " (" << POLL2_SOCKET_DATE << ")\n";
		return 0;
	}
	
	debug_mode = false;
	dry_run_mode = false;
	shm_mode = false;

	num_spills_recvd = 0;

	long file_start_offset = 0;

	// Fill the argument list.
	std::deque<std::string> scan_args;
	std::deque<std::string> core_args;
	int arg_index = 1;
	while(arg_index < argc){
		scan_args.push_back(std::string(argv[arg_index++]));
	}

	Unpacker *core = GetCore(); // Get a pointer to the main Unpacker object.
	
	// Loop through the arg list and extract ScanMain arguments.
	std::string current_arg;
	while(!scan_args.empty()){
		current_arg = scan_args.front();
		scan_args.pop_front();
	
		if(current_arg == "--debug"){ 
			core->SetDebugMode();
			debug_mode = true;
		}
		else if(current_arg == "--dry-run"){
			dry_run_mode = true;
		}
		else if(current_arg == "--fast-fwd"){
			if(scan_args.empty()){
				std::cout << " Error: Missing required argument to option '--fast-fwd'!\n";
				help(argv[0], core);
				return 1;
			}
			file_start_offset = atoll(scan_args.front().c_str());
			scan_args.pop_front();
		}
		else if(current_arg == "--quiet"){
			is_verbose = false;
		}
		else if(current_arg == "--shm"){ 
			file_format = 0;
			shm_mode = true;
			std::cout << " Using shm mode!\n";
		}
		else if(current_arg == "--ldf"){ 
			file_format = 0;
		}
		else if(current_arg == "--pld"){ 
			file_format = 1;
		}
		else if(current_arg == "--root"){ 
			file_format = 2;
		}
		else{ core_args.push_back(current_arg); } // Unrecognized option.
	}

	std::string input_filename = "";
	if(!core->SetArgs(core_args, input_filename)){ 
		help(argv[0], core);
		return 1; 
	}

	if(!shm_mode){
		extension = GetExtension(input_filename, prefix);
		if(file_format != -1){
			if(file_format == 0){ std::cout << sys_message_head << "Forcing ldf file readout.\n"; }
			else if(file_format == 1){ std::cout << sys_message_head << "Forcing pld file readout.\n"; }
			else if(file_format == 2){ std::cout << sys_message_head << "Forcing root file readout.\n"; }
		}
		else{
			if(prefix == ""){
				std::cout << " ERROR: Input filename was not specified!\n";
				return 1;
			}
		
			if(extension == "ldf"){ // List data format file
				file_format = 0;
			}
			else if(extension == "pld"){ // Pixie list data file format
				file_format = 1;
			}
			else if(extension == "root"){ // Pixie list data file format
				file_format = 2;
			}
			else{
				std::cout << " ERROR: Invalid file format '" << extension << "'\n";
				std::cout << "  The current valid data formats are:\n";
				std::cout << "   ldf - list data format (HRIBF)\n";
				std::cout << "   pld - pixie list data format\n";
				std::cout << "   root - root file containing raw pixie data\n";
				return 1;
			}
		}
	}

	// Initialize the Unpacker object.
	core->Initialize(sys_message_head);

	// Initialize the command terminal
	Terminal terminal;
	term_ = &terminal;

	if(!shm_mode){
		std::cout << sys_message_head << "Using file prefix " << prefix << ".\n";
		input_file.open((prefix+"."+extension).c_str(), std::ios::binary);
		if(!input_file.is_open() || !input_file.good()){
			std::cout << " ERROR: Failed to open input file '" << prefix+"."+extension << "'! Check that the path is correct.\n";
			input_file.close();
			return 1;
		}
	}
	else{
		if(!poll_server.Init(5555, 1)){
			std::cout << " ERROR: Failed to open shm socket 5555!\n";
			return 1;
		}

		std::string temp_name = std::string(PROG_NAME);
		
		// Only initialize the terminal if this is shared-memory mode
		terminal.Initialize(("."+temp_name+".cmd").c_str());
		terminal.SetPrompt((temp_name+" $ ").c_str());
		terminal.AddStatusWindow();

		std::cout << "\n " << PROG_NAME << " v" << SCAN_VERSION << "\n"; 
		std::cout << " ==  ==  ==  ==  == \n\n"; 
	}

	if(debug_mode){ std::cout << sys_message_head << "Using debug mode.\n"; }
	if(dry_run_mode){ std::cout << sys_message_head << "Doing a dry run.\n"; }
	if(shm_mode){ 
		std::cout << sys_message_head << "Using shared-memory mode.\n"; 
		std::cout << sys_message_head << "Listening on poll2 SHM port 5555\n";
	}

	if(!shm_mode){
		// Start reading the file
		// Every poll2 ldf file starts with a DIR buffer followed by a HEAD buffer
		int num_buffers;
		if(file_format == 0){
			dirbuff.Read(&input_file, num_buffers);
			headbuff.Read(&input_file);
			
			// Let's read out the file information from these buffers
			std::cout << "\n 'DIR ' buffer-\n";
			std::cout << "  Run number: " << dirbuff.GetRunNumber() << std::endl;
			std::cout << "  Number buffers: " << num_buffers << std::endl << std::endl;
	
			std::cout << " 'HEAD' buffer-\n";
			std::cout << "  Facility: " << headbuff.GetFacility() << std::endl;
			std::cout << "  Format: " << headbuff.GetFormat() << std::endl;
			std::cout << "  Type: " << headbuff.GetType() << std::endl;
			std::cout << "  Date: " << headbuff.GetDate() << std::endl;
			std::cout << "  Title: " << headbuff.GetRunTitle() << std::endl;
			std::cout << "  Run number: " << headbuff.GetRunNumber() << std::endl << std::endl;
		}
		else if(file_format == 1){
			pldHead.Read(&input_file);
			
			max_spill_size = pldHead.GetMaxSpillSize();
			
			// Let's read out the file information from these buffers
			std::cout << "\n 'HEAD' buffer-\n";
			std::cout << "  Facility: " << pldHead.GetFacility() << std::endl;
			std::cout << "  Format: " << pldHead.GetFormat() << std::endl;
			std::cout << "  Start: " << pldHead.GetStartDate() << std::endl;
			std::cout << "  Stop: " << pldHead.GetEndDate() << std::endl; 
			std::cout << "  Title: " << pldHead.GetRunTitle() << std::endl;
			std::cout << "  Run number: " << pldHead.GetRunNumber() << std::endl;
			std::cout << "  Max spill: " << pldHead.GetMaxSpillSize() << " words\n";
			std::cout << "  ACQ Time: " << pldHead.GetRunTime() << " seconds\n\n";
		}
		else if(file_format == 2){
		}
		
		// Fast forward in the file
		if(file_start_offset != 0){
			std::cout << " Skipping ahead to word no. " << file_start_offset << " in file\n";
			input_file.seekg(file_start_offset*4);
			std::cout << " Input file is now at " << input_file.tellg() << " bytes\n";
		}

		start_run_control(core);
	}
	else{ 
		// Start the run control thread
		std::cout << "\nStarting data control thread\n";
		std::thread runctrl(start_run_control, core);
	
		// Start the command control thread. This needs to be the last thing we do to
		// initialize, so the user cannot enter commands before setup is complete
		std::cout << "Starting command thread\n\n";
		std::thread comctrl(start_cmd_control);

		// Synchronize the threads and wait for completion
		comctrl.join();
		runctrl.join();
	
		// Close the socket and restore the terminal
		terminal.Close();
		poll_server.Close();
		
		//Reprint the leader as the carriage was returned
		std::cout << "Running " << PROG_NAME << " v" << SCAN_VERSION << " (" << SCAN_DATE << ")\n";
	}
	
	std::cout << sys_message_head << "Retrieved " << num_spills_recvd << " spills!\n";

	input_file.close();	

	// Clean up detector driver
	std::cout << "\nCleaning up...\n";
	
	core->PrintStatus(sys_message_head);
	core->Close();
	delete core;
	
	return 0;
}