Commit 071a21c0 authored by Romain Feron's avatar Romain Feron
Browse files

Initial commit

parent e67232a2
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
# Perso
/bin
/test
// ============================================================================
// gzstream, C++ iostream classes wrapping the zlib compression library.
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ============================================================================
//
// File : gzstream.C
// Revision : $Revision: 1.7 $
// Revision_date : $Date: 2003/01/08 14:41:27 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
//
// Standard streambuf implementation following Nicolai Josuttis, "The
// Standard C++ Library".
// ============================================================================
#include "gzstream.h"
#include <iostream>
#include <string.h> // for memcpy
#include <zlib.h>
#ifdef GZSTREAM_NAMESPACE
namespace GZSTREAM_NAMESPACE {
#endif
// ----------------------------------------------------------------------------
// Internal classes to implement gzstream. See header file for user classes.
// ----------------------------------------------------------------------------
// --------------------------------------
// class gzstreambuf:
// --------------------------------------
gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
if ( is_open())
return (gzstreambuf*)0;
mode = open_mode;
// no append nor read/write mode
if ((mode & std::ios::ate) || (mode & std::ios::app)
|| ((mode & std::ios::in) && (mode & std::ios::out)))
return (gzstreambuf*)0;
char fmode[10];
char* fmodeptr = fmode;
if ( mode & std::ios::in)
*fmodeptr++ = 'r';
else if ( mode & std::ios::out)
*fmodeptr++ = 'w';
*fmodeptr++ = 'b';
*fmodeptr = '\0';
file = gzopen( name, fmode);
if (file == 0)
return (gzstreambuf*)0;
opened = 1;
return this;
}
gzstreambuf * gzstreambuf::close() {
if ( is_open()) {
sync();
opened = 0;
if ( gzclose( file) == Z_OK)
return this;
}
return (gzstreambuf*)0;
}
int gzstreambuf::underflow() { // used for input buffer only
if ( gptr() && ( gptr() < egptr()))
return * reinterpret_cast<unsigned char *>( gptr());
if ( ! (mode & std::ios::in) || ! opened)
return EOF;
// Josuttis' implementation of inbuf
int n_putback = gptr() - eback();
if ( n_putback > 4)
n_putback = 4;
memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
int num = gzread( file, buffer+4, bufferSize-4);
if (num <= 0) // ERROR or EOF
return EOF;
// reset buffer pointers
setg( buffer + (4 - n_putback), // beginning of putback area
buffer + 4, // read position
buffer + 4 + num); // end of buffer
// return next character
return * reinterpret_cast<unsigned char *>( gptr());
}
int gzstreambuf::flush_buffer() {
// Separate the writing of the buffer from overflow() and
// sync() operation.
int w = pptr() - pbase();
if ( gzwrite( file, pbase(), w) != w)
return EOF;
pbump( -w);
return w;
}
int gzstreambuf::overflow( int c) { // used for output buffer only
if ( ! ( mode & std::ios::out) || ! opened)
return EOF;
if (c != EOF) {
*pptr() = c;
pbump(1);
}
if ( flush_buffer() == EOF)
return EOF;
return c;
}
int gzstreambuf::sync() {
// Changed to use flush_buffer() instead of overflow( EOF)
// which caused improper behavior with std::endl and flush(),
// bug reported by Vincent Ricard.
if ( pptr() && pptr() > pbase()) {
if ( flush_buffer() == EOF)
return -1;
}
return 0;
}
// --------------------------------------
// class gzstreambase:
// --------------------------------------
gzstreambase::gzstreambase( const char* name, int mode) {
init( &buf);
open( name, mode);
}
gzstreambase::~gzstreambase() {
buf.close();
}
void gzstreambase::open( const char* name, int open_mode) {
if ( ! buf.open( name, open_mode))
clear( rdstate() | std::ios::badbit);
}
void gzstreambase::close() {
if ( buf.is_open())
if ( ! buf.close())
clear( rdstate() | std::ios::badbit);
}
#ifdef GZSTREAM_NAMESPACE
} // namespace GZSTREAM_NAMESPACE
#endif
// ============================================================================
// EOF //
// ============================================================================
// gzstream, C++ iostream classes wrapping the zlib compression library.
// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ============================================================================
//
// File : gzstream.h
// Revision : $Revision: 1.5 $
// Revision_date : $Date: 2002/04/26 23:30:15 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
//
// Standard streambuf implementation following Nicolai Josuttis, "The
// Standard C++ Library".
// ============================================================================
#ifndef GZSTREAM_H
#define GZSTREAM_H 1
// standard C++ with new header file names and std:: namespace
#include <iostream>
#include <fstream>
#include <zlib.h>
#ifdef GZSTREAM_NAMESPACE
namespace GZSTREAM_NAMESPACE {
#endif
// ----------------------------------------------------------------------------
// Internal classes to implement gzstream. See below for user classes.
// ----------------------------------------------------------------------------
class gzstreambuf : public std::streambuf {
private:
static const int bufferSize = 47+256; // size of data buff
// totals 512 bytes under g++ for igzstream at the end.
gzFile file; // file handle for compressed file
char buffer[bufferSize]; // data buffer
char opened; // open/close state of stream
int mode; // I/O mode
int flush_buffer();
public:
gzstreambuf() : opened(0) {
setp( buffer, buffer + (bufferSize-1));
setg( buffer + 4, // beginning of putback area
buffer + 4, // read position
buffer + 4); // end position
// ASSERT: both input & output capabilities will not be used together
}
int is_open() { return opened; }
gzstreambuf* open( const char* name, int open_mode);
gzstreambuf* close();
~gzstreambuf() { close(); }
virtual int overflow( int c = EOF);
virtual int underflow();
virtual int sync();
};
class gzstreambase : virtual public std::ios {
protected:
gzstreambuf buf;
public:
gzstreambase() { init(&buf); }
gzstreambase( const char* name, int open_mode);
~gzstreambase();
void open( const char* name, int open_mode);
void close();
gzstreambuf* rdbuf() { return &buf; }
};
// ----------------------------------------------------------------------------
// User classes. Use igzstream and ogzstream analogously to ifstream and
// ofstream respectively. They read and write files based on the gz*
// function interface of the zlib. Files are compatible with gzip compression.
// ----------------------------------------------------------------------------
class igzstream : public gzstreambase, public std::istream {
public:
igzstream() : std::istream( &buf) {}
igzstream( const char* name, int open_mode = std::ios::in)
: gzstreambase( name, open_mode), std::istream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::in) {
gzstreambase::open( name, open_mode);
}
};
class ogzstream : public gzstreambase, public std::ostream {
public:
ogzstream() : std::ostream( &buf) {}
ogzstream( const char* name, int mode = std::ios::out)
: gzstreambase( name, mode), std::ostream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::out) {
gzstreambase::open( name, open_mode);
}
};
#ifdef GZSTREAM_NAMESPACE
} // namespace GZSTREAM_NAMESPACE
#endif
#endif // GZSTREAM_H
// ============================================================================
// EOF //
\ No newline at end of file
# Compiler options
CC = g++
OPTCFLAGS = -Ofast
CFLAGS = -Wall -std=c++11 $(OPTCFLAGS)
LDFLAGS = -pthread -static-libstdc++ -lz
# Directory organisation
BASEDIR = .
BIN = $(BASEDIR)/bin
BUILD = $(BASEDIR)/build
INCLUDE = $(BASEDIR)/include
SRC = $(BASEDIR)/src
CPP = $(wildcard $(SRC)/*.cpp)
# Target
TARGET = stacks_replacement
# Variables
OBJS = $(addprefix $(BUILD)/, $(notdir $(CPP:.cpp=.o)))
# Rules
all: init print-OBJS $(TARGET)
print-% : ; @echo $* = $($*)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -I $(INCLUDE) -o $(BIN)/$(TARGET) $^ $(LDFLAGS)
$(BUILD)/%.o: $(SRC)/%.cpp
$(CC) $(CFLAGS) -I $(INCLUDE) -c -o $@ $^
clean:
rm -rf $(BUILD)/*.o
rm -rf $(BIN)/$(TARGET)
init:
mkdir -p $(BUILD) $(BUILD)
mkdir -p $(BIN) $(BIN)
rebuild: clean $(TARGET)
#include "analysis.h"
void analysis(Parameters& parameters) {
std::vector<InputFile> input_files = get_input_files(parameters);
std::unordered_map<std::string, std::unordered_map<std::string, uint16_t>> results;
std::vector<std::thread> threads;
std::mutex results_mutex, files_mutex;
for (uint i=0; i<parameters.n_threads; ++i) {
threads.push_back(std::thread(file_processor, std::ref(input_files), std::ref(results), std::ref(results_mutex), std::ref(files_mutex)));
}
for (auto &t : threads) t.join();
std::vector<std::string> individuals;
for (auto i: input_files) individuals.push_back(i.individual_name);
write_output(parameters.output_file, individuals, results);
}
void file_processor(std::vector<InputFile>& input_files, std::unordered_map<std::string, std::unordered_map<std::string, uint16_t>>& results, std::mutex& results_mutex, std::mutex& files_mutex) {
bool remaining_files = true;
while (remaining_files) {
files_mutex.lock();
for (std::vector<InputFile>::iterator it = input_files.begin(); it != input_files.end(); ++it) {
if (not it->processed) {
it->processed = true;
remaining_files = true;
process_file(*it, results, results_mutex);
break;
} else {
remaining_files = false;
}
}
files_mutex.unlock();
}
return;
}
#pragma once
#include <thread>
#include "input_dir.h"
#include "process_file.h"
#include "output.h"
void analysis(Parameters& parameters);
void file_processor(std::vector<InputFile>& input_files, std::unordered_map<std::string, std::unordered_map<std::string, uint16_t>>& results, std::mutex& results_mutex, std::mutex& files_mutex);
#include "arg_parser.h"
ArgParser::ArgParser(int &argc, char **argv) {
for (auto i=1; i < argc; ++i) this->fields.push_back(std::string(argv[i]));
if (this->contains("-h")) {
this->usage();
exit(0);
}
if (!this->contains("-i")){
std::cout << std::endl << "** Error: no input directory specified" << std::endl;
this->usage();
exit(0);
}
if (!this->contains("-o")){
std::cout << std::endl << "** Error: no output file specified" << std::endl;
this->usage();
exit(0);
}
}
void ArgParser::set_parameters(Parameters& parameters) {
parameters.n_threads = std::stoul(this->set_value("-t"));
parameters.input_dir_path = std::string(realpath(this->set_value("-i").c_str(), NULL));
parameters.output_file_path = this->set_value("-o");
// Add a trailing "/"
if (parameters.input_dir_path.back() != '/') parameters.input_dir_path += "/";
//Need to check that the string given for dir path is really a dir before converting to absolute path
parameters.input_dir = opendir(parameters.input_dir_path.c_str());
if (!parameters.input_dir) {
std::cout << "Error: input directory does not exist (" << parameters.input_dir_path << ")." << std::endl;
exit(0);
}
parameters.output_file.open(parameters.output_file_path);
if (not parameters.output_file.is_open()) {
std::cout << "Error: cannot open output file (" << parameters.output_file_path << ")." << std::endl;
exit(0);
}
}
const std::string ArgParser::get_value(const std::string& setting) const {
std::vector<std::string>::const_iterator itr = std::find(this->fields.begin(), this->fields.end(), setting);
if (itr != this->fields.end() && ++itr != this->fields.end()) {
return *itr;
}
return "";
}
bool ArgParser::contains(const std::string &option) const {
return std::find(this->fields.begin(), this->fields.end(), option) != this->fields.end();
}
const std::string ArgParser::set_value(const std::string& field) {
if (this->contains(field)) return this->get_value(field);
else return this->options.at(std::string(field))[0];
}
void ArgParser::usage() {
std::cout << std::endl << "Usage: stacks_replacement -i input_dir -o output_file [-t threads]" << std::endl;
std::cout << std::endl << "Options:" << std::endl << std::endl;
for (auto o: this->options) std::cout << "\t" << o.first << " <" << o.second[1] << "> " << o.second[2] << " [" << o.second[0] << "]" << std::endl;
std::cout << std::endl;
}
void ArgParser::print_parameters() {
std::cout << "\n- Parameters:\n";
for (auto o: this->options) {
if (o.first != "-h") std::cout << "\t" << "- " << o.second[2] << " : " << this->set_value(o.first) << "\n";
}
std::cout << "\n";
}
#pragma once
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <iostream>
#include "parameters.h"
class ArgParser {
public:
// Options: flag -> [default, type, help message]
std::map<std::string, std::vector<std::string>> const options { {"-h", {"0", "bool", "Prints this message"} },
{"-t", {"1", "int", "Number of threads"} },
{"-i", {"", "string", "Input directory"} },
{"-o", {"", "string", "Output file"} }
};
ArgParser(int& argc, char** argv);
void set_parameters(Parameters& parameters);
const std::string get_value(const std::string& setting) const;
bool contains(const std::string &option) const ;
const std::string set_value(const std::string& field);
void usage();
void print_parameters();
private:
std::vector<std::string> fields;
};