1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#include <boost/program_options.hpp>
#include "../lib/headers.h"
#include "../lib/definitions.h"
#include "../lib/kindex.h"
#include "../lib/alnstream.h"
#include "../lib/alnout.h"
#include "../lib/parallel.h"
#include "../lib/argument_parser.h"
namespace po = boost::program_options;
AlignmentSettings globalAlignmentSettings;
KixRun* idx;
mutex_map<std::string> fileLocks;
/**
* Main function that organizes the overall structure of the program.
* @param argc Number of arguments
* @param argv Argument array
* @return 0 on success, other numbers on error
*/
int main(int argc, const char* argv[]) {
// Program start output
std::cout << std::endl << "__________________________________________________________________________" << std::endl << std::endl << "HiLive Output Tool v"<< HiLive_VERSION_MAJOR << "." << HiLive_VERSION_MINOR <<
" - Output of Realtime Alignments of Illumina Reads" << std::endl << "__________________________________________________________________________" << std::endl<< std::endl;
// Parse the command line arguments
HiLiveOutArgumentParser argumentParser(argc, argv);
int parser_returnStatus = argumentParser.parseCommandLineArguments();
// Successful execution of "help" or "license"
if ( parser_returnStatus == 1 ) {
exit(EXIT_SUCCESS);
}
// Parsing error
else if ( parser_returnStatus == -1 ) {
std::cout << "Parsing of command line options failed. For help, type 'hilive-out --help'." << std::endl;
exit(EXIT_FAILURE);
}
// load the index
std::cout << "Loading Index Header..." << std::endl;
idx = new KixRun();
//
// index->get_header_information(globalAlignmentSettings.get_index_fname());
// index->store_kmer();
idx->load_metadata( globalAlignmentSettings.get_index_fname() );
idx->load_fmindex( globalAlignmentSettings.get_index_fname() );
std::cout << "Start writing ouput." << std::endl;
// Maximum number of output threads.
CountType max_output_threads = std::max(CountType(1), globalAlignmentSettings.get_num_out_threads());
std::cout << "Using " << max_output_threads << " threads." << std::endl;
std::deque<AlnOut> alnouts;
std::deque<std::thread> threads;
bool all_finished = false;
for ( CountType cycle : globalAlignmentSettings.get_output_cycles() ) {
alnouts.emplace_back(globalAlignmentSettings.get_lanes(), globalAlignmentSettings.get_tiles(), cycle);
}
while ( !all_finished ) {
all_finished = true;
CountType num_active_threads = 0;
for ( auto& alnout : alnouts ) {
num_active_threads += alnout.get_task_status_num( RUNNING );
}
for ( auto& alnout : alnouts ) {
// Assume that all tasks are available.
for ( auto& lane : globalAlignmentSettings.get_lanes() ) {
for ( auto& tile : globalAlignmentSettings.get_tiles() ) {
alnout.set_task_available( Task(lane, tile, alnout.get_cycle()) );
}
}
if ( !alnout.is_finished() ) {
all_finished = false;
if ( num_active_threads < max_output_threads ) {
CountType newThreads = max_output_threads - num_active_threads;
for ( auto i=0; i < newThreads; i++) {
threads.emplace_back(&AlnOut::write_next, &alnout);
++num_active_threads;
}
}
} else if ( !alnout.is_finalized() ) {
alnout.finalize();
std::cout << "Finished output of cycle " << alnout.get_cycle() << " (" << alnout.get_task_status_num( FINISHED ) << " finished, " << alnout.get_task_status_num( FAILED ) << " failed)." << std::endl;
}
}
std::this_thread::sleep_for (std::chrono::milliseconds(1000));
}
// Clear the vector will destruct all elements.
alnouts.clear();
// Ensure that all threads are finished.
for ( auto& thread : threads )
thread.join();
std::cout << "Finished." << std::endl;
delete idx;
return EXIT_SUCCESS;
}
|