Commit 613635f7 authored by adrien's avatar adrien
Browse files

Merge pull request #1 from a-slide/dev

Dev
parents dc9e198b 45abee36
......@@ -59,5 +59,4 @@ src/AdapterTrimmer.o
src/AdapterTrimmer.so
src/AdapterTrimmer.html
src/build/
test/local_dataset/
test/test/
test/local*
# FastqFT
Parralelized quality filter and adapter trimmer for PAIRED fastq files (Hybrid Python/C)
# Sekator 0.2
**Multithreaded quality and adapter trimmer for PAIRED fastq files (Python2.7/Cython/C)**
IN DEVELOPMENT
[see GitHub Page](http://a-slide.github.io/Sekator)
**Creation : 2015/03/31**
**Last update : 2015/03/31**
## Motivation
Sekator is a **python2.7, cython 0.21+, C** object oriented semi-compiled program performing fastq quality trimming and adapter trimming
Specific features:
* The program can parse a pair of fastq files files per sample, but many samples can be analysed together.
* Fastq reading and writing are mono-threaded, but the trimming steps are multi-threaded.
* The quality trimming step can be performed from both ends of reads with an adjustable sliding windows.
* The adapter trimming step is performed by searching imperfect matches of as many adapters as desired (or short sequences) thanks to a fast Smith and Waterman Algorithm coded in C (maintained by [Mengyao](https://github.com/mengyao/Complete-Striped-Smith-Waterman-Library)).
## Principle
1. A configuration file containing all program parameters (including sample/adpater association) is parsed and thoroughly verified for validity.
2. Paired fastq paired files are read read by read and sample by sample with a custom Fastq parser supporting **Illumina 1.8 Phred+33 quality encoding only**.
3. If required, a quality trimming of reads can be performed with a quality sliding windows, starting from both ends of reads. Reads of insufficient quality or too short after trimming are discarded, together with their paired mate.
4. If required, an adapter trimming of reads can be performed with the adapters provided for each sample. **Imperfect matches can be found anywhere in the reads for as many adapters as required** thanks to an optimized and fast Smith and Waterman Algorithm. If adapters matches are found in a read, the longest part of the read without adapter match is extracted. Reads too short after trimming are discarded, together with their paired mate.
5. The paired reads that passed thought the trimming steps are subsequently writen in new fastq.gz files (R1 and R2) in Illumina 1.8 Phred+33 quality encoding.
6. A progress bar indicates the advancement of sequence processing and a report is generated for each sample.
## Dependencies
The program was developed under Linux Mint 17 and was not tested with other OS.
In addition to python2.7 and gcc 4.8 + the following dependencies are required for proper program execution:
* cython 0.21.2+
* python package [numpy](http://www.numpy.org/) 1.7.1+
If you have pip already installed, enter the following line to install packages: ```sudo pip install numpy cython```
## Get and install Sekator
* Clone the repository or download the archive ```git clone https://github.com/a-slide/Sekator.git```
* Enter the src folder of the program folder
* Compile the C/Cython sources with the Makefile ```make``` or the setup.py ```python setup.py build_ext --inplace```. This will create the dynamic library AdapterTrimmer.so required for the adapter trimming step.
* Unnecessary files can be removed with the makefile ```make clean```
* Make the main script executable ```sudo chmod u+x Sekator.py```
* Finally, add Sekator.py to your PATH
## Usage
In the folder where fastq files will be created
Usage: Sekator.py -c Conf.txt [-i -h]
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-c CONF_FILE Path to the configuration file [Mandatory]
-i Generate an example configuration file and exit [Facultative]
An example configuration file can be generated by running the program with the option -i
The possible options are extensively described in the configuration file.
The program can be tested from the test folder with the dataset provided and the default configuration file.
```
cd ./test/result
Sekator.py -i
Sekator.py -c Sekator_conf_file.txt
```
## Authors and Contact
Adrien Leger - 2014
* <adrien.leger@gmail.com> - <adrien.leger@inserm.fr> - <adrien.leger@univ-nantes.fr>
* [Github](https://github.com/a-slide)
* [Atlantic Gene Therapies - INSERM 1089](http://www.atlantic-gene-therapies.fr/)
# -*- coding: utf-8 -*-
# @package Sekator
# @brief Perform Adapter trimming of fastq sequences
# @copyright [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
# @author Adrien Leger - 2014
# * <adrien.leger@gmail.com>
# * <adrien.leger@inserm.fr>
# * <adrien.leger@univ-nantes.fr>
# * [Github](https://github.com/a-slide)
# * [Atlantic Gene Therapies - INSERM 1089] (http://www.atlantic-gene-therapies.fr/)
#~~~~~~~CIMPORTS~~~~~~~#
# C standard library import
......@@ -39,7 +52,7 @@ cdef class AdapterTrimmer:
cdef:
uint32_t min_size, n_query, total, untrimmed, trimmed, fail
uint64_t base_trimmed
int8_t ssw_match, ssw_mismatch, ssw_ambiguous, ssw_gapO, ssw_gapE
int8_t ssw_match, ssw_mismatch, ssw_gapO, ssw_gapE
int8_t* score_mat
s_query* ql
......@@ -48,7 +61,7 @@ cdef class AdapterTrimmer:
def __init__(self, list adapter_list, int32_t min_size=30,\
float min_match_len=0.3, float min_match_score=1, int8_t ssw_match=2,\
int8_t ssw_mismatch=2, int8_t ssw_ambiguous=0, int8_t ssw_gapO=3, int8_t ssw_gapE=1):
int8_t ssw_mismatch=2, int8_t ssw_gapO=3, int8_t ssw_gapE=1):
# Initialize AdapterTrimmer from a list of adapter sequence and compute the score matrix
# based on the provided ssw scores.
......@@ -58,7 +71,6 @@ cdef class AdapterTrimmer:
# @param min_match_score Minimal score per base for the alignment of adapter and read
# @param ssw_match Gain in case of match (POSITIVE)
# @param ssw_mismatch Penalty in case of mismatch (POSITIVE)
# @param ssw_ambiguous Value in case of ambiguous base (Should remain NULL)
# @param ssw_gapO Penalty in case of gap opening (POSITIVE)
# @param ssw_gapE Penalty in case of gap extension (POSITIVE)
# @note Default values determined for 100pb reads with randomly generated 60 pb adaptors
......@@ -67,7 +79,6 @@ cdef class AdapterTrimmer:
self.min_size = min_size
self.ssw_match = ssw_match
self.ssw_mismatch = ssw_mismatch
self.ssw_ambiguous = ssw_ambiguous
self.ssw_gapO = ssw_gapO
self.ssw_gapE = ssw_gapE
......@@ -79,7 +90,7 @@ cdef class AdapterTrimmer:
self.base_trimmed = 0
# Init a score matrix
self.score_mat = score_matrix (ssw_match, ssw_mismatch, ssw_ambiguous)
self.score_mat = score_matrix (ssw_match, ssw_mismatch)
# Init a list of adapters
self.n_query = len(adapter_list)
......@@ -87,7 +98,7 @@ cdef class AdapterTrimmer:
for n, seq in enumerate(adapter_list):
self.ql[n] = self.build_query (n, seq, min_match_len, min_match_score)
def __repr__(self):
def __str__(self):
msg = "ADAPTER TRIMMER CLASS\n"
msg += "Minimal size:{} Total:{} Untrimmed:{} Trimmed:{} Fail:{} Base Trimmed:{}\n".format(
self.min_size, self.total, self.untrimmed, self.trimmed, self.fail, self.base_trimmed)
......@@ -99,7 +110,7 @@ cdef class AdapterTrimmer:
msg += "\tInteger sequence : {}\n".format("".join([str(self.ql[i].seq_int[j]) for j in range(self.ql[i].size)]))
msg += "SSW parameters\n"
msg += "Match:{} Mismatch:{} Ambiguous:{} Gap Open:{} Gap extend:{}\n".format(
self.ssw_match, self.ssw_mismatch, self.ssw_ambiguous, self.ssw_gapO, self.ssw_gapE)
self.ssw_match, self.ssw_mismatch, 0, self.ssw_gapO, self.ssw_gapE)
msg += "Score matrix\n"
buf = ""
for i in range(0, 25, 5):
......@@ -109,7 +120,7 @@ cdef class AdapterTrimmer:
buf=""
return msg
def __str__(self):
def __repr__(self):
return ("<Instance of AdapterTrimmer Class>\n")
def __dealloc__(self):
......@@ -128,7 +139,7 @@ cdef class AdapterTrimmer:
# Find imperfect adapter matches with ssw algorithm and extract the larger interval of
# reference sequence that do not overlap interval match
# @param seq HTSeq.SequenceWithQualities object
# @param seq a Fastq.FastqSeq object
cdef:
int32_t seq_size, i, start_max=0, end_max=0, inter_max=0, start=0, inter=0
......
# -*- coding: utf-8 -*-
"""
@package Sekator
@brief Contain the template of the empty configuration file for Sekator
@copyright [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
@author Adrien Leger - 2014
* <adrien.leger@gmail.com>
* <adrien.leger@inserm.fr>
* <adrien.leger@univ-nantes.fr>
* [Github](https://github.com/a-slide)
* [Atlantic Gene Therapies - INSERM 1089] (http://www.atlantic-gene-therapies.fr/)
"""
def write_example_conf():
with open ("Sekator_conf_file.txt", 'wb') as fp:
fp.write ("""
###################################################################################################
# SEKATOR CONFIGURATION FILE #
###################################################################################################
# Values can by customized with users values, but the file template must remain unchanged,
# otherwise the program will not be able to load default values.
# - File path should be indicated as absolute path preferably and should not contain blank spaces
# - Values identified with '**' in the descriptor are not recommended to be modified
###################################################################################################
[general]
# The quality encoding of your sequence have to be Illumina 1.8+ Phred+33. The program does not
# manage the other encoding scales
# Minimal size of read after trimming (POSITIVE INTEGER)
min_size = 30
# Use all available threads for parrallel processing (BOOLEAN)
auto_thread = True
# If auto_thread is "False" specify the maximal number of thread to use (POSITIVE INTEGER)
n_thread :
# Write a txt report (BOOLEAN)
write_report : True
# Compress the fastq output (BOOLEAN)
compress_output : True
###################################################################################################
[quality]
# Perform quality trimming from the left and/or extremities (BOOLEAN)
left_trim : True
right_trim : True
# Size of the sliding window in which quality will be computed (POSITIVE INTEGER)
win_size : 6
# Step of sliding window during trimming (POSITIVE INTEGER)
step : 2
# Minimal quality in a given windows to be retained during trimming (0 <= POSITIVE INTEGER <= 40)
qual_cutdown : 28
###################################################################################################
[adapter]
# Perform a step of adapter trimming (BOOLEAN)
adapter_trim : True
# Minimal fraction of the length of the adapter matching on the read (0 < FLOAT <= 1) **
min_match_len : 0.3
# Minimal SSW score/base of the adapter matching on the read (POSITIVE FLOAT <= ssw_match) **
min_match_score : 1
# Scores for stripped Smith and Waterman sequence alignment if :
# - Gain if 2 aligned bases are identical : ssw_match
# - Penalty if 2 aligned bases are different : ssw_mismatch
# - Penalty if a gap is opened : ssw_gapO
# - Penalty if a gap is extended : ssw_gapE
# All values have to be POSITIVE INTEGER. Penalty will be converted in negative scores by the
# aligner. Values were optimized for adapter match (40-60 pb) on short reads (100, 200 pb) **
ssw_match : 2
ssw_mismatch : 2
ssw_gapO : 3
ssw_gapE : 1
###################################################################################################
# SAMPLE DEFINITIONS
# It is possible to include as many independant sample as required by duplicating a entire sample
# section and incrementing the id number in the sample section name
# Each sample section is organize as follow :
# name = Unique identifier that will be used to prefix the read files (STRING)
# - R1_path = Valid path to the fastq(.gz) file containing the forward reads of the pair (STRING)
# - R1_path = Valid path to the fastq file (gziped or not) containing the reverse reads of the pair
# preferably absolute path without spaces) (STRING)
# - adapter_list = list of adapter DNA sequence to be trimmed if adapter_trimming is required.
# - Separate each adapter by a blank space (LIST OF STR)
[sample1]
name : S1_pass
R1_path : ../dataset/S1_R1_pass.fastq.gz
R2_path : ../dataset/S1_R2_pass.fastq.gz
adapter_list : GATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNATCTCGTATGCCGTCTTCTGCTTG AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT
[sample2]
name : test
R1_path : ../dataset/testR1.fastq.gz
R2_path : ../dataset/testR2.fastq.gz
adapter_list : GATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNATCTCGTATGCCGTCTTCTGCTTG AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT """)
# -*- coding: utf-8 -*-
"""
@package Sekator
@brief Contain a class to model a fastq sequence and an iterator function to read fastq files
@copyright [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
@author Adrien Leger - 2014
* <adrien.leger@gmail.com>
* <adrien.leger@inserm.fr>
* <adrien.leger@univ-nantes.fr>
* [Github](https://github.com/a-slide)
* [Atlantic Gene Therapies - INSERM 1089] (http://www.atlantic-gene-therapies.fr/)
"""
# Standard library imports
from gzip import open as gopen
# Third party imports
import numpy as np
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
class FastqSeq (object):
"""
Simple Representation of a fastq file. The object support slicing and addition operations
The quality score is a numpy array to facilitate further data manipulation
"""
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~FUNDAMENTAL AND MAGIC METHODS~~~~~~~#
def __init__ (self, name, seq, qual, descr=""):
"""
@param name Name of the sequence (without spaces)
@param seq DNA sequence string
@param qual nunpy array of the Phred Quality of bases
@param descr Facultative description
"""
self.name = name
self.seq = seq
self.qual = qual
self.descr = descr
assert len(seq) == len(qual), "Sequence length and quality string length are not equal."
def __len__ (self):
return len(self.seq)
def __repr__(self):
return "<Instance of {} from {} >".format(self.__class__.__name__, self.__module__)
def __str__(self):
if len(self) > 20:
return "{} : {}...{} {}...{}".format(self.name, self.seq[:10], self.seq[-10:], self.qual[:10], self.qual[-10:])
else:
return "{} : {} {}".format(self.name, self.seq, self.qual)
def __getitem__( self, item ):
return FastqSeq(name = self.name, seq = self.seq[ item ], qual = self.qual[ item ])
@property
def qualstr( self ):
qualstr_phred = ""
for i in self.qual:
qualstr_phred += str(unichr(i+33))
return qualstr_phred
#~~~~~~~PUBLIC METHODS~~~~~~~#
def get_fastq_str(self):
""" Return string formated as a fastq sequence """
return "@{}\n{}\n+\n{}\n".format(self.name, self.seq, self.qualstr)
def __add__(self, other):
return FastqSeq(
name = "{}_{}".format(self.name, other.name),
seq = self.seq+other.seq,
qual = np.concatenate((self.qual, other.qual)),
descr = self.descr+other.descr)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# FUNCTIONS
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
def is_gz(fp):
""" Indicate if a file is gziped """
return fp[-2:].lower() == "gz"
def FastqReader (fastq_file):
""" Simple fastq reader returning a generator over a fastq file """
try:
# Open the file depending of the compression status
fastq = gopen(fastq_file, "rb") if is_gz(fastq_file) else open(fastq_file, "rb")
i=0
# Iterate on the file until the end
while True:
# Extract informations from the fastq file
name = fastq.readline()
seq = fastq.readline()
sep = fastq.readline()
qual = fastq.readline()
# Condition of loop exit
if not name or not seq or not sep or not qual:
break
# Try to generate a valid FastqSeq object
try:
yield FastqSeq(
name = name.rstrip()[1:].split()[0],
seq = seq.rstrip(),
qual = np.array([ord(x)-33 for x in qual.rstrip()]))
i+=1
except AssertionError as E:
print(E)
print ("Skipping the sequence")
raise StopIteration("\t{} sequences parsed".format(i))
except IOError as E:
print(E)
exit()
# -*- coding: utf-8 -*-
"""
@package Sekator
@brief A simple ProgressBar for Sekator
@copyright [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
@author Adrien Leger - 2014
* <adrien.leger@gmail.com>
* <adrien.leger@inserm.fr>
* <adrien.leger@univ-nantes.fr>
* [Github](https://github.com/a-slide)
* [Atlantic Gene Therapies - INSERM 1089] (http://www.atlantic-gene-therapies.fr/)
"""
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
class ProgressBar (object):
""" Simple progress bar """
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~FUNDAMENTAL METHODS~~~~~~~#
def __init__ (self, total_seq, number_step):
"""
To be init with the total number of sequence and the desired number of steps
"""
self.total_seq = total_seq # To match 0 base index
self.number_step = number_step
self.numeric_step = int(self.total_seq/self.number_step) # Non exact steps
self.n_step = 1
assert total_seq >= number_step
#~~~~~~~PUBLIC METHODS~~~~~~~#
def __call__ (self, n):
"""
Call each iteration of the loop to verify is the progress bar needs to be updated
"""
if n%self.numeric_step == 0:
if self.n_step == self.number_step :
print("\t[{}] 100% DONE".format("X"*self.n_step))
else:
print("\t[{}{}] {}%".format(
"X"*self.n_step,
"-"*(self.number_step - self.n_step),
self.n_step*100/self.number_step))
self.n_step +=1
# -*- coding: utf-8 -*-
"""
@package Sekator
@brief Perform Quality trimming of fastq sequences
@copyright [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
@author Adrien Leger - 2014
* <adrien.leger@gmail.com>
* <adrien.leger@inserm.fr>
* <adrien.leger@univ-nantes.fr>
* [Github](https://github.com/a-slide)
* [Atlantic Gene Therapies - INSERM 1089] (http://www.atlantic-gene-therapies.fr/)
"""
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
class QualityTrimmer(object):
......@@ -40,7 +53,7 @@ class QualityTrimmer(object):
def mean_qual(self):
return self.qual_mean_sum / self.total
def __repr__(self):
def __str__(self):
msg = "QUALITY TRIMMER CLASS\n"
msg += "\tQuality cutdown : {}\n".format(self.qual_cutdown)
msg += "\tSliding windows size : {}\n".format(self.win_size)
......@@ -56,7 +69,7 @@ class QualityTrimmer(object):
msg += "\tCumulative sum of quality : {}\n".format(self.qual_mean_sum)
return (msg)
def __str__(self):
def __repr__(self):
return "<Instance of {} from {} >\n".format(self.__class__.__name__, self.__module__)
#~~~~~~~PUBLIC METHODS~~~~~~~#
......@@ -64,7 +77,7 @@ class QualityTrimmer(object):
def __call__(self, seq):
"""
Compute mean quality score and compare to the minimal quality required
@param seq HTSeq.SequenceWithQualities object
@param seq a Fastq.FastqSeq object
"""
# Update counters and init border index
......
# -*- coding: utf-8 -*-
"""
@package Sekator
@brief Helper class for Sekator to represent Samples
@copyright [GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)
@author Adrien Leger - 2014
* <adrien.leger@gmail.com>
* <adrien.leger@inserm.fr>
* <adrien.leger@univ-nantes.fr>
* [Github](https://github.com/a-slide)
* [Atlantic Gene Therapies - INSERM 1089] (http://www.atlantic-gene-therapies.fr/)
"""
# Standard library imports
import os
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
class Sample(object):
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~CLASS FIELDS~~~~~~~#
SAMPLE_NAMES = []
#~~~~~~~CLASS METHODS~~~~~~~#
@ classmethod
def ADD_TO_SAMPLE_NAMES(self, name):
self.SAMPLE_NAMES.append(name)
#~~~~~~~FUNDAMENTAL METHODS~~~~~~~#
def __init__ (self, name, R1_path, R2_path, adapter_list, compress_output):
# Create self variables
self.name = name
self.R1_path = R1_path
self.R2_path = R2_path
self.adapter_list = adapter_list
self._test_values()
self.R1_outname = "{}_R1_filtered.fastq{}".format(self.name, ".gz" if compress_output else "")
self.R2_outname = "{}_R2_filtered.fastq{}".format(self.name, ".gz" if compress_output else "")
self.ADD_TO_SAMPLE_NAMES(self.name)
# Fundamental class methods str and repr
def __str__(self):
msg = "SAMPLE CLASS\n\tParameters list\n"
# list all values in object dict in alphabetical order
keylist = [key for key in self.__dict__.keys()]
keylist.sort()
for key in keylist:
msg+="\t{}\t{}\n".format(key, self.__dict__[key])
return (msg)
def __repr__(self):
return "<Instance of {} from {} >\n".format(self.__class__.__name__, self.__module__)
#~~~~~~~PRIVATE METHODS~~~~~~~#
def _test_values(self):
assert self.name not in self.SAMPLE_NAMES, "Sample name <{}> is duplicated".format(self.name)
assert self._is_readable_file (self.R1_path), "R1_path in Sample <{}> is not valid".format(self.name)
assert self._is_readable_file (self.R2_path), "R2_path in Sample <{}> is not valid".format(self.name)
for adapter in self.adapter_list:
assert self._is_dna(adapter), "<{}> in Sample <{}> is not a valid DNA sequence".format(adapter, self.name)
def _is_readable_file (self, fp):
return os.access(fp, os.R_OK)
def _is_dna (self, sequence):
for base in sequence:
if base not in ["A","T","C","G","N","a","t","c","g","n"]:
return False
return True
......@@ -27,15 +27,13 @@ try:
import os
from gzip import open as gopen
# Third party imports
import numpy
from HTSeq import FastqReader
from HTSeq import SequenceWithQualities as HTSeq_Fastq
# Local Package import
from AdapterTrimmer import AdapterTrimmer
from QualityTrimmer import QualityTrimmer
from HTSeqProxy import SequenceWithQualitiesProxy as Proxy_Fastq
from Conf_file import write_example_conf
from Fastq import FastqSeq, FastqReader
from Sample import Sample
from ProgressBar import ProgressBar
except ImportError as E:
print (E)
......@@ -49,38 +47,62 @@ class Sekator (object):
"""
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~CLASS FIELDS~~~~~~~#
VERSION = "Sekator 0.2"
USAGE = "Usage: %prog -c Conf.txt [-i -h]"
#~~~~~~~CLASS METHODS~~~~~~~#
@classmethod
def class_init (self):
"""
init class method for instantiation from command line. Parse arguments parse CL arguments
"""
# Define parser usage, options
optparser = optparse.OptionParser(usage = self.USAGE, version = self.VERSION)