diff --git a/.gitignore b/.gitignore index b8bd0267..42f62cb4 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,42 @@ *.exe *.out *.app + +# eclipse files +.project +.settings +.cproject +.autotools +.* + +# temporary autotools files +config.* +Makefile +autom4te.cache +configure +missing +install-sh +depcomp +aclocal.m4 +Makefile.in +compile +*/.deps +*/.deps/* +/intaRNA-*.tar.gz + + +# temp dir +tmp +tmp/* +tests/logs +tests/logs/* + +/1 +/RNAup +/IntaRNA-1 +/IntaRNA-1.out2 +/q.fasta +/q2.fasta +/seq.fasta +/t.fasta +/t2.fasta diff --git a/.travis.yml b/.travis.yml index 9405fc51..594adbc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,44 @@ -sudo: false language: cpp +cache: + apt: true + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.9 + - g++-4.9 + os: - - linux + - linux + compiler: - - gcc - + - gcc + +before_install: + - wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh + - chmod +x miniconda.sh + - "./miniconda.sh -b" + - export PATH=/home/travis/miniconda2/bin:$PATH + - conda update --yes conda + - conda install --yes viennarna automake boost -c conda-forge -c bioconda + - export CONDA_PATH=/home/travis/miniconda2/ + - export CONDA_LIB_PATH=/home/travis/miniconda2/lib + - ls $CONDA_LIB_PATH + - ls $CONDA_PATH/include + - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CONDA_LIB_PATH + script: - # download and compile ViennaRNA dependency - - wget https://depot.galaxyproject.org/software/vienna_rna/vienna_rna_1.8_src_all.tar.gz - - tar xvfz vienna_rna_1.8_src_all.tar.gz - - cd ViennaRNA-1.8.5 && ./configure --prefix=$HOME/vienna --without-perl && make && make install - - cd $TRAVIS_BUILD_DIR && ./configure --with-RNA=$HOME/vienna --prefix=$HOME/IntaRNA && make && make install - - $HOME/IntaRNA/bin/IntaRNA -h + - RNAalifold --version + ##### start IntaRNA build ##### + - cd $TRAVIS_BUILD_DIR + # generate autotools's files + - bash autotools-init.sh + - CC=gcc-4.9 CXX=g++-4.9 ./configure --with-boost=$CONDA_PATH --with-RNA=$CONDA_PATH --prefix=$HOME/IntaRNA + # compile, test and install IntaRNA + - make && make tests && make install + ##### check IntaRNA build ##### + # run IntaRNA with help output + - $HOME/IntaRNA/bin/IntaRNA -h diff --git a/AUTHORS b/AUTHORS index fbc21bae..74bf2617 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,15 @@ -Anke Busch http://www.bioinf.uni-freiburg.de/~abusch/ -Andreas Richter http://www.bioinf.uni-freiburg.de/ -Sven Siebert + +############################################################# + version 2.* +############################################################# + +- Martin Mann + +############################################################# + version 1.* +############################################################# + +- Anke Busch +- Andreas Richter +- Sven Siebert + diff --git a/COPYING b/COPYING deleted file mode 120000 index 7a694c96..00000000 --- a/COPYING +++ /dev/null @@ -1 +0,0 @@ -LICENSE \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..fc9a34e3 --- /dev/null +++ b/COPYING @@ -0,0 +1 @@ +see LICENSE file \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 9888b64d..018bfd7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,1400 @@ + +170206 Martin Mann : + * src/Makefile.am : + + AUTOMAKE_OPTIONS = std-options : checks for std options of binary + * tests/Makefile.am : + * tests now build via 'check' make target (autotools-based setup) + * Makefile.am : + * adaptions to test Makefile changes + +170203 Martin Mann : + * configure.ac : + + check for VRNA >= 2.3.0 via function 'vrna_md_copy' exists + * AccessibilityConstraint + + maxBpSpan + getter : maximal base pair span to be considered for + accessibility computation + * Accessibility* : + - getES() : now part of InteractionEnergy interface + * AccessibilityVrna : + - EsMatrix : moved to InteractionEnergyVrna + - esValues : moved to InteractionEnergyVrna + - computeES() : moved to InteractionEnergyVrna + * constructor() : + - plFoldL : now via AccessibilityConstraint.getMaxBpSpan() + - computeES + * ED >= 0 ensured + * InteractionEnergy : + * getES*() now abstract and to be implemented in subclass + - getES*() implementation based on Accessibility interface + * InteractionEnergyBasePair : + + getES*() : throws exception since not implemented yet + * constructor() : + + initES : whether or not to compute precompute ES values + * InteractionEnergyVrna : + * constructor() : + + initES : whether or not to compute precompute ES values + + EsMatrix data type + + esValues1/2 : optional ES value data + + getES*() : returns esValues* entry if available; throws exception otherwise + + computeES() : inits ES values based on VRNA routines + * VrnaHandler : + * getModel() : + * uses now vrna_md_copy() (VRNA >= 2.3.0) for model copying + * CommandLineParsing : + * energy : + - 'F' : replaced by 'V' + + 'V' : VRNA based computation + - OutputMode : replaced by char encoding + * outMode : now char encoding + * OutputHandlerText : + + detailedOutput : flag to switch between detailed and reduced output + * add() : + + heads detailedOutput flag + * construction() : + + detailedOutput flag handling + * PredictorMfe2d : + * initHybridE() : + + outConstraint argument + * bugfix : maxE check was not considering outConstraint.maxE + * fillHybridE() : + + outConstraint argument + * PredictorMfe4d* : + * predict : + * bugfix : maxE check was not considering outConstraint.maxE + +170202 Martin Mann : + * CommandLineParsing : + * outMaxE maximum now 999 (was 0) + - PredictionMode : replaced by char-based setup + * seedMaxUPq -> seedQMaxUP + * seedMaxUPt -> seedTMaxUP + * seedRangeq -> seedQRange + * seedRanget -> seedTRange + + pred + validator : setup of prediction target (mfe-si, maxprob-si, ...) + * predMode : + * char-based setup + - max-prob mode (now selected via --pred=P) + * outOverlap : char-based setup + * outAccFileq -> outQAccFile + * outAccFilet -> outTAccFile + * outPuFileq -> outQPuFile + * outPuFilet -> outTPuFile + * get*Accessibility() : + * computeES setup now via pred.val + * getPredictor() : + + support for different prediction targets via pred.val switch + * OutputConstraint : + * constructor() : + - (maxE < 0) check removed + + intarna_config.h.in : header containing package version and configure + information + * configure.ac : + + generate intarna_config.h + + AC_SUBST(INTARNA_MULITHREADING) + * AccessibilityDisabled : + * getES() : + - no error is thrown anymore + * perl/*.pl : adaptions to CLI changes + +170201 Martin Mann : + * CommandLineParsing : + * max sequence number now 99999 + * setup of threads parameter only if INTARNA_MULITHREADING + * configure.ac : + + --disabled-multithreading : sets INTARNA_MULITHREADING to 0, otherwise 1 + * enclose all OMP stuff with INTARNA_MULITHREADING preprocessor checks + * AccessibilityVrna : + * computeES() : bugfix + +170131 Martin Mann : + * CommandLineParsing : + + opts_cmdline_short : short option list for abbreviated help output + * constructor() : + + setup of opts_cmdline_short + * parse() + + handling of short and full help output + + disallow multi-threading for IntaRNA v1 output (due to separators) + * q|tAcc : renamed 'F' option to 'C' for 'computation of accessibilities' + * adaption to OutputHandlerIntaRNA1* rename + + OutputMode::V1_NORMAL : normal version 1.* output + + threads + validate + getter : OMP max thread number + - OutputHandlerIntaRNA1detailed : renamed to OutputHandlerIntaRNA1 + + OutputHandlerIntaRNA1 : former OutputHandlerIntaRNA1detailed + + detailedOutput : flag to switch between detailed and normal v1 output + + OMP : ensure no parallel write to output stream + * perl/IntaRNA*_1ui.pl : + + normal output enabled (-o flag now with effect) + * intaRNA : + * adaption to OutputHandlerIntaRNA1* rename + + OMP : parallelization of target/query processing + + OMP : exception handling within parallelized loops due to missing OMP + exception forwarding + * final exception handling now always returns -1 (even in debug mode) + * OutputHandlerCsv : + + E_loops output + + OMP : ensure no parallel write to output stream + * OutputHandlerText : + + OMP : ensure no parallel write to output stream + * AccessibilityVrna : + + OMP : ensure no parallel VRNA-calls since not threadsafe + + m4/m4_ax_openmp.mp4 : OMP checks + * configure.ac : + - backward compatibility stuff for autoconf < 2.65 + + OMP check and AM_CXXFLAGS setup + +170130 Martin Mann : + * CommandLineParsing : + + stdinUsed : flag to ensure STDIN is used for input only once + + setStdinUsed() : sets stdinUsed = true if not already or throws log + otherwise + * q/tAcc : + + 'P' : unpaired probabilities in RNAplfold style from --q/tAccFile + + 'E' : ED values in RNAplfold-Pu-like style from --q/tAccFile + + validate_q/tAccFile() + * get*Accessibility() : + + AccessibilityFromStream support + * bugfix : maxLength setup has to be = min(maxLength,accW) + + outAccFile* + validate : output ED values to file/stream + + outPuFile* + validate : output Pu values to file/stream + + validate_outputTarget() : generic text function for stream names + * validate_out() : calls validate_outputTarget() + + write*Accessibility() : write the given accessibility to file/stream if + requested by the user + + writeAccessibility() : writes accessibility data to file/stream in the + requested format + * q/tIntLenMax argument info : + + information that --q/tAccW might overwrite + * Accessibility : + * getMaxLength() : return value non-const size_t + + writeRNAplfold_ED_text() : Pu output in RNAplfold style + + writeRNAplfold_Pu_text() : ED output in RNAplfold style + + writeRNAplfold_text() : generic RNAplfold Pu-styled text output + * AccessibilityFromStream : + + InStreamType::ED_RNAplfold_Text : ED input in RNAplfold style + + parseED_RNAplfold_text() : read ED input in RNAplfold style + * parsePu_RNAplfold_text() : using parseRNAplfold_text() + + parseRNAplfold_text() : generic RNAplfold Pu-styled text input + + reduces availMaxLength if not enough data in input and outputs a user + information + + availMaxLength : stores the maximal window length parsed from the input, + init = Accessibility::getMaxLength() + + getMaxLength() : provides availMaxLength + * AccessibilityVrna : + * getED() : + + accessibility constraint check + * AccessibilityConstraint : + + isAccessible( range ) + + isMarkedAccessible( range ) + + isMarkedBlocked( range ) + + isUnconstrained( range ) + * README.md : + + docu for read/write of ED and Pu values for accessibility initialization + +170129 Martin Mann : + * PredictorMfe2dHeuristic* : + * fillHybrid*() : + + interaction length check before energy evaluation + +170128 Martin Mann : + * Makefile : + + info for testing directive + * AccessibilityDisabled : + * constructor : + - defaults removed + * AccessibilityVrna : + * constructor : + * argument order changed + + AccessibilityFromStream : populates ED values from stream + + InStreamType::Pu_RNAplfold_Text + + parsePu_RNAplfold_Text() : parse RNAplfold unpaired probability text output + * CommandLineParsing : + + q/tAccFile : file/stream to read accessibilities from + + q/tAcc : + + 'P' : read unpaired probability from file : RNAplfold text output + + stream name checks now case insensitive + +170127 Martin Mann : + * SeedConstraint : + + maxED + getter : maximal ED value per sequence for a seed region + * constructor () + + maxED + * SeedHandler : + * fillSeed() : + + skip seed regions with ED > maxED + * RnaSequence : + * SequenceAlphabet order changed + * OutputHandlerText : + * add() : + + seed ED values added + * OutputHandlerCsv : + + Pu, seedPu, start/end, ED, E_*, seedStart/End, seedED + * id : replacement of colSep occurrences + * CommandLineParsing : + + seedMinPu + validator + * constructor() : + + seedMaxED argument + * outCsvCol : + spaces to unlink ID list + * outCsvCols_default = id1,start1,end1,id2,start2,end2,subseqDP,hybridDP,E + * intaRNA : + + storing of queryAcc object to avoid recomputation for different targets + +170126 Martin Mann : + * Interaction : + + dotBracket() : converts to VRNA-like dot-bracket notation + + dotBar() : converts to position+interaction encoding using dot and bar + + dotSomething() : generic function to generate substrings for dotBracket() + and dotBar() + * test/Interaction : + + dotBracket() + + dotBar() + * PredictorMfe : + * reportOptima() : + * bugfix : nextBest() called too often + * OutputHandlerText : + * add(range) inlined + + OutputHandlerCsv : produces customizable CVS table output + * CommandLineParsing : + * OutputMode : + + CSV + + outCsvCols* + validator : argument variable + default value + + initOutputHandler() : prints initial output + * constructor : + * outMode argument : support for CSV + + outCsvCols argument + * out argument : short option removed + * parse() : + + parseStyle setup to guide parsing + - intial output moved to initOutputHandler() + + initOutputHandler() call + + CSV check + * getOutputHandler() : + + CSV + * intaRNA : + + generic exception handling + +170125 Martin Mann : + * perl/*.pl : + * bugfix : -L setup was using -w argument + +170123 Martin Mann : + * AccessibilityVrna : + * fillByConstraints() : bugfix of line shift for ED filling + * fillByRNAplfold() : + * fillByRNAup() : + + explicit handling of Pu == 0 to trigger ED = ED_UPPER_BOUND + * intaRNA : + * debug exception catch message extended (debugger hint) + * PredictorMfe2dHeuristic : + * PredictorMfe2dHeuristicSeed : + * traceBack() : bugfix : right boundary (j1,j2) could be inserted again + * loop check simplified + * CommandLineParsing : + * fix of plfold L <= W check (only enabled if W>0) + +170122 Martin Mann : + * AccessibilityVrna : + * fillByRNAplfold : bugfix memleak (pl return value not freed) + * consistent use of CLEANUP() to deallocate memory allocations done via 'new' + * intaRNA : + * global try-catch-block now always enabled but forwards exception in debug + mode (for debugger use) + * PredictorMaxProb* : + * PredictorMfe4d* : + * clear() : bugfix memleak (4th dimension not freed) + * RnaSequence : + * SequenceAlphabet now 'ACGUN' to simplify checks + +170120 Martin Mann : + * Accessibility : + + getES() : computes the ensemble energy of all local structures of a + subsequence under the assumption that the subsequence is part of a + multiloop + * AccessibilityDisabled : + + getES() : throws an exception since not computable + * AccessibilityVrna : + + EsMatrix type = triangular matrix + + esValues : stores ES values if non-NULL + + getES() : computed via McCaskill algorithm + * constructor() : + * vrnaHandler now const + + computeES argument to trigger ES computation + * RNAup-based ED computation also when plFoldW > seqLength + + computeES() : computes the ES values via VRNA 3 interface + * CommandLineParsing : + * get*Accessibility() : + + computeES flag = true in DEBUG mode (has to be replace by predictor + selection based setup) + * InteractionEnergy : + * getES*() : now implemented based on accS*.getES() + + getEU() abstract : energy for k unpaired bases within a multiloop + * InteractionEnergyBasePair : + - getES*() : implemented in superclass + + getEU() : returns 0 + * InteractionEnergyIdxOffset : + + getEU() forward + * InteractionEnergyVrna : + - getES*() : implemented in superclass + + getEU() : returns k * VRNA.MLbase + * ReverseAccessibility : + + getES() forward + +170119 Martin Mann : + * CommandLineParsing : + + out : output stream selection + + outStream : output stream to write to + + argument 'outMode' : former 'out' + * argument 'out' now sets output stream + * getOutputStream() : returns now outStream + * destructor() + + deletion of outStream if file stream + * parse() : + + creation of file stream for output if out != STDOUT|STDERR + * perl/*.pl : + * adaptions to argument change + +170118 Martin Mann : + * CommandLineParsing : + * validate_sequenceArgument() : + * parseSequences() : + * uses now RnaSequence::isValidSequenceIUPAC() + +170117 Martin Mann : + * RnaSequence : + * SequenceAlphabet : now 'ACGU' only + + SequenceAlphabetIUPAC : all IUPAC-conform nucleotide encodings + * areComplementary() : + * getCodeForChar() : + * getUpperCase() : + + checks in debug mode only + * isAmbiguous() : + * check reduced to 'N' + * RnaSequence() : + * ambiguity check uses now converted sequence + + isValidSequenceIUPAC() : check for IUPAC conformity + * CommandLineParsing : + * validateSequenceAlphabet() : + * now checks with RnaSequence::isValidSequenceIUPAC() + + information about IUPAC sequence encoding + +170111 Martin Mann : + * CommandLineParsing : + * IntaRNA v1 input details corrected + +161230 Martin Mann : + * CommandLineParsing : + * parseSequencesFasta() : + + bugfix : was not reading final lines without newline at the end + * OutputHandlerIntaRNA1detailed : + * output corrected + +161229 Martin Mann : + * CommandLineParsing : + * IntaRNA_v1_detailed init output now more like v1 output + * PredictorMfe2dHeuristic* : + * getNextBest() : + * bugfix : seq1 range overlap check + * PredictorMfe4d : + * getNextBest() : + * bugfix : getE() using wrong index order + * PredictorMfe4dSeed : + * getNextBest() : + * bugfix : getE() using wrong index order + * predict() : + * bugfix : hybridE_seed resize missing + * fillHybridE_seed() : + + additional early check for too small interaction sites (no seed) + * traceBack() : + * bugfix : energy check right of seed corrected + * bugfix : check entry existence before access + * intaRNA : + + exception catch + handling only in non-debug mode (eases debug) + +161224 Martin Mann : + * OutputHandler : + + reportedInteractions : count of reported interactions + + reported() : returns reportedInteractions + * intaRNA : + + setup of separator output for IntaRNA v1 output + * OutputHandlerIntaRNA1detailed : + + intialOutputDone : tag to store whether or not something was already done + + prinSeparator : tag whether or not a separator is to be printed + * constructor() + - initial output (now part of add()) + * add() + + initial output for first reported interactions + + counting of non-empty interactions + + addSeparator() : sets printSeparator + +161222 Martin Mann : + * perl/IntaRNA_1ui.pl : + - seed energy restriction (only needed to mimic IntaRNA v1 behaviour) + + output mode setup + * CommandLineParsing : + + OutputMode : enum for different output modes + + PredictionMode_min/max + + outMode + validator : output mode argument variable + * predMode : init via min/max enum entries + * constructor : + * argument values via toString() and enum entries to be consistent + + '--out,-o' : argument to setup output mode + * parse() : + + IntaRNA1_detailed input output + * getOutputHandler() : + - IntaRNA1_detailed input output + + switch based on outMode.val + * getPredictor() : + + PredictorMfe4dSeed support + * OutputHandlerIntaRNA1detailed : + * output corrected + + perl/IntaRNA_up_1ui.pl : IntaRNA v1-styled interface wrapper for IntaRNA_up, + i.e. RNAup like computation (4d space&time) including seed constraints + + PredictorMfe4dSeed : seed-constraint incorporating full RNAup-like predictor + +161221 Martin Mann : + * RnaSequence : + * SequenceAlphabet += tT + * getUpperCase() : + * replacement of 'T' with 'G' + * Predictor : + * updateOptima() : additional flag to avoid recomputation of overall energy + * PredictorMfe2dHeuristic* : + * fillHybridE() : + + temporary vars to reduce full energy recomputation + * SeedHandler : + * fillSeed() : + + returns now the number of valid seeds found + * PredictorMfe2dHeuristicSeed : + * predict() : + + stops computation if + + no seed interaction possible + + mfe without seed not < outConstraint.maxE + * SeedHandler : + * best hybrid energy now via table access (avoid recomputation) + * Predictor*Seed : + * bugfix : reported seed energy missed E_init term + * OutputHandlerIntaRNA1detailed : + * bugfix : newline missing at end of each interaction output + +161219 Martin Mann : + * src/Makefile : + * bin file name changed to "IntaRNA" + * .travis : bin file name changed + + perl/IntaRNA-1ui.pl : wrapper to enable IntaRNA v1 like parameter usage + * OutputConstraint : + + maxE : maximal energy to be reported + * CommandLineParsing : + + outMaxE + validator : argument for maximal energy of reported interactions + * PredictorMfe : + * initOptima() : initializes with OutputConstraint.maxE + * reportOptima() : ensures energy is below OutputConstraint.maxE + * .gitignore : + + .* : all hidden files ignored + + perl/Makefile.am + + perl wrapper packaging and install + * configure.ac : + + perl/Makefile + +161216 Martin Mann : + * README.md + + feature comparison table started + + configure.ac : + * -fopenmp now always added to CXXFLAGS (also if VRNA path not specified) + + OutputHandlerIntaRNA1detailed : output similar to IntaRNA v1.2.* + * CommandLineParsing : + * getOutputHandler() : + + temporarily : init output of IntaRNA 1.* mode + * temporarily : IntaRNA 1 output + + getOutputStream() : stream to be passed to OutputHandler instances + +161215 Martin Mann : + * AccessibilityConstraint : + * construction : bugfix reverse handling + * CommandLineParsing : + * getSeedConstraint() + + now with energy argument arguments to access seed lengths + + reverses seed ranges for seq2 + * IndexRangeList : + * List now std::list (before std::vector) + + covers(range) + tests + + reverse() + tests : reverses the indices and range order + * PredictorMfe2d : + * PredictorMfe2dSeed : + * predict() : bugfix : throw without "new" + * Predictor*Seed : + * bugfix : uses now SeedHandlerIdxOffset instead of SeedHandler + + seed handler offset setup + * RnaSequence : + * areComplementary() : bugfix : throw without "new" + * SeedConstraint : + * members not const (otherwise getter not needed) + + getRanges*() : write access for ranges + * SeedHandler : + * public functions virtual + + offset* : index offset (needed for restricted matrices) + * fillSeed() : + * bugfix : sanity checks corrected + * bugfix : index offset was missing + * traceBack() : + * bugfix : index offset was missing + + SeedHandlerIdxOffset : index shift wrapper for SeedHandler + +161214 Martin Mann : + * intaRNA : + * query/target enumeration swapped, such that seq1 == target in prediction + and output + * OutputConstraint : data structure defining all output constraints + + enum ReportOverlap : 4 possibilities where overlapping is allowed + + reportMax : max number of (suboptimal) interactions to report + + reportOverlap : the overlap constraint for reported interactions + + deltaE : maximal energy difference to mfe to be reported + * Predictor : + * reportMax/reportNonOverlapping replaced by outConstraint + * predict() + * initOptima() + * reportOptima() + * IndexRange : + + regex : regex to match valid string encoding + + fromString() : parse string encoding + + operator == () + + operator != () + * operator << () : now regex conform + * IndexRangeList : + + regex : regex to match valid string encoding + + fromString() : parse string encoding + * operator << () : regex conform + + operator == () + + operator != () + * insert() : + + no duplicated insertions + + overlap checks + * overlaps() : bugfix of predecessor check + + shift() : shifts all indices by a given term and creates a new valid list + * CommandLineParsing : + - outNonOverlapping : replaced by outOverlap + - isOutNonOverlapping() : obsolete + - isOutputReportMax() : obsolete + + outOverlap + validator : overlap encoding + + getOutputConstraint() : central data structure for output constraints´ + - regexRangeEncoding : obsolete due to IndexRangeList::regex + * parseRegion() : now uses IndexRangeList string constructor and shift() for + initialization + * general : + + E_precisionEpsilon : variable holding the precision epsilon value for + energy equivalence comparisons + * SeedConstraint : + + range1 + getter : ranges for seed search in seq1 + + range2 + getter : ranges for seed search in seq2 + +161213 Martin Mann : + * PredictorMfe2d : + * initHybridE : + * code optimizations to reduce lookups + * Predictor* : + + initOptima() + + updateOptima() + + reportOptima() + = generic optima handling + - *Mfe() : replaced by *Optima() + - *MaxPro() : replaced by *Optima() + * IndexRangeList : + + overlaps( range r ) : whether or not one of the ranges overlaps with r + + tests + * Predictor* : + * reportOptima( parameters ) + * PredictorMfe : + + reportedInteractions : index range lists to enable non-overlapping + interaction reporting + + getNextBest() : abstract interface to access the next best non-overlapping + interaction (based on reportedInteractions) + -> implemented by all subclasses + * reportOptima() : now screens for non-overlapping suboptimal interactions + using getNextBest() + +161212 Martin Mann : + * InteractionEnergy* : + + getES*() : ensemble energy of intramolecular substructures within a given + sequence interval under the assumption that the region is part of an + intermolecular multiloop, i.e. contains at least one intramolecular bp + NOTE: not implemented yet, only functions set up + * CommandLineParsing : + + oNumber + validator : max number of subopts to report + + oNonOverlapping : whether or not overlapping interactions to report + + opts_output : new output param category + + getOutputNumber() + + isOutputNonOverlapping() + * intaRNA : + + predict() calls now with getOutputNumber() and isOutputNonOverlapping() + * Interaction : + + compareEnergy() : checks whether a given interaction has energy higher + than a given value + * operator << (BasePair) now externally defined + * Predictor* : + * predict( + reportMax, + reportNonOverlapping ) : for multi-interaction out + * PredictorMfe : + * initMfe( + reportMax, + reportNonOverlapping ) : for multiple + overlapping interaction reporting + - mfeInteraction : replaced by list of interactions + + InteractionList : type of double-linked list of interactions + + mfeInteractions : list of (overlapping) lowest energy interactions + + traceBack() : now part of abstract interface to be used in reportMfe() + + reportMfe() : for all interactions from list with E<0: calls traceBack() + and adds to output handler + * updateMfe() : + + lowest energy interaction list update + + exclusion of duplicated list insertions (e.g. due to matrix recomputation) + +161207 Martin Mann : + * Interaction : + - addInteraction() : obsolete + + seedRange : optional seed information + + setSeedRange() : initializes or overwrites seedRange + * PredictorMfe2dSeed : + * PredictorMfe2dHeuristicSeed : + * traceBack() : + + storing seed interaction information + * OutputHandlerText : + * add() : + + seed information printed (if available) + + interaction position printed + + energy unit added + +161120 Martin Mann : + * autotools-init.sh : + * sh -> bash + + pipefail : script fails on first failed command + * CommandLineParsing : + + new predictors registered + * default predictor : heuristic + + time/space infor for each predictor + * bugfix: accessibility length/window check now after individual checks + * Interaction : + + ostream operator for Interaction::BasePair + * ostream operator uses BasePair operator to reduce redundancy + + SeedHandler : central handler for seed interaction and access for a given + SeedConstraint + + fillSeed() : computes the seed information + + traceBackSeed() : traces a specific seed start + + getSeedE() : the seed energy for a seed start (or INF if no seed possible) + + getSeedLength*() : the seed length for a seed start (or 0 if not possible) + * PredictorMfe : + * updateMfe() : + - dangling end based pre-check removed (not sure if valid) + * PredictorMfe2d : + * interface documentation corrected + * PredictorMfe2dSeed : + - seed calculation methods and data structure (move to SeedHandler) + + seedHandler (generated in constructor) + * fillHybridE_seed() : + * bugfix : init of all cells was not ensured + * sanity checks now include lower i boundary + * PredictorMfe4d : prediction info adapted + + PredictorMfe2dHeuristic : heuristic mfe prediction in n^2 time and space + + PredictorMfe2dHeuristicSeed : heuristic mfe prediction in n^2 time and space + including seed constraint + +161023 Martin Mann : + * AccessibilityConstraint : + - isBlocked() : renamed to isMarkedBlocked() + * isAccessible() : now : whether or not a position is available for + interaction + + isMarkedAccessible() : former isAccessible() + + isMarkedBlocked() : former isBlocked() + * AccessibilityDisabled : + * getED() : checks now for constraint.isAccessible() + * InteractionEnergy : + + getBasePair() : generates an Interaction BasePair for given indices + + getIndex*() : generates the computation indices for a given base pair + + getED*() : fast access to ED of a sequence + + isAccessible*() : checks for accessibility and non-ambiguity + + size*() : sequence length + * isValidInteraction() : now protected + * isAllowedLoopRegion() : now protected + + InteractionEnergyIdxOffset : wrapper for an InteractionEnergy that handles + index shifts due to a given offset. To this end, all according functions are + overwritten, which eases formulations of Predictors. + * Predictor : + * energy : now InteractionEnergyIdxOffset object + * PredictorXXX : + - i*offset : obsolete due to energy class change + * all offsets are now obsolete with extended InteractionEnergy interface and + InteractionEnergyIdxOffset energy access : this simplifies the formulation + of the algorithms and makes debugging easier. + - test/InteractionEnergy_test.cpp : obsolete + +161020 Martin Mann : + * configure.ac : + + boost_regex lib registered + * CommandLineParsing : + + argument qRegion : query interaction regions (sorted, non-overlapping) + + argument tRegion : target interaction regions + + getter and validator + + regexRangeEncoding : regex to validate range string encodings + + parseRegion() : parses region argument + * IndexRange : + * constructor() : + * default to = RnaSequence::lastPos + * IndexRangeList : + * push_back() : ascending check corrected + * intaRNA : + + predicts only for all index range combinations + * ReverseAccessibility : + + getReversedIndexRange() : reverses an index range + * PredictorMfe2dSeed : + * bugfix : rotating seedE_rec usage not possible; reset to full 5D array + * bugfix : index offset added + +161019 Martin Mann : + + m4/m4_ax_cxx_compile_stdcxx.m4 : enables c11 compiler support check + * configure.ac : + + ensures c11 compiler compliance via m4_ax_cxx_compile_stdcxx.m4 + * defining "_DEBUG" instead of "DEBUG" in debug mode + - enable-c11 flag removed since obsolete (c11 now mandatory) + * .travis : adaption to configure changes + + easylogging++.h : v9.83 of header-only logging lib (MIT license) + * general.h : + + includes config.h for configure-based flags + + IN_DEBUG_MODE : compiler flag to mark debug mode + + includes easylogging++.h : global logging support + + easylogging++ log file setup (disabled) + * AccessibilityConstraint : + + isUnconstrained() : checks whether or not a position is unconstrained + * isBlocked() : + * isAccessible() : + + quick check for empty list + * AccessibilityVrna : + - log stream : obsolete + * construction : + + base pair span forwarded to fill* functions + * fillRNAup() also used if sliding window size == 0 (since fastest) + * fill*() : + + timing added (debug mode only) + + verbose log of computation mode + * fillByConstraints() : + * getPfScale() : + * fillByRNAup() : + + uses now base pair span + * CommandLineParsing : + - logStream : obsolete (global logging) + + seedMaxE argument : maximal overall energy of a seed interaction + + validate_seedMaxE() + + seedConstraint : central seed constraint object for all predictors + * getSeedConstraint() : returns constant reference to central object + * InteractionEnergy : + - getInterLoop() : replaced by getInterLeft() + + getInterLeft() : left side loop extension (former getInterLoop()) + + getPr_danglingLeft() : probability of dangling ends on the left side + + getPr_danglingRight() : probability of dangling ends on the right side + * getE() : + * getE_contributions() : + * using getPr_dangling*() for dangling end energy computation + * Predictor* : + * predict() : + + verbose log for prediction mode + + performance logging in debug mode + * PredictorMfe2dSeed : + * fillSeed() : + + over energy computation for seed now includes getE_init() + * seed max energy boundary now via SeedConstraint.getMaxE() + * traceBackSeed() : + * bugfix : j2 initialization + * SeedConstraint : + + maxE + getter : maximal overall energy a seed is allowed to have + +161017 Martin Mann : + * CommandLineParsing : + - seedMinBP : renamed to seedBP + - getSeedMinBp : obsolete + + noSeedRequired : whether or not to enforce seed constraint for interactions + + seedBP : number of base pairs within seed + + seedMaxUP : maximal overall number of unpaired bases in seed + + seedMaxUPq : maximal number of unpaired bases within query's seed + + seedMaxUPt : maximal number of unpaired bases within target's seed + + validator_*() for arguments + + getSeedConstraint() : provides the seed according to the arguments + * parse() : + + noSeedRequired setup + * getPredictor() : predictor type depends now on noSeedRequired member setup + * general.h : + + E_isNotINF() : check for energy != E_INF + + E_isINF() : check for energy == E_INF + * InteractionEnergy : + * getE() : + + overall energy only computed if hybridE != E_INF + * OutputHandlerText : + * add() : + + output text for empty interaction + * PredictorMaxProb : + * fillHybridZ() : bugfix of boundary checks + * updateMaxProbInteraction() : bugfix : offset missing + * PredictorMfe : + * updateMfe() : + * feasibility check extended with dangling end energies (can be < 0) + * bugfix : offset missing + * PredictorMfe2d/4d : + * checks via E_isINF and E_isNotINF + + PredictorMfe2dSeed : predicts interactions that fulfill the seed constraint + + SeedConstraint : defines a seed constraint + + bp : number of base pairs + + maxUnpairedOverall : maximal overall number of unpaired bases + + maxUnpaired1 : maximal number of unpaired bases in first sequence + + maxUnpaired2 : maximal number of unpaired bases in second sequence + + getMaxLength*() : provides maximal length of a seed given the constraints + + ostream operator + +161012 Martin Mann : + * CommandLineParsing : + + parseSequencesFasta() : read FASTA format from input stream + * validate_sequenceArgument() : + + stream/file support enabled + * parseSequence() : + + stream/file support enabled + * intaRNA : + * bugfix: queryAcc cleanup in inner loop + +161012 Martin Mann : + * AccessibilityVrna : + * getPf* : + + local vrna_md_t model for according window sizes + * CommandLineParsing : + * getOutputHandler() : + energy handler as argument + + energyFile : file name of the VRNA energy parameter file to be used + + validate_energyFile() + + validateFile() : generic file existence and readability check + + updateParsingCode() : central utility function for parsing code updates + * parse() : + + update of vrnaHandler after parsing + + energFile handling + + updateParsingCode() usage + * validate_sequenceArgument() + + validateFile() usage + * general.h + + E_equal() : checks for (semi)equality for floating point variables + * intaRNA : adaptions to interface changes + * InteractionEnergy : + + EnergyContributions : individual energy contributions for an interaction + + getE_contributions() : provides an EnergyContributions container for a + given interaction + + getE_init() : the duplex initiation energy + + getE_interLoop() : former getInterLoopE() + + getE_danglingLeft() : former getDanglingLeft() + + getE_danglingRight() : former getDanglingRight() + + getE_endLeft() : former getEndLeft() + + getE_endRight() : former getEndRight() + + getBestE_interLoop() : former getBestStackingEnergy() + + getBestE_dangling() : former getBestDangleEnergy() + + getBestE_end() : former getBestEndEnergy() + - getInterLoopE() : renamed + - getDangling*() : renamed + - getEnd*() : renamed + - getBest*Energy() : renamed + - getBestInitEnergy() : obsolete + * isValidInternalLoop() : + + returns false on (i1==j1 || i2==j2) + * InteractionEnergyBasePair : + * adaptions to interface changes + + getE_init() : returns -1.0 + * getE_interLoop() : returns only interior loop energies (no init) + * InteractionEnergyVrna : + * adaptions to interface changes + * getE_interLoop() : returns only interior loop energies (no init) + * getE_dangling*() : substracts end energies to get dangling end + contributions only (combined value from the VRNA interface) + * OutputHandlerText : + + energy : used energy handler for interaction computation + * construction() : + energy argument + * add() : + + provide energy contribution details + * PredictorMaxProb : + * fillHybridZ() : + + explicit energy.getE_init() handling + * PredictorMfe : + * adaption to interface changes + * PredictorMfe2d/4d : + * fillHybridE() : + + explicit energy.getE_init() handling + * traceback() : + * bugfix: i2/j2 index computation for offset > 0 + + explicit energy.getE_init() handling + * VrnaHandler : + * constructor() : + + vrnaParamFile argument : for loading non-default energy parameters + - max_bp_span : now in getModel() + - window_size : now in getModel() + * default for max_bp_span/window_size = -1 + * getModel() : + * now creates a new model object per call to enable different parameters + e.g. for different accessibility computations + + max_bp_span argument + + window_size argument + * test/InteractionEnergyBasePair : adaption to interface changes + +161007 Martin Mann : + + PredictorMfe : generic interface for mfe predictors to reduce code redundancy + + mfeInteraction + + i1offset + + i2offset + + initMfe() + + updateMfe() + + min..E() : minimal energy contributions to avoid recomputation + * PredictorMfe4d + * now PredictorMfe subclass + - PredictorMfe members + * using energy.areComplementary() + * bugfix : single interaction energy was doubled + * bugfix : ED-based cell computation skipping was check reversed + * fillHybridE() : + - energy argument was obsolete + + PredictorMfe2d : space efficient mfe predictor using 2D matrices only + + predict() : computes best interaction screening all possible right + interaction ends + + initHybridE() : initializes the cells used for current right interaction + ends + * bugfix : ED-based cell computation skipping was check reversed + + fillHybridE() : computes all possible interactions for current right + interaction ends and reports them to updateMfe() + + traceBack() : recomputes interactions for the right side of the current + interaction site and traces the details of the interaction of interest + * PredictorMaxProb : + * bugfix : single interaction energy was doubled + * InteractionEnergy : + + areComplementary() : checks two positions if complementary + * CommandLineParsing : + + predMode argument (mode,m) + + validate_predMode() : checks the argument value + * getPredictor() : returns predictor by argument setup + +161006 Martin Mann : + - PredictorMfeRNAup : renamed to PredictorMfe4d + + PredictorMfe4d : former PredictorMfeRNAup + * overall energies computed in updateMfeInteraction() + * InteractionEnergy : + + getE() : computes the overall energy for a given interaction site and + hybridization energy + E = hybridE + ED1 + ED2 + + dangleLeftE*prob(leftFree) + dangleRightE*prob(rightFree) + + closeLeftE + closeRightE + + getBoltzmannWeight() : the Boltzmann weight for a given energy + * InteractionEnergy* : + + getEndLeft/Right() : the penalty for ending the interaction + + getBestEndEnergy() : best energy penalty for interaction ends + * InteractionEnergyVrna : + + bpGC/CG : base pair type encoding for GC/CG base pair + + isGC() : tests whether two positions resemble a GC/CG base pair + * PredictorMaxProb : + - getBoltzmannWeight() : now part of InteractionEnergy + * overall energies/weights computed in updateMaxProbInteraction() + +161005 Martin Mann : + * Predictor : + + getMaxInteractionWidth() : upper width bound for an interacting site + * PredictorMaxProb : + * PredictorMfeRNAup : + * matrix initialization of end regions reduced to the accessible window + widths using getMaxInteractionWidth() + * adaption of recursion to varying matrix sizes + + test/Interaction + * test/Makefile.am : clear binary before each test run (ensures relinking) + * Interaction : + * isValid() : bugfix : wrong return for single bp interaction + +161005 Martin Mann : + * Accessibility* : + - AccessibilityConstraintAlphabet : now part of AccessibilityConstraint + * ED_UPPER_BOUND = E_INF + * uses now AccessibilityConstraint object instead of dot-bracket string + + AccessibilityConstraint : encodes an accessibility constraint based + + init via dot-bracket VRNA-like encoding + + getVrnaDotBracket() : get according VRNA-styled dot-bracket encoding + + isAccessible() : check for explicit "accessible" marking + + isBlocked() : check for explicit "blocked" marking + + isEmpty() : check if any constraint information present + * CommandLineParsing : + * getTargetAccessibility() : creation of AccessibilityConstraint object + * getQueryAccessibility() : creation of AccessibilityConstraint object + + IndexRange : represents an ascending or descending range of (sequence) indices + + isAscending() : check if ascending range encoding + + isDescending() : check if descending range encoding + + ostream operator + + less-than operator + * Interaction : + + construction from InteractionRange + * sequence handling via pointers to enable assignment operator + * basePairs : public + - getBasePairs() : obsolete for public member + * energy : public + - get/setEnergy() : obsolete for public member + + isEmpty() : check if any base pairs present + + assignment operator (InteractionRange) + * InteractionEnergy* : + + getBestStackingEnergy() : access to the best stacking energy contribution + + getBestInitEnergy() : access to the best initiation energy contribution + + getBestDangleEnergy() : access to the best dangling end energy contribution + + InteractionRange : represents two interacting ranges of two sequences based + on two according IndexRange objects + + construction from Interaction (boundaries) + + isSane() : checks ordering of index ranges + + ostream operator + + less-than operator + + assignment operator (Interaction) + * src/Makefile.am : adaption to source changes + * OutputHandler* : + + add(InteractionRange) + + OutputHandlerRangeOnly : converts reported Interactions into an + InteractionRange and forwards the output to a successive OutputHandler + * OutputHandlerText : + * adaption to Interaction interface changes + * Predictor* : + * predict(IndexRange,IndexRange) : takes to ranges instead of 4 coordinates + * PredictorMaxProb : + * maxProbInteraction : now an InteractionRange + * PredictorMfeRNAup : + + getE() : computes the overall energy for a given interaction site + * updateMfe() : takes only the overall energy instead of individual contribs + * ReverseAccessibility : + * adaption to AccessibilityConstraint usage + * RnaSequence : + + isAmbiguous() : checks a certain sequence position for ambiguity + + test/AccessibilityConstraint + + test/IndexRange + + test/InteractionRange + + test/OutputRangeOnly + +161004 Martin Mann : + * general : + - E_MAX : replaced by E_INF + + E_INF : infinity representation for E_type + +161001 Martin Mann : + - tests/test* : renamed to *_test + + tests/*_test.cpp : test files for the according classes + * tests/Makefile : + + wildcard based test file listing + * travis : + + make test added + * configure.ac : back to automake 1.11 features + * */Makefile.am : test target adapted to configure change + +160930 Martin Mann : + * InteractionEnergy* : + + getRT() : provides the RT constant for this energy model to compute + Boltzmann weights + + PredictorMaxProb : computes the interaction site with maximal probability + and reports the according boundaries and the site's ensemble energy to the + output handler +160930 Martin Mann : + * PredictorMfeRNAup : + * mfeInteraction base pairs now updated instead of recreation (reduced memory + allocation events) + - PredictorRNAup.* : renamed to PredictorMfeRNAup.* + + PredictorMfeRNAup.* : rename to be class name conform + * Makefile.am : adaption to file rename + * intaRNA : + + call CommandLineParsing.getPredictor() to get predictor + * CommandLineParsing : + + getPredictor() : generates the predictor according to the user request +160930 Martin Mann : + * InteractionEnergyVrna : + * getDangling*() : bugfix : dangling sequence code was not given + * ReverseAccessibility : + + getReversedIndex() : get index in reversed sequence + * Interaction : + + energy + get/set() : optional energy value for the interaction (init NaN) + * Predictor : + * output non-const + * constructor : + * output non-const (otherwise no filling possible) + + predict() : triggers prediction + - PredictorRNAup : renamed PredictorMfeRNAup + + PredictorMfeRNAup : + + mfeInteraction : holds the mfe interaction + - hybridEmin : now part of mfeInteraction + + initMfe() : initializes mfe and mfe interaction + + updateMfe() : updated mfe and mfe interaction + * fillHybridE() : + * global temp variables to reduce allocation effort + + dangling end contribution added + * constructor() : only initializes data structures, no computation triggered + + predict() : does the computation and output reporting + + clear() : clears temporary data structures + * destructor() : calls now only clear() + + i1offset : the offset for the first sequence for index handling + + i2offset : the offset for the second sequence for index handling + * OutputHandlerText : + + add() : + + prints interaction energy + * RnaSequence + + last : placeholder to represent the last position within a sequence + * intaRNA : + * calls predictor->predict() + * AccessibilityVrna : + * calc_ensemble_free_energy() + * input check preprocessor defines corrected + +160929 Martin Mann : + * CommandLineParsing : + + ReturnCode : enum for different return codes for parsing + - parsingResultNotSet : obsolete (covered by ReturnCode) + * adaption to ReturnCode usage + * intaRNA : + * adaption to ReturnCode + + PredictorRNAup temporarily hard-coded + + unit tests added using Catch header library + * configure.ac : + + generate tests/Makefile + + AM_EXTRA_RECURSIVE_TARGETS([tests]) : recursive "tests" make target + * AM_INIT_AUTOMAKE([1.13]) : need v1.13 for AM_EXTRA_RECURSIVE_TARGETS + * Makefile.am : + + go to subdir 'tests' for 'tests' make directive only + + tests/Makefile.am : compile and run tests + + catch.hpp : Catch library version 1.5.7 + + tests/runTests.cpp : central test program + + tests/testInteractionEnergy.cpp + + tests/testInteractionEnergyBasePair.cpp + + tests/testRnaSequence.cpp + * RnaSequence : + + areComplementary() : tests for base pair complementarity + * constructor : input checks in debug mode + * Accessibility + subclasses : + * constructor : accConstraint now pointer to enable NULL argument + * CommandLineParsing : + * argument docu extended + * adaption to Accessibility interface change + + energy argument added + + validate_energy() + * InteractionEnergy : + * energy getters now const + * isAllowedLoopRegion() + * now public + * bugfix of maxInternalLoppSize check + + getMaxInternalLoopSize*() to access individual max internal loop size + + isValidInternalLoop() : checks an internal loop request + * InteractionEnergyVrna : + * energy getters : bugfix normalization dcal to kcal + * interface adaption + * getInterLoopE() : + * getDanglingLeft() : + * getDanglingRight() : + * bugfix of sequence access + * InteractionEnergyBasePair : + * interface adaption + * PredictorRNAup : + * E2dMatrix : now quadratic matrix for interaction widths w1,w2 + * E4dMatrix : now quadratic matrix for interaction starts i1,i2 + + hybridEmin : global minimal energy value computed + * (de/con)structor : matrix deletion/initialization adapted + * fillHybridE() : + + two round computation: first hybridizations only, than ED values added + +160928 Martin Mann : + * AccessibilityVrna : + + fillByConstraints() : intarna-1 way of computing ED values + + fillByRNAup() : RNAup-like ED value computation + + fillByRNAplfold() : RNAplfold-like ED value computation + * remaining interface adapted to local computation and data structures + * using boost::banded_matrix for ED storage + * constructor() : + + ED setup depends on whether or not structure constraint present + * getPfScale() : bugfix : now use global accessibility constraint for + mfe/ensemble energy computation + * Accessibility member access now via getter + * adaption to possibly empty accConstraint + * Accessibility : + * constructor() : accConstraint now empty if not provided to reduce memory + * checkIndices() : checks only in DEBUG mode enabled + * CommandLineParsing : + * cleanup + * intaRNA : + * adaption to parse return value change + * InteractionEnergyVrna : + * destructor : bugfix : has to use 'free' for VRNA cleanup + * VrnaHandler : + + getRT() : computes the RT constant for the current temperature + * configure.ac : + * VRNA check extended + + PredictorRNAup : RNAup-like interaction prediction + * Makefile.am : adaption to source file changes + * configure.ac : + + additional check for "-std=c++11" support of the compiler + * InteractioNEnergy : + + getAccessibility* : access to full accessibility objects + - getLength* : obsolete + +160927 Martin Mann : + + AccessibilityVrna : vrna-based accessibility computation + (former AccessibilityVienna) + + InteractionEnergy : former Energy + + InteractionEnergyBasePair : former EnergyBasePair + + InteractionEnergyVrna : former EnergyVienna + - AccessibilityVienna : renamed + - Energy : renamed + - EnergyBasePair : renamed + - EnergyVienna : renamed + * Accessibility : + + ostream operator : prints ED values + * AccessibilityVrna : + - modelDetails : obsolete + * RnaSequence : + + ostream operator : prints "ID(Sequence)" + + VrnaHandler : central handler for VRNA folding parameter setup + * model generation now done in constructor + * model access non-const due to VRNA interface ("features" on the fly + initialization of model if not initialized yet, thus non-const) + * CommandLineParsing : + + vrnaHandler + + getTemperature() : getter for user defined temperature + * adaption to renames + + +160923 Martin Mann : + * .travis : + * sudo: true (was false) + +160922 Martin Mann : +############### MOVE FROM CVS TO GIT INTARNA REPO ############################ + * README : + + compilation information + + refers to README.md + + README.md (by Björn Grüning) + * COPYING : refers to LICENSE + + LICENSE : now MIT license for intarna 2.* + * configure.ac : replaced by new version for intarna 2.* + .travis.yml : updated to Vienna 2.2.10 usage + + m4/m4_ax_boost_base.m4 : boost m4 checks for configure.ac usage + + autotools-init.sh : calls autotools to generate system specific files + ==> NOTE : CALL AFTER CHECKOUT <== + - depcomp : temporary autotools file generated by 'bash autotools-init.sh' + - install-sh : temporary autotools file generated by 'bash autotools-init.sh' + - configure : temporary autotools file generated by 'bash autotools-init.sh' + - missing : temporary autotools file generated by 'bash autotools-init.sh' + - Makefile.in : temporary autotools file generated by 'bash autotools-init.sh' + - aclocal.m4 : temporary autotools file generated by 'bash autotools-init.sh' + - src/*.h : old source removed + - src/*.c* : old source removed + - src/data/ : old energy data removed + + src/*.h : new source data for version 2.* + + src/*.cpp : new source data for version 2.* + * src/Makefile.am : updated for new source files + +160921 Martin Mann : + * RnaSequence.h : documentation corrected + * CommandLineParsing : + + validateSequenceAlphabet() : checks + + sequence alphabet check + + ambiguity check for warning + * parseSequences() : + + validateSequenceAlphabet() call + +150616 Martin Mann + * CommandLineParsing : + * parse() + + check for minimal sequence length (>= seedMinBP) + +140719 Martin Mann + * EnergyBasePair : + * getInterLoopE() : BUGFIX : was returning loop energy instead of negated + base pair number only + +140716 Martin Mann + + OutputHandlerText : prints reported interaction in a simple text format to + stream similar to IntaRNA 1.* output + +140714 Martin Mann + * general : + + CHECKNOTNULL macro to throw an exception with message if a given pointer is + not initialized + + Predictor : general interaction prediction interface + + Interaction : interaction information container to be filled by predictors + and to be handled by output handlers + + OutputHandler : general interaction reporting handler interface + +140703 Martin Mann + * Accessibility* : + + global accessibility constraint support (some sequence positions have to be + unstructured both in structure ensemble and interaction and are thus + omitted from interaction prediction via ED_UPPER_BOUND accessibility + values) + * CommandLineParsing : + + *AccConst : parameter + checks for accessibility constraints + + validateSequenceNumber() : sequence number check (for depending parameters) + +140701 Martin Mann + * intaRNA : + + general computation setup started + * general : + + CLEANUP : macro to delete a pointer and to set it to NULL + * CommandLineParsing : + + CharParameter : ensures a char parameter is from a given alphabet + + validate_charArgument() : generic check function + + validate_numberArgument() : generic check function + + several parameters including check functions, defaults, etc. + + get*Accessibility() : generates an Accessibility object according to the + user parameters + + getEnergyHandler() : generates an Energy object according to the parameters + * ReverseAccessibility : + + access to original sequence and accessibility object + * RnaSequence : + + ambiguity check + +140630 Martin Mann + + ReverseAccessibility : reversed index access to a sequence and its + accessibility (ED) values as needed for the energy computation + * AccessibilityVienna : + * Vienna RNA package calls corrected + + partFoldParams : central partition function folding parameter object + + Energy : abstract interface to compute energy contributions + + getDangling*() : dangling end penalties + + EnergyBasePair : energy computation in terms of number of base pairs + + EnergyVienna : energy computation via Vienna RNA package + +140627 Martin Mann + * Accessibility* : + + maxLength : maximal length of accessible regions to consider, defaults to + the sequence's length + + E_type : global type for energy variables/values + + T_type : global type for temperature variables/values + + E_MAX : constant : maximal value for energies + +140625 Martin Mann + * configure : + + Vienna RNA package v2.* path support and checks + + Accessibility : abstract interface to get accessibility energies for regions + + AccessibilityNone : Accessibility implementation that always returns zero + + AccessibilityVienna : Accessibility implementation that computes _all_ ED + values based on ensemble energies computed via the Vienna RNA package + * RnaSequence : + + as* : access functions for different sequence encodings + +140624 Martin Mann + + general.h : + + macro to stop at unimplemented source code locations via std::runtime_error + + RnaSequence : class that represents an RNA sequence with according + functionality + + integer encoding + + string validation + * CommandLineParser : + + query and target : + + support for direct sequence input + + preparation for stream/file parsing + +140618 Martin Mann + + cygwin boost installation using + ./b2 --prefix=/cygdrive/c/Research/Software/boost/1.55.0 --layout=tagged + --without-python --without-mpi --without-context threading=single + link=static variant=release install + + src/CommandLineParsing : class that handles command line argument parsing + and checking via boost::program_options + NOTE: under cygwin a boost build from source is needed to get the libraries + correctly compiled and linkable (boost lib from cygwin repos is not + working) + +140617 Martin Mann + + autoconf setup + +140617 ******** start reimplementation of IntaRNA in CVS ****************** + + +############################################################################# + 2011-06-10 Andreas Richter version 1.2.5 * fixed bug in string clearing when option -v is used and no significant interactions are found diff --git a/LICENSE b/LICENSE index 94a9ed02..255a1763 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,23 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 +The MIT License (MIT) - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Copyright (c) 2016 Bioinformatics Group of Prof. Backofen, +Institute for Computer Science, University Freiburg, Freiburg, Germany - Preamble +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - The GNU General Public License is a free, copyleft license for -software and other kinds of works. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/Makefile.am b/Makefile.am index 00d837d9..f9f46ce5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,14 @@ # sub directories to check for Makefiles -SUBDIRS = src +SUBDIRS = src perl tests . + +# global test directive # ensure all is compiled (need object files for tests) +.PHONY: tests test +tests: all + @echo + @echo " => compiling and running tests ... will take a while ..." + @echo + @$(MAKE) check -s -C tests + +test: tests + diff --git a/Makefile.in b/Makefile.in deleted file mode 100644 index 9c397fa3..00000000 --- a/Makefile.in +++ /dev/null @@ -1,661 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ - ChangeLog INSTALL NEWS depcomp install-sh missing -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir dist dist-all distcheck -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - { test ! -d "$(distdir)" \ - || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr "$(distdir)"; }; } -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# sub directories to check for Makefiles -SUBDIRS = src -all: all-recursive - -.SUFFIXES: -am--refresh: - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz - $(am__remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) - -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @$(am__cd) '$(distuninstallcheck_dir)' \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-generic \ - ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ - dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ - distclean distclean-generic distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-recursive uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/NEWS b/NEWS index e69de29b..911dab30 100644 --- a/NEWS +++ b/NEWS @@ -0,0 +1,2 @@ + + see Changelog file diff --git a/README b/README index 8e1d7b72..eaf707f1 100644 --- a/README +++ b/README @@ -1,22 +1,12 @@ -IntaRNA uses the libRNA.a from the Vienna RNA Package. Thus before compiling -IntaRNA, you have to configure and install the Vienna RNA Package. You can -download it at: - -http://www.tbi.univie.ac.at/~ivo/RNA/ - -If the Vienna RNA Package is not installed to a default directory you can -add this information to the 'configure' script using the -'--with-RNA=$VIENNA-PATH' flag. - -Run './configure --help' for more configuration details. +######### IntaRNA ################################################ + +To configure, compile and install do the following steps: + - run ./configure [--help for additional configuration options] + - run make + - run make install -Call './IntaRNA -h' for a help page with all options offered by IntaRNA. +In case you run into problems, please contact us! -For bug reports or questions please write to +Also refer to README.md file for further information. - intarna(a)informatik.uni-freiburg.de - - or visit - - http://www.bioinf.uni-freiburg.de/Software/ diff --git a/README.md b/README.md index 5394b554..a6ed5c1f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,696 @@ [![Build Status](https://travis-ci.org/BackofenLab/IntaRNA.svg?branch=master)](https://travis-ci.org/BackofenLab/IntaRNA) -# IntaRNA -Efficient target prediction incorporating accessibility of interaction sites +# IntaRNA version 2.* -**Motivation**: During the last few years, several new small regulatory RNAs (sRNAs) have been discovered in bacteria. Most of them act as post-transcriptional regulators by base pairing to a target mRNA, causing translational repression or activation, or mRNA degradation. Numerous sRNAs have already been identified, but the number of experimentally verified targets is considerably lower. Consequently, computational target prediction is in great demand. Many existing target prediction programs neglect the accessibility of target sites and the existence of a seed, while other approaches are either specialized to certain types of RNAs or too slow for genome-wide searches. +**Efficient RNA-RNA interaction prediction incorporating accessibility and +seeding of interaction sites** + +During the last few years, several new small regulatory RNAs +(sRNAs) have been discovered in bacteria. Most of them act as post-transcriptional +regulators by base pairing to a target mRNA, causing translational repression +or activation, or mRNA degradation. Numerous sRNAs have already been identified, +but the number of experimentally verified targets is considerably lower. +Consequently, computational target prediction is in great demand. Many existing +target prediction programs neglect the accessibility of target sites and the +existence of a seed, while other approaches are either specialized to certain +types of RNAs or too slow for genome-wide searches. + +IntaRNA, developed by +[Prof. Backofen's bioinformatics group at Freiburg University](http://www.bioinf.uni-freiburg.de), +is a general and fast approach to the +prediction of RNA-RNA interactions incorporating both the accessibility of +interacting sites +as well as the existence of a user-definable seed interaction. We successfully applied +IntaRNA to the prediction of bacterial sRNA targets and determined the exact +locations of the interactions with a higher accuracy than competing programs. + +For testing or ad hoc use of IntaRNA, you can use its webinterface at the + +**==> [Freiburg RNA tools IntaRNA webserver](http://rna.informatik.uni-freiburg.de/IntaRNA/) <==** -**Results:** We introduce INTARNA, a new general and fast approach to the prediction of RNA–RNA interactions incorporating accessibility of target sites as well as the existence of a user-definable seed. We successfully applied INTARNA to the prediction of bacterial sRNA targets and determined the exact locations of the interactions with a higher accuracy than competing programs. ## Contribution -Feel free to contribute to this project by wirting [Issues](https://github.com/BackofenLab/IntaRNA/issues) with feature requests or bug reports. +Feel free to contribute to this project by writing +[Issues](https://github.com/BackofenLab/IntaRNA/issues) +with feature requests, bug reports, or just contact messages. + +## Citation +If you use IntaRNA, please cite our articles +- [IntaRNA: efficient prediction of bacterial sRNA targets incorporating target site accessibility and seed regions](http://dx.doi.org/10.1093/bioinformatics/btn544) + Anke Busch, Andreas S. Richter, and Rolf Backofen, + Bioinformatics, 24 no. 24 pp. 2849-56, 2008, DOI(10.1093/bioinformatics/btn544). +- [CopraRNA and IntaRNA: predicting small RNA targets, networks and interaction domains](http://dx.doi.org/10.1093/nar/gku359) + Patrick R. Wright, Jens Georg, Martin Mann, Dragos A. Sorescu, Andreas S. Richter, Steffen Lott, Robert Kleinkauf, Wolfgang R. Hess, and Rolf Backofen + Nucleic Acids Research, 42 (W1), W119-W123, 2014, DOI(10.1093/nar/gku359). + + + +



+ +# Documentation + +## Overview + +The following topics are covered by this documentation: + +- [Installation](#install) + - [Dependencies](#deps) + - [Cloning from github](#instgithub) + - [Source code distribution](#instsource) +- [Usage and Parameters](#usage) + - [Just run ...](#defaultRun) + - [Prediction modes, their features and emulated tools](#predModes) + - [Interaction restrictions](#interConstr) + - [Seed constraints](#seed) + - [Output modes](#outmodes) + - [Suboptimal RNA-RNA interaction prediction and output restrictions](#subopts) + - [Energy parameters and temperature](#energy) + - [Accessibility and unpaired probabilities](#accessibility) + - [Local versus global unpaired probabilities](#accLocalGlobal) + - [Read/write accessibility from/to file or stream](#accFromFile) + - [Multi-threading and parallelized computation](#multithreading) + + + +



+
+# Installation + +

+
+## Dependencies + +- compiler supporting C++11 standard and OpenMP +- GNU autotools (automake, autoconf, ..) +- [boost C++ library](http://www.boost.org/) version >= 1.50.0 +- [Vienna RNA package](http://www.tbi.univie.ac.at/RNA/) version >= 2.3.0 + +

+
+## Cloning from github (or downloading ZIP-file) + +The data provided within the github repository is no complete distribution and +lacks all system specific generated files. Thus, in order to get started with +a fresh clone of the IntaRNA repository you have to run the GNU autotools +to generate all needed files for a proper `configure` and `make`. To this end, +we provide a helper script that as shown in the following. +```bash +# call aclocal, automake, autoconf +bash ./autotools-init.sh +``` +Afterwards, you can continue as if you would have downloaded a +[IntaRNA source code distribution](#instsource). + +

+
+## Source code distribution + +When downloading an IntaRNA source code distribution, e.g. from the +[IntaRNA release page](https://github.com/BackofenLab/IntaRNA/releases), you should +first ensure, that you have all [dependencies](#deps) installed. If so, you can +simply run the following (assuming `bash` shell). +```bash +# generate system specific files (use -h for options) +./configure +# compile IntaRNA from source +make +# run tests to ensure all went fine +make tests +# install (use 'configure --prefix=XXX' to change default install directory) +make install +# (alternatively) install to directory XYZ +make install prefix=XYZ +``` + + + + + +



+
+# Usage and parameters + +IntaRNA comes with a vast variety of ways to tune or enhance *YOUR* RNA-RNA prediction. +To this end, different [prediction modes](#predModes) are implemented that allow +to balance predication quality and runtime requirement. Furthermore, it is +possible to define +[interaction restrictions](#interConstr), +[seed constraints](#seed), +[output modes](#outmodes), +[suboptimal enumeration](#subopts), +[energy parameters, temperature](#energy), +and the [accessibility](#accessibility) handling. If you are doing high-throughput +computations, you might also want to consider [multi-threading support](#multithreading). + + + +

+
+## Just run ... + +If you just want to start and are fine with the default parameters set, +you only have to provide two RNA sequences, +a (long) target RNA (using `-t` or `--target`) and a (short) query RNA +(via `-q` or `--query`), in +[IUPAC RNA encoding](#https://en.wikipedia.org/wiki/Nucleic_acid_notation). +You can either directly input the sequences +```bash +# running IntaRNA with direct sequence input +# call : IntaRNA -t CCCCCCCCGGGGGGGGGGGGGG -q CCCCCCC + +target + 9 15 + | | + 5'-CCCCCCCC GGGGGGG-3' + GGGGGGG + ||||||| + CCCCCCC + 3'- -5' + | | + 7 1 +query + +interaction energy = -10.7116 kcal/mol + +``` + +or provide (multiple) sequence(s) in [FASTA-format](#https://en.wikipedia.org/wiki/FASTA_format). +It is possible to provide either file input or to read the FASTA input from the +STDIN stream. + +```bash +# running IntaRNA with FASTA files +IntaRNA -t myTargets.fasta -q myQueries.fasta +# reading query FASTA input from stream via pipe +cat myQueries.fasta | IntaRNA -q STDIN -t myTargets.fasta +``` + +Nucleotide encodings different from `ACGUT` are rewritten as `N` and the respective +positions are not considered to form base pairs (and this ignored). +Thymine `T` encodings are replaced by uracil `U`, since a `ACGU`-only +energy model is used. + +For a list of general program argument run `-h` or `--help`. For a complete +list covering also more sophisticated options, run `--fullhelp`. + + + + + +

+
+## Prediction modes, their features and emulated tools + +For the prediction of *minimum free energy interactions*, the following modes +and according features are supported and can be set via the `--mode` parameter. +The tiem and space complexities are given for the prediction of two sequences +of equal length *n*. + +| Features | Heuristic `--mode=H` | Exact-SE `--mode=S` | Exact `--mode=E` | +| -------- | :------------------: | :-----------------: | :--------------: | +| Time complexity (prediction only) | O(*n*^2) | O(*n*^4) | O(*n*^4) | +| Space complexity | O(*n*^2) | O(*n*^2) | O(*n*^4) | +| [Seed constraint](#seed) | x | x | x | +| No [seed constraint](#seed) | x | x | x | +| Minimum free energy interaction | not guaranteed | x | x | +| Overlapping [suboptimal interactions](#subopts) | x | x | x | +| Non-overlapping [suboptimal interactions](#subopts) | x | - | x | + +Note, due to the low run-time requirement of the heuristic prediction mode +(`--mode=H`), heuristic IntaRNA interaction predictions are widely used to screen +for interaction in a genome-wide scale. If you are more interested in specific +details of an interaction site or of two relatively short RNA molecules, you +should investigate the exact prediction mode (`--mode=S`, or `--mode=E` +if non-overlapping suboptimal prediction is required). + +Given these features, we can emulate and extend a couple of RNA-RNA interaction +tools using IntaRNA. + +**TargetScan** and **RNAhybrid** are approaches that predict the interaction hybrid with +minimal interaction energy without consideratio whether or not the interacting +subsequences are probably involved involved in intramolecular base pairings. Furthermore, +no seed constraint is taken into account. +This prediction result can be emulated (depending on the used prediction mode) +by running IntaRNA when disabling both the seed constraint +as well as the accessibility integration using +```bash +# prediction results similar to TargetScan/RNAhybrid +IntaRNA [..] --noSeed --qAcc=N --tAcc=N +``` +We *add seed-constraint support to TargetScan/RNAhybrid-like computations* by removing the +`--noSeed` flag from the above call. + +**RNAup** was one of the first RNA-RNA interaction prediction approaches that took the +accessibility of the interacting subsequences into account while not considering the seed feature. +IntaRNA's exact prediction mode is eventually an alternative implementation when disabling +seed constraint incorporation. Furthermore, the unpaired probabilities used by RNAup to score +the accessibility of subregions are covering the respective overall structural ensemble for each +interacting RNA, such that we have to disable accessibility computation based on local folding (RNAplfold) +using +```bash +# prediction results similar to RNAup +IntaRNA --mode=S --noSeed --qAccW=0 --qAccL=0 --tAccW=0 --tAccL=0 +``` +We *add seed-constraint support to RNAup-like computations* by removing the +`--noSeed` flag from the above call. + + + + + + +

+
+## Interaction restrictions + +The predicted RNA-RNA interactions can be enhanced if additional +knowledge is available. To this end, IntaRNA provides different options to +restrict predicted interactions. + +A general most general restriction is the maximal energy (inversely related to +stability) an RNA-RNA interaction is allowed to have. Per default, a reported +interaction should have a negative energy (<0) to be energetically favorable. +This report barrier can be altered using `--outMaxE`. For suboptimal interaction +restriction, please refer to [suboptimal interaction prediction](#subopts) section. + +Furthermore, the region where interactions are supposed to occur can be restricted +for target and query independently. To this end, a list of according index pairs +can be provided using `--qRegion` and `--tRegion`, respectively. The indexing +starts with 1 and should be in the format `from1-end1,from2-end2,..` using +integers. + +Finally, it is possible to restrict the overall length an interaction is allowed +to have. This can be done independently for the query and target sequence using +`--qIntLenMax` and `--tIntLenMax`, respectively. Both default to the full sequence +length (by setting both to 0). + + + + + + + +

+
+## Seed constraints + +For different types of RNA-RNA interactions it was found that experimentally +verified interactions were showing a short and compact subinteraction of high +stability (= low energy). It was hypothesized that these regions are among the +first formed parts of the full RNA-RNA interaction, and thus considered as the +*seed* of the overall interaction. + +Based on this observation, RNA-RNA interaction predictors were enhanced by +incorporating such seed constraints into their prediction pipeline, i.e. a +reported interaction has to feature at least one seed. Typically, +a seed is defined as a short subinteraction of 5-8 consecutive base pairs that +are not enclosing any unpaired nucleotides (or if so only very few). + +IntaRNA supports the definition of such seed constraints and adds further +options to even more constrain the seed selection. The list of options is given +by +- `--seedBP` : the number of base pairs the seed has to show +- `--seedMaxUP` : the maximal overall number of unpaired bases within the seed +- `--seedQMaxUP` : the maximal number of unpaired bases within the query's seed region +- `--seedTMaxUP` : the maximal number of unpaired bases within the target's seed region +- `--seedMaxE` : the maximal overall energy of the seed (to exclude weak seed interactions) +- `--seedMinPu` : the minimal unpaired probability of each seed region in query and target +- `--seedQRange` : a list of index intervals where a seed in the query is allowed +- `--seedTRange` : a list of index intervals where a seed in the target is allowed + +Seed constraint usage can be globally disabled using the `--noSeed` flag. + + -## Cite -If you use IntaRNA, please cite our [article](http://bioinformatics.oxfordjournals.org/content/24/24/2849): + + + +

+
+## Output modes + +The RNA-RNA interactions predicted by IntaRNA can be provided in different +formats. The style is set via the argument `--outMode` and the different modes +will be discussed below. + +Furthermore, it is possible to define *where to output*, i.e. using `--out` +you can either name a file or one of the stream names `STDOUT`|`STDERR`. Note, +any string not matching one of the two stream names is considered a file name. +The file will be overwritten by IntaRNA! + + +### Standard RNA-RNA interaction output with ASCII chart + +The standard output mode `--outMode=D` provides a detailed ASCII chart of the +interaction together with its overall interaction energy. +For an example see the [Just run ...](#defaultRun) section. + + + +### Detailed RNA-RNA interaction output with ASCII chart + +Using `--outMode=D`, a detailed ASCII chart of the interaction together with +various interaction details will be provided. An example is given below. + +```bash +# call: IntaRNA -t AAACACCCCCGGUGGUUUGG -q AAACACCCCCGGUGGUUUGG --outMode=D --seedBP=4 + +target + 5 12 + | | + 5'-AAAC C UGGUUUGG-3' + ACC CCGG + ||| |||| + UGG GGCC + 3'-GGUU U CCCACAAA-5' + | | + 16 9 +query + +interaction seq1 = 5 -- 12 +interaction seq2 = 9 -- 16 + +interaction energy = -2.78924 kcal/mol + = E(init) = 4.1 + + E(loops) = -13.9 + + E(dangleLeft) = -0.458042 + + E(dangleRight) = -0.967473 + + E(endLeft) = 0.5 + + E(endRight) = 0 + + ED(seq1) = 3.91068 + + ED(seq2) = 4.0256 + + Pu(seq1) = 0.00175516 + + Pu(seq2) = 0.00145659 + +seed seq1 = 9 -- 12 +seed seq2 = 9 -- 12 +seed energy = -1.4098 kcal/mol +seed ED1 = 2.66437 kcal/mol +seed ED2 = 2.66437 kcal/mol +seed Pu1 = 0.0132596 +seed Pu2 = 0.0132596 +``` +Position annotations start indexing with 1 at the 5'-end of each RNA. +`ED` values are the energy penalties for reduced [accessibility](#accessibility) +and `Pu` denote unpaired probabilities of the respective interacting subsequences. + + +### Customizable CSV RNA-RNA interaction output + +IntaRNA provides via `--outMode=C` a flexible interface to generate RNA-RNA +interaction output in CSV format (using `;` as separator). + +```bash +# call: IntaRNA -t AAACACCCCCGGUGGUUUGG -q AAACACCCCCGGUGGUUUGG --outMode=C --noSeed --outOverlap=B -n 3 +id1;start1;end1;id2;start2;end2;subseqDP;hybridDP;E +target;4;14;query;4;14;CACCCCCGGUG&CACCCCCGGUG;((((...((((&))))...))));-4.14154 +target;5;16;query;5;16;ACCCCCGGUGGU&ACCCCCGGUGGU;(((((.((.(((&))))).)).)));-4.04334 +target;1;14;query;4;18;AAACACCCCCGGUG&CACCCCCGGUGGUUU;(((((((...((((&))))...)))).)));-2.94305 +``` +For each prediction, a row in the CSV is generated. + +Using the argument `--outCsvCols`, the user can specify what columns are +printed to the output using a comma-separated list of colIds. Available colIds +are +- `id1` : id of first sequence +- `id2` : id of second sequence +- `seq1` : full first sequence +- `seq2` : full second sequence +- `subseq1` : interacting subsequence of first sequence +- `subseq2` : interacting subsequence of second sequence +- `subseqDP` : hybrid subsequences compatible with hybridDP +- `subseqDB` : hybrid subsequences compatible with hybridDB +- `start1` : start index of hybrid in seq1 +- `end1` : end index of hybrid in seq1 +- `start2` : start index of hybrid in seq2 +- `end2` : end index of hybrid in seq2 +- `hybridDP` : hybrid in VRNA dot-bracket notation +- `hybridDB` : hybrid in dot-bar notation +- `E` : overall hybridization energy +- `ED1` : ED value of seq1 +- `ED2` : ED value of seq2 +- `Pu1` : probability to be accessible for seq1 +- `Pu2` : probability to be accessible for seq2 +- `E_init` : initiation energy +- `E_loops` : sum of loop energies (excluding E_init) +- `E_dangleL` : dangling end contribution of base pair (start1,end2) +- `E_dangleR` : dangling end contribution of base pair (end1,start2) +- `E_endL` : penalty of closing base pair (start1,end2) +- `E_endR` : penalty of closing base pair (end1,start2) +- `seedStart1` : start index of the seed in seq1 +- `seedEnd1` : end index of the seed in seq1 +- `seedStart2` : start index of the seed in seq2 +- `seedEnd2` : end index of the seed in seq2 +- `seedE` : overall hybridization energy of the seed only (excluding rest) +- `seedED1` : ED value of seq1 of the seed only (excluding rest) +- `seedED2` : ED value of seq2 of the seed only (excluding rest) +- `seedPu1` : probability of seed region to be accessible for seq1 +- `seedPu2` : probability of seed region to be accessible for seq2 + +Using `--outCsvCols ''`, all available columns are added to the output. + +Energies are provided in unit *kcal/mol*, probabilities in the interval [0,1]. +Position annotations start indexing with 1. + +The `hybridDP` format is a dot-bracket notation as e.g. generated by **RNAup**. +Here, for each target sequence position within the interaction, +a '.' represents a position not involved +in the interaction while a '(' marks an interacting position. For the query +sequence this is done analogously but using a ')' for interacting positions. +Both resulting strings are concatenated by a separator '&' to yield a single +string encoding of the interaction's base pairing details. + +The `hybridDB` format is similar to the `hybridDP` but also provides site information. +Here, a bar '|' is used in both base pairing encodings (which makes it a 'dot-bar encoding'). +Furthermore, each interaction string is prefixed +with the start position of the respective interaction site. + +In the following, an altered CSV output for the example from above is generated. +```bash +# call: IntaRNA --outCsvCols=Pu1,Pu2,subseqDB,hybridDB -t AAACACCCCCGGUGGUUUGG -q AAACACCCCCGGUGGUUUGG --outMode=C --noSeed --outOverlap=B -n 3 +Pu1;Pu2;subseqDB;hybridDB +0.00133893;0.00133893;4CACCCCCGGUG&4CACCCCCGGUG;4||||...||||&4||||...|||| +0.00134094;0.00134094;5ACCCCCGGUGGU&5ACCCCCGGUGGU;5|||||.||.|||&5|||||.||.||| +0.00133686;0.0013368;1AAACACCCCCGGUG&4CACCCCCGGUGGUUU;1|||||||...||||&4||||...||||.||| +``` + + + +### Backward compatible IntaRNA v1.* output + +If your scripts/whatever is tuned to the old IntaRNA v1.* output, you can use +- `--outMode=1` : IntaRNA v1.* normal output +- `--outMode=O` : IntaRNA v1.* detailed output (former `-o` option) + + + + +

+
+## Suboptimal RNA-RNA interaction prediction and output restrictions + +Besides the identification of the optimal (e.g. minimum-free-energy) RNA-RNA +interaction, IntaRNA enables the enumeration of suboptimal interactions. To this +end, the argument `-n N` or `--outNumber=N` can be used to generate up to `N` +interactions for each query-target pair (including the optimal one). Note, the +suboptimal enumeration is increasingly sorted by energy. + +Furthermore, it is possible to *restrict (sub)optimal enumeration* using +- `--outMaxE` : maximal energy for any interaction reported +- `--outDeltaE` : maximal energy difference of suboptimal interactions' energy + to the minimum free energy interaction +- `--outOverlap` : defines if an where overlapping of reported interaction sites + is allowed (Note, IntaRNA v1.* used implicitly the 'T' mode): + - 'N' : no overlap neither in target nor query allowed for reported interactions + - 'B' : overlap allowed for interacting subsequences for both target and query + - 'T' : overlap allowed for interacting subsequences in target only + - 'Q' : overlap allowed for interacting subsequences in query only + + + + + +

+
+## Energy parameters and temperatures + +The selection of the correct temperature and energy parameters is cruicial for +a correct RNA-RNA interaction prediction. To this end, various settings are +supported by IntaRNA. + +The temperature can be set via `--temperature=C`to set a temperature `C` in +degree Celsius. Note, this is important especially for predictions within plants +etc., since the default temperature is 37°C. + +The energy model used can be specified using the `--energy` parameters using +- 'B' for base pair maximization similar to the Nussinov intramolecular structure prediction. + Here, each base pair contributes an energy term of `-1` independently of its + structural or sequence context. This mode is mainly useful for study or teaching + purpose. +- 'V' enables *Nearest Neighbor Model* energy computation similar to the Zuker + intramolecular structure prediction using the Vienna RNA package routines. + Within this model, the energy contribution of a base + pair depends on its directly enclosed (neighbored) basepair and the subsequence(s) + involved. Different energy parameter sets have been experimentally derived + in the last decades. Since IntaRNA makes use of the energy evaluation routines + of the Vienna RNA package, all parameter sets from the Vienna RNA package are + available for RNA-RNA interaction prediction. Per default, the default parameter + set of the linked Vienna RNA package version is used. You can change the parameter + set using the `--energyVRNA` parameter as explained below. + +If Vienna RNA package is used for energy computation (`--energy=V`), per default +the default parameter set of the linked Vienna RNA package is used (e.g. the +set `Turner04` for VRNA 2.3.0). If you want to use a different parameter set, you +can provide an according parameter file via `--energVRNA=MyParamFile`. The +following example exemplifies the use of the old `Turner99` parameter set as +used by IntaRNA v1.*. +```bash +# IntaRNA v1.* like energy parameter setup +IntaRNA --energyVRNA=/usr/local/share/Vienna/rna_turner1999.par --seedMaxE=999 +``` + +To increase prediction quality and to reduce the computational complexity, the +number of unpaired bases between intermolecular base pairs is restricted +(similar to internal loop length restrictions in the Zuker algorithm). The +upper bound can be set independent for the query and target sequence via +`--qIntLoopMax` and `--tIntLoopMax`, respectively, and default to 16. + + + +

+
+## Accessibility and unpaired probabilities + +Accessibility describes the availability of an RNA subsequence for intermolecular +base pairing. It can be expressed in terms of the probability of the subsequence +to be unpaired (its *unpaired probability* *Pu*). + +A limited accessibility, i.e. a low unpaired probability, can be incorporated into +the RNA-RNA interaction prediction by adding according energy penalties. +These so called *ED* values are transformed unpaired probabilities, i.e. the +penalty for a subsequence partaking in an interaction is given by *ED=-RT log(Pu)*, +where *Pu* denotes the unpaired probability of the subsequence. Within the +IntaRNA energy model, *ED* values for both interacting subsequences are considered. + +Accessibility incorporation can be disabled for query or target sequences using +`--qAcc=N` or `--tAcc=N`, respectively. + +A setup of `--qAcc=C` or `--tAcc=C` (default) enables accessibility computation +using the Vienna RNA package routines for query or target sequences, respectively. + + + +### Local versus global unpaired probabilities + +Exact computation of unpaired probabilities (*Pu* terms) is considers all possible +structures the sequence can adopt (the whole structure ensemble). This is referred +to as *global unpaired probabilities* as computed e.g. by **RNAup**. + +Since global probability computation is (a) computationally demanding and (b) not +reasonable for long sequences, local RNA folding was suggested, which also enables +according *local unpaired probability* computation, as e.g. done by **RNAplfold**. +Here, a folding window of a defined length 'screens' along the RNA and computes +unpaired probabilities within the window (while only intramolecular base pairs +within the window are considered). + +IntaRNA enables both global as well as local unpaired probability computation. +To this end, the sliding window length has to be specified in order to enable/disable +local folding. + +#### Use case examples global/local unpaired probability computation +The use of global or local accessibilities can be defined independently +for query and target sequences using `--qAccW|L` and `--tAccW|L`, respectively. +Here, `--?AccW` defines the sliding window length (0 sets it to the whole sequence length) +and `--?AccL` defines the maximal length of considered intramolecular base pairs, +i.e. the maximal number of positions enclosed by a base pair +(0 sets it to the whole sequence length). Both can be defined +independently while respecting `AccL <= AccW`. +```bash +# using global accessibilities for query and target +IntaRNA [..] --qAccW=0 --qAccL=0 --tAccW=0 --qAccL=0 +# using local accessibilities for target and global for query +IntaRNA [..] --qAccW=0 --qAccL=0 --tAccW=150 --qAccL=100 ``` -doi: 10.1093/bioinformatics/btn544 + + + +### Read/write accessibility from/to file or stream + +It is possible to read precomputed accessibility values from file or stream to +avoid their runtime demanding computation. To this end, we support the following +formats + +| Input format | produced by | +| ---- | --- | +| RNAplfold unpaired probabilities | `RNAplfold -u` or `IntaRNA --out*PuFile` | +| RNAplfold-styled ED values | `IntaRNA --out*AccFile` | + +The **RNAplfold** format is a table encoding of a banded upper triangular matrix +with band width l. First row contains a header comment on the data starting with +`#`. Second line encodes the column headers, i.e. the window width per column. +Every successive line starts with the index (starting from 1) of the window end +followed by a tabulator separated list for each windows value in increasing +window length order. That is, column 2 holds values for window length 1, column +3 for length 2, ... . The following provides a short output/input +example for a sequence of length 5 with a maximal window length of 3. + ``` +#unpaired probabilities + #i$ l=1 2 3 +1 0.9949492 NA NA +2 0.9949079 0.9941056 NA +3 0.9554214 0.9518663 0.9511048 +4 0.9165814 0.9122866 0.9090283 +5 0.998999 0.915609 0.9117766 +6 0.8549929 0.8541667 0.8448852 + +``` + +#### Use case examples for read/write accessibilities and unpaired probabilities +If you have precomputed data, e.g. the file `plfold_lunp` with unpaired probabilities +computed by **RNAplfold**, you can run +```bash +# fill accessibilities from RNAplfold unpaired probabilities +IntaRNA [..] --qAcc=P --qAccFile=plfold_lunp +# fill accessibilities from RNAplfold unpaired probabilities via pipe +cat plfold_lunp | IntaRNA [..] --qAcc=P --qAccFile=STDIN +``` +Another option is to store the accessibility data computed by IntaRNA for +successive calls using +```bash +# storing and reusing (target) accessibility (Pu) data for successive IntaRNA calls +IntaRNA [..] --outTPuFile=intarna.target.pu +IntaRNA [..] --tAcc=P --tAccFile=intarna.target.pu +# piping (target) accessibilities (ED values) between IntaRNA calls +IntaRNA [..] --outTAccFile=STDOUT | IntaRNA [..] --tAcc=E --tAccFile=STDIN +``` + + +

+
+## Multi-threading and parallelized computation + +IntaRNA supports the parallelization of the target-query-combination processing. +The maximal number of threads to be used can be specified using the `--threads` parameter. +If `--threads=k > 0`, than *k* predictions are processed in parallel. + +When using parallelization, you should have the following things in mind: + +- Most of the IntaRNA runtime (in heuristic prediction mode) + is consumed by [accessibility computation](#accessibility) + (if not [loaded from file](#accFromFile)). + Currently, due to some thread-safety issues with the + routines from the Vienna RNA package, the IntaRNA + accessibility computation is done serially. This significantly reduces the + multi-threading effect when running IntaRNA in the fast heuristic mode (`--mode=H`). + If you run a non-heuristic prediction mode, multi-threading will show a more + dramatic decrease in runtime performance, since here the interaction prediction + is the computationally more demanding step. +- The memory consumption will be much higher, since each thread runs an independent + prediction (with according memory consumption). Thus, ensure you have enough + RAM available when using many threads of memory-demanding + [prediction modes](#predModes). + +The support for multi-threading can be completely disabled before compilation +using `configure --disable-multithreading`. diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index 9de60828..00000000 --- a/aclocal.m4 +++ /dev/null @@ -1,951 +0,0 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.66],, -[m4_warning([this file was generated for autoconf 2.66. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) - -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.1], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.1])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 9 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 10 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -#serial 5 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 16 - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl -]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) - -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST(install_sh)]) - -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 6 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 5 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; -esac - -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006, 2008 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - diff --git a/autotools-init.sh b/autotools-init.sh new file mode 100644 index 00000000..c0b45757 --- /dev/null +++ b/autotools-init.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# +# Run this before configure +# + +set -e -o pipefail + +#test -d config || mkdir config +# Produce aclocal.m4, so autoconf gets the automake macros it needs +echo "Creating aclocal.m4..." +aclocal || exit $?; + +# Produce config.h raw file +autoheader || exit $?; + +# Produce all the `Makefile.in's, verbosely, and create neat missing things +# like `libtool', `install-sh', etc. +automake --add-missing --gnu --copy || exit $?; + +# If there's a config.cache file, we may need to delete it. +# If we have an existing configure script, save a copy for comparison. +if [ -f config.cache ] && [ -f configure ]; then + cp configure configure.$$.tmp +fi + +# Produce ./configure +echo "Creating configure..." +autoconf || exit $?; + +echo "" +echo "You can run ./configure [--prefix=$HOME] now." +echo "" diff --git a/configure b/configure deleted file mode 100755 index a9beb279..00000000 --- a/configure +++ /dev/null @@ -1,5901 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.66 for IntaRNA 1.2.5. -# -# Report bugs to . -# -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: intarna@informatik.uni-freiburg.de about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='IntaRNA' -PACKAGE_TARNAME='intarna' -PACKAGE_VERSION='1.2.5' -PACKAGE_STRING='IntaRNA 1.2.5' -PACKAGE_BUGREPORT='intarna@informatik.uni-freiburg.de' -PACKAGE_URL='' - -ac_unique_file="src/energy.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -EGREP -GREP -CXXCPP -am__fastdepCXX_FALSE -am__fastdepCXX_TRUE -CXXDEPMODE -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -ac_ct_CC -CFLAGS -CC -OBJEXT -EXEEXT -ac_ct_CXX -CPPFLAGS -LDFLAGS -CXXFLAGS -CXX -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_dependency_tracking -with_RNA -enable_debug -' - ac_precious_vars='build_alias -host_alias -target_alias -CXX -CXXFLAGS -LDFLAGS -LIBS -CPPFLAGS -CCC -CC -CFLAGS -CXXCPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures IntaRNA 1.2.5 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/intarna] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of IntaRNA 1.2.5:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --enable-debug enable debug mode and assertions (default=disabled) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-RNA=PREFIX alternative prefix path to Vienna RNA library - -Some influential environment variables: - CXX C++ compiler command - CXXFLAGS C++ compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CC C compiler command - CFLAGS C compiler flags - CXXCPP C++ preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -IntaRNA configure 1.2.5 -generated by GNU Autoconf 2.66 - -Copyright (C) 2010 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_cxx_try_compile LINENO -# ---------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_compile - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_cxx_try_cpp LINENO -# ------------------------ -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_cpp - -# ac_fn_cxx_try_run LINENO -# ------------------------ -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_cxx_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_run - -# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES -# --------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_cxx_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_cxx_check_type - -# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES -# --------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_cxx_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_cxx_check_header_compile - -# ac_fn_cxx_try_link LINENO -# ------------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_link -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by IntaRNA $as_me 1.2.5, which was -generated by GNU Autoconf 2.66. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -ac_aux_dir= -for ac_dir in . "$srcdir"/.; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - -# Checks for programs. -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CXX+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 -$as_echo_n "checking whether the C++ compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C++ compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 -$as_echo_n "checking for C++ compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C++ compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -else - CXXFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - -else - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -am__api_version='1.11' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; -esac - -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if test "${ac_cv_path_mkdir+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='intarna' - VERSION='1.2.5' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -depcc="$CXX" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -############################################################################### -# BEGIN PATH-SUPPORT CHECK -############################################################################### - -# Vienna RNA package library path support, if not installed in usual directories - -# Check whether --with-RNA was given. -if test "${with_RNA+set}" = set; then : - withval=$with_RNA; RNAPATHSET=1 -else - RNAPATHSET=0 - -fi - -if test $RNAPATHSET = 1 ; then - CXXFLAGS="-I$with_RNA/include $CXXFLAGS" - LDFLAGS="-L$with_RNA/lib $LDFLAGS" -fi - -# add the Vienna RNA lib to the libraries used -LIBS="-lRNA $LIBS" - -############################################################################### -# END PATH-SUPPORT CHECK -############################################################################### - -# add all libraries to the LDFLAGS for linking -LDFLAGS="$LDFLAGS $LIBS" - -############################################################################### -# BEGIN MISC CHECKS -############################################################################### - -# Checks for header files. - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 -$as_echo_n "checking how to run the C++ preprocessor... " >&6; } -if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 -$as_echo "$CXXCPP" >&6; } -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_cxx_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - - -# Checks for typedefs, structures, and compiler characteristics. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if test "${ac_cv_c_const+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset cs; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = x""yes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - - -# Check if everything should be compiled in DEBUG mode -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build in debug mode with assertions" >&5 -$as_echo_n "checking whether to build in debug mode with assertions... " >&6; } -debuger=no -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; debuger="$enableval" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debuger" >&5 -$as_echo "$debuger" >&6; } -if test x"$debuger" = x"yes"; then - $as_echo "#define DEBUG 1" >>confdefs.h - - CXXFLAGS="$CXXFLAGS -g -Wall -Wno-uninitialized -O0" - LDFLAGS="$LDFLAGS -g -Wall -Wno-uninitialized -O0" -else - $as_echo "#define NDEBUG 1" >>confdefs.h - - CXXFLAGS="-O2 $CXXFLAGS" -fi - -############################################################################### -# END MISC CHECKS -############################################################################### - -############################################################################### -# BEGIN VIENNA CHECK -############################################################################### - -# check for Vienna RNA headers -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Vienna RNA C header" >&5 -$as_echo_n "checking for the Vienna RNA C header... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - #include -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for energy_of_struct in -lRNA" >&5 -$as_echo_n "checking for energy_of_struct in -lRNA... " >&6; } -if test "${ac_cv_lib_RNA_energy_of_struct+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lRNA $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char energy_of_struct (); -int -main () -{ -return energy_of_struct (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_lib_RNA_energy_of_struct=yes -else - ac_cv_lib_RNA_energy_of_struct=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_RNA_energy_of_struct" >&5 -$as_echo "$ac_cv_lib_RNA_energy_of_struct" >&6; } -if test "x$ac_cv_lib_RNA_energy_of_struct" = x""yes; then : - RNANOTFOUND=0 -else - RNANOTFOUND=1 -fi - - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - RNANOTFOUND=1; - - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -############################################################################### -# END VIENNA CHECK -############################################################################### - - -############################################################################### -# BEGIN DO NOT COMPILE CHECKS -############################################################################### - -# flag for final abort if one of the dependency was not found but all were checked -DEPENDENCYNOTFOUND=0; - -# error output if ViennaRNA not found -if test "$RNANOTFOUND" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: the Vienna RNA C library is required for building the program." >&5 -$as_echo "$as_me: the Vienna RNA C library is required for building the program." >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: it can be obtained from http://www.tbi.univie.ac.at/~ivo/RNA/." >&5 -$as_echo "$as_me: it can be obtained from http://www.tbi.univie.ac.at/~ivo/RNA/." >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} - if test "$RNAPATHSET" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: cant find Vienna RNA library in given path '$with_RNA'." >&5 -$as_echo "$as_me: cant find Vienna RNA library in given path '$with_RNA'." >&6;} - else - { $as_echo "$as_me:${as_lineno-$LINENO}: if Vienna RNA is installed elsewhere use --with-RNA=PREFIX." >&5 -$as_echo "$as_me: if Vienna RNA is installed elsewhere use --with-RNA=PREFIX." >&6;} - fi - DEPENDENCYNOTFOUND=1; -fi - -# error ABORT if on of the libraries was not found -if test "$DEPENDENCYNOTFOUND" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} - as_fn_error $? "library not found! Try './configure --help'." "$LINENO" 5 -fi - -############################################################################### -# END DO NOT COMPILE CHECKS -############################################################################### - - - -ac_config_files="$ac_config_files Makefile" - -ac_config_files="$ac_config_files src/Makefile" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - - -: ${CONFIG_STATUS=./config.status} -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by IntaRNA $as_me 1.2.5, which was -generated by GNU Autoconf 2.66. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -IntaRNA config.status 1.2.5 -configured by $0, generated by GNU Autoconf 2.66, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2010 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - - -eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff --git a/configure.ac b/configure.ac index 2ef42ae2..db8b9168 100644 --- a/configure.ac +++ b/configure.ac @@ -1,139 +1,231 @@ - -AC_PREREQ(2.59) - -AC_INIT([IntaRNA], [1.2.5], [intarna@informatik.uni-freiburg.de]) - -AC_CONFIG_SRCDIR(src/energy.h) -AC_CONFIG_AUX_DIR([.]) - -# Checks for programs. -AC_PROG_CXX -AC_PROG_CC - -AM_INIT_AUTOMAKE - -AC_LANG_CPLUSPLUS - -############################################################################### -# BEGIN PATH-SUPPORT CHECK -############################################################################### - -# Vienna RNA package library path support, if not installed in usual directories -AC_ARG_WITH(RNA, - AC_HELP_STRING( - [--with-RNA=PREFIX], - [alternative prefix path to Vienna RNA library] - ), - RNAPATHSET=1, - RNAPATHSET=0 -) -if test $RNAPATHSET = 1 ; then - CXXFLAGS="-I$with_RNA/include $CXXFLAGS" - LDFLAGS="-L$with_RNA/lib $LDFLAGS" -fi - -# add the Vienna RNA lib to the libraries used -LIBS="-lRNA $LIBS" - -############################################################################### -# END PATH-SUPPORT CHECK -############################################################################### - -# add all libraries to the LDFLAGS for linking -LDFLAGS="$LDFLAGS $LIBS" - -############################################################################### -# BEGIN MISC CHECKS -############################################################################### - -# Checks for header files. -AC_HEADER_STDC - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_TYPE_SIZE_T - -# Check if everything should be compiled in DEBUG mode -AC_MSG_CHECKING(whether to build in debug mode with assertions) -debuger=no -AC_ARG_ENABLE(debug, - AC_HELP_STRING( - [--enable-debug], - [enable debug mode and assertions (default=disabled)] - ), - debuger="$enableval" -) -AC_MSG_RESULT($debuger) -if test x"$debuger" = x"yes"; then - AC_DEFINE(DEBUG) - CXXFLAGS="$CXXFLAGS -g -Wall -Wno-uninitialized -O0" - LDFLAGS="$LDFLAGS -g -Wall -Wno-uninitialized -O0" -else - AC_DEFINE(NDEBUG) - CXXFLAGS="-O2 $CXXFLAGS" -fi - -############################################################################### -# END MISC CHECKS -############################################################################### - -############################################################################### -# BEGIN VIENNA CHECK -############################################################################### - -# check for Vienna RNA headers -AC_MSG_CHECKING([for the Vienna RNA C header]) -AC_COMPILE_IFELSE( - [ #include ], - [ - AC_MSG_RESULT(yes) - AC_CHECK_LIB(RNA, [energy_of_struct], [RNANOTFOUND=0], [ RNANOTFOUND=1]) - ], - [ - AC_MSG_RESULT(no) - RNANOTFOUND=1; - ] -) - -############################################################################### -# END VIENNA CHECK -############################################################################### - - -############################################################################### -# BEGIN DO NOT COMPILE CHECKS -############################################################################### - -# flag for final abort if one of the dependency was not found but all were checked -DEPENDENCYNOTFOUND=0; - -# error output if ViennaRNA not found -if test "$RNANOTFOUND" = "1"; then - AC_MSG_NOTICE() - AC_MSG_NOTICE(the Vienna RNA C library is required for building the program.) - AC_MSG_NOTICE(it can be obtained from http://www.tbi.univie.ac.at/~ivo/RNA/.) - AC_MSG_NOTICE() - if test "$RNAPATHSET" = "1"; then - AC_MSG_NOTICE(cant find Vienna RNA library in given path '$with_RNA'.) - else - AC_MSG_NOTICE(if Vienna RNA is installed elsewhere use --with-RNA=PREFIX.) - fi - DEPENDENCYNOTFOUND=1; -fi - -# error ABORT if on of the libraries was not found -if test "$DEPENDENCYNOTFOUND" = "1"; then - AC_MSG_NOTICE() - AC_MSG_ERROR(library not found! Try './configure --help'.) -fi - -############################################################################### -# END DO NOT COMPILE CHECKS -############################################################################### - - - -AC_CONFIG_FILES([ Makefile ]) -AC_CONFIG_FILES([ src/Makefile ]) - -AC_OUTPUT +# this is example-file: configure.ac + +AC_PREREQ([2.65]) +# 5 argument version only available with aclocal >= 2.64 +AC_INIT( [IntaRNA], [2.0.0], [], [intaRNA], [http://www.bioinf.uni-freiburg.de] ) + + +# minimal required version of the boost library +BOOST_REQUIRED_VERSION=1.50.0 + + +AC_CANONICAL_HOST +AC_CONFIG_AUX_DIR([.]) +AC_CONFIG_SRCDIR([src/intaRNA.cpp]) +AC_CONFIG_HEADERS([src/config.h]) + +m4_include([m4/m4_ax_boost_base.m4]) +m4_include([m4/m4_ax_cxx_compile_stdcxx.m4]) +m4_include([m4/m4_ax_openmp.m4]) + +lt_enable_auto_import="" +case "$host_os" in + cygwin* | mingw* | cegcc*) + AM_LDFLAGS="-Wl,--enable-auto-import $AM_LDFLAGS" +esac + +# Checks for programs + +# check for C++ compiler +# store current compiler flags to avoid default setup via AC_PROG_CXX and *_CC +OLD_CXXFLAGS=$CXXFLAGS +OLD_CFLAGS=$CFLAGS +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +# reset compiler flags to initial flags +CXXFLAGS=$OLD_CXXFLAGS +CFLAGS=$OLD_CFLAGS + +# automake initialisation (mandatory) and check for minimal automake API version +AM_INIT_AUTOMAKE([1.11]) + +# use the C++ compiler for the following checks +AC_LANG([C++]) + +# ensure we are using c11 C++ standard +AX_CXX_COMPILE_STDCXX( [11], [noext], [mandatory]) + +# ensure OPENMP can be used +AX_OPENMP([],[AC_MSG_ERROR([OPENMP support is mandatory for compilation])]]) +AM_CXXFLAGS="$AM_CXXFLAGS $OPENMP_CXXFLAGS" + +############################################################################### +############################################################################### + +############ PARAMETERS ######################################## + +############################################################################### +# DEBUG SUPPORT SETUP +############################################################################### + +AC_MSG_CHECKING([whether to build with debug information]) +debuger=no +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [enable debug data generation (def=disabled)])], + [debuger="$enableval"]) +AC_MSG_RESULT([$debuger]) +if test x"$debuger" = x"yes"; then + AC_DEFINE([_DEBUG], [1], [Run in DEBUG mode with additional assertions and debug output]) + AM_CXXFLAGS="$AM_CXXFLAGS -g -O0 -Wno-uninitialized -Wno-deprecated" # -Wall" +else + AC_DEFINE([NDEBUG], [1], [Run in normal mode with minimal assertions]) + AM_CXXFLAGS="$AM_CXXFLAGS -O3 -fno-strict-aliasing -Wno-uninitialized -Wno-deprecated" +fi + + +############################################################################### +# DEBUG SUPPORT SETUP +############################################################################### + +AC_MSG_CHECKING([whether to enable multi-threading support]) +multithreadingEnabled=yes +AC_ARG_ENABLE([multithreading], + [AS_HELP_STRING([--disable-multithreading], + [disable multi-threading support (def=enabled)])], + [multithreadingEnabled="$enableval"], + [multithreadingEnabled=yes]) +AC_MSG_RESULT([$multithreadingEnabled]) +if test x"$multithreadingEnabled" = x"yes"; then + AC_DEFINE([INTARNA_MULITHREADING], [1], [Enabling multi-threading support]) + AC_SUBST([INTARNA_MULITHREADING],[1]) +else + AC_DEFINE([INTARNA_MULITHREADING], [0], [Disabling multi-threading support]) + AC_SUBST([INTARNA_MULITHREADING],[0]) +fi + +############################################################################### +# Vienna RNA package library path support, if not installed in usual directories +############################################################################### +AC_ARG_WITH([RNA], + [AC_HELP_STRING( + [--with-RNA=PREFIX], + [alternative prefix path to Vienna RNA library] + )], + [RNAPATHSET=1], + [RNAPATHSET=0] +) +if test $RNAPATHSET = 1 ; then + # set compiler and linker flags if needed + AM_CXXFLAGS="-I$with_RNA/include $AM_CXXFLAGS" + AM_LDFLAGS="-L$with_RNA/lib $AM_LDFLAGS" +fi + +############################################################################### +############################################################################### + + +############################################################################### +# BOOST CHECK +############################################################################### + +AX_BOOST_BASE([$BOOST_REQUIRED_VERSION], [FOUND_BOOST=1;], [FOUND_BOOST=0;]) + + +############ CHECKS ############################################ + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T + +# Checks for header files. +AC_HEADER_STDC + + +########################################################################## +# check boost test results +########################################################################## + +# FOUND_BOOST is only defined if want_boost is "yes" +if test $want_boost = "no" || test $FOUND_BOOST != 1; then + AC_MSG_NOTICE([]) + AC_MSG_NOTICE([The Boost Library was not found!]) + AC_MSG_NOTICE([ -> If installed in a non-standard path, please use '--with-boost=PREFIX'.]) + AC_MSG_NOTICE([]) + DEPENDENCYNOTFOUND=1; +else + AM_CXXFLAGS="$BOOST_CPPFLAGS $AM_CXXFLAGS" + AM_LDFLAGS="$BOOST_LDFLAGS $AM_LDFLAGS" + LIBS="$LIBS -lboost_regex -lboost_program_options -lboost_filesystem -lboost_system" +fi + + +############################################################################### +# BEGIN VIENNA CHECK +############################################################################### +# check for Vienna RNA headers +AC_MSG_CHECKING([for the Vienna RNA package headers version >= 2.3.0]) +OLD_CPPFLAGS=$CPPFLAGS +OLD_CXXFLAGS=$CXXFLAGS +OLD_LDFLAGS=$LDFLAGS +AC_LANG_PUSH([C]) +CPPFLAGS="$CPPFLAGS $AM_CXXFLAGS" +LDFLAGS="$LDFLAGS $AM_LDFLAGS" +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include ]],[[vrna_md_t tmp; vrna_md_copy(&tmp,&tmp);]])], + [ + AC_MSG_RESULT([yes]) + RNANOTFOUND=0; + ], + [ + AC_MSG_RESULT([no]) + AC_MSG_NOTICE([DEBUG : used CPPFLAGS = $CPPFLAGS]) + AC_MSG_NOTICE([DEBUG : used LDFLAGS = $LDFLAGS]) + RNANOTFOUND=1; + ] +) +AC_LANG_POP([C]) +CPPFLAGS=$OLD_CPPFLAGS +LDFLAGS=$OLD_LDFLAGS + +# error output if ViennaRNA not found +if test "$RNANOTFOUND" = "1"; then + AC_MSG_NOTICE() + AC_MSG_NOTICE([The Vienna RNA C library version >= 2.3.0 is required.]) + AC_MSG_NOTICE([ -> It can be obtained from http://www.tbi.univie.ac.at/.]) + AC_MSG_NOTICE() + if test "$RNAPATHSET" = "1"; then + AC_MSG_NOTICE([ -> Can't find the Vienna RNA library in given path '$with_RNA'.]) + else + AC_MSG_NOTICE([ -> If installed in a non-standard path, please use '--with-RNA=PREFIX'.]) + fi + DEPENDENCYNOTFOUND=1; +else + # register Vienna RNA lib for linking + LIBS="$LIBS -lRNA" +fi + + +############################################################################### +# END VIENNA CHECK +############################################################################### + +############################################################################### +# FINAL DEPENDENCY CHECK AND EXIT IF NEEDED +############################################################################### + +# error ABORT if on of the libraries was not found +if test "$DEPENDENCYNOTFOUND" = "1"; then + AC_MSG_NOTICE() + AC_MSG_ERROR([Some dependency was not met! See above for errors and relate to './configure --help'.]) +fi + +########################################################################## + + + +# distribute additional compiler and linker flags +# --> set these variables instead of CXXFLAGS or LDFLAGS +AC_SUBST([AM_CXXFLAGS]) +AC_SUBST([AM_LDFLAGS]) +AC_SUBST([LIBS]) + +# files to generate via autotools (.am or .in source files) +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([src/Makefile]) +AC_CONFIG_FILES([src/intarna_config.h]) +AC_CONFIG_FILES([perl/Makefile]) +AC_CONFIG_FILES([tests/Makefile]) + +# generate the final Makefile etc. +AC_OUTPUT diff --git a/depcomp b/depcomp deleted file mode 100755 index e5f9736c..00000000 --- a/depcomp +++ /dev/null @@ -1,589 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2007-03-29.01 - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software -# Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program 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 General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. - sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/install-sh b/install-sh deleted file mode 100755 index a5897de6..00000000 --- a/install-sh +++ /dev/null @@ -1,519 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2006-12-25.00 - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/m4/m4_ax_boost_base.m4 b/m4/m4_ax_boost_base.m4 new file mode 100644 index 00000000..54a2a1be --- /dev/null +++ b/m4/m4_ax_boost_base.m4 @@ -0,0 +1,258 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# DESCRIPTION +# +# Test for the Boost C++ libraries of a particular version (or newer) +# +# If no path to the installed boost library is given the macro searchs +# under /usr, /usr/local, /opt and /opt/local and evaluates the +# $BOOST_ROOT environment variable. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) +# +# And sets: +# +# HAVE_BOOST +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2009 Peter Adolphs +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 20 + +AC_DEFUN([AX_BOOST_BASE], +[ +AC_ARG_WITH([boost], + [AS_HELP_STRING([--with-boost@<:@=ARG@:>@], + [use Boost library from a standard location (ARG=yes), + from the specified location (ARG=), + or disable it (ARG=no) + @<:@ARG=yes@:>@ ])], + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ac_boost_path="" + else + want_boost="yes" + ac_boost_path="$withval" + fi + ], + [want_boost="yes"]) + + +AC_ARG_WITH([boost-libdir], + AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), + [ + if test -d "$withval" + then + ac_boost_lib_path="$withval" + else + AC_MSG_ERROR(--with-boost-libdir expected directory name) + fi + ], + [ac_boost_lib_path=""] +) + +if test "x$want_boost" = "xyes"; then + boost_lib_version_req=ifelse([$1], ,1.20.0,$1) + boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` + boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` + boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` + boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + if test "x$boost_lib_version_req_sub_minor" = "x" ; then + boost_lib_version_req_sub_minor="0" + fi + WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` + AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) + succeeded=no + + dnl On 64-bit systems check for system libraries in both lib64 and lib. + dnl The former is specified by FHS, but e.g. Debian does not adhere to + dnl this (as it rises problems for generic multi-arch support). + dnl The last entry in the list is chosen by default when no libraries + dnl are found, e.g. when only header-only libraries are installed! + libsubdirs="lib" + ax_arch=`uname -m` + if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64; then + libsubdirs="lib64 lib lib64" + fi + + dnl first we check the system location for boost libraries + dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl or if you install boost with RPM + if test "$ac_boost_path" != ""; then + BOOST_CPPFLAGS="-I$ac_boost_path/include" + for ac_boost_path_tmp in $libsubdirs; do + if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then + BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" + break + fi + done + elif test "$cross_compiling" != yes; then + for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then + for libsubdir in $libsubdirs ; do + if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + break; + fi + done + fi + + dnl overwrite ld flags if we have required special directory with + dnl --with-boost-libdir parameter + if test "$ac_boost_lib_path" != ""; then + BOOST_LDFLAGS="-L$ac_boost_lib_path" + fi + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_REQUIRE([AC_PROG_CXX]) + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + + + + dnl if we found no boost with system layout we search for boost libraries + dnl built and installed without the --layout=system option or for a staged(not installed) version + if test "x$succeeded" != "xyes"; then + _version=0 + if test "$ac_boost_path" != ""; then + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + fi + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" + done + fi + else + if test "$cross_compiling" != yes; then + for ac_boost_path in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + best_path=$ac_boost_path + fi + done + fi + done + + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" + if test "$ac_boost_lib_path" = ""; then + for libsubdir in $libsubdirs ; do + if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$best_path/$libsubdir" + fi + fi + + if test "x$BOOST_ROOT" != "x"; then + for libsubdir in $libsubdirs ; do + if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then + version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` + stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` + stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` + V_CHECK=`expr $stage_version_shorten \>\= $_version` + if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then + AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) + BOOST_CPPFLAGS="-I$BOOST_ROOT" + BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" + fi + fi + fi + fi + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + fi + + if test "$succeeded" != "yes" ; then + if test "$_version" = "0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) + else + AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) + fi + # execute ACTION-IF-NOT-FOUND (if present): + ifelse([$3], , :, [$3]) + else + AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_LDFLAGS) + AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) + # execute ACTION-IF-FOUND (if present): + ifelse([$2], , :, [$2]) + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" +fi + +]) diff --git a/m4/m4_ax_cxx_compile_stdcxx.m4 b/m4/m4_ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000..2c18e49c --- /dev/null +++ b/m4/m4_ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,562 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 4 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) diff --git a/m4/m4_ax_openmp.m4 b/m4/m4_ax_openmp.m4 new file mode 100644 index 00000000..26639faa --- /dev/null +++ b/m4/m4_ax_openmp.m4 @@ -0,0 +1,123 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_openmp.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro tries to find out how to compile programs that use OpenMP a +# standard API and set of compiler directives for parallel programming +# (see http://www-unix.mcs/) +# +# On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS +# output variable to the flag (e.g. -omp) used both to compile *and* link +# OpenMP programs in the current language. +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. +# +# If you want to compile everything with OpenMP, you should set: +# +# CFLAGS="$CFLAGS $OPENMP_CFLAGS" +# #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" +# #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" +# +# (depending on the selected language). +# +# The user can override the default choice by setting the corresponding +# environment variable (e.g. OPENMP_CFLAGS). +# +# ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is +# found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is +# not found. If ACTION-IF-FOUND is not specified, the default action will +# define HAVE_OPENMP. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2015 John W. Peterson +# Copyright (c) 2016 Nick R. Papior +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 12 + +AC_DEFUN([AX_OPENMP], [ +AC_PREREQ([2.69]) dnl for _AC_LANG_PREFIX + +AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS +ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown +# Flags to try: -fopenmp (gcc), -mp (SGI & PGI), +# -qopenmp (icc>=15), -openmp (icc), +# -xopenmp (Sun), -omp (Tru64), +# -qsmp=omp (AIX), +# none +ax_openmp_flags="-fopenmp -openmp -qopenmp -mp -xopenmp -omp -qsmp=omp none" +if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then + ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" +fi +for ax_openmp_flag in $ax_openmp_flags; do + case $ax_openmp_flag in + none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; + *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; + esac + AC_LINK_IFELSE([AC_LANG_SOURCE([[ +@%:@include + +static void +parallel_fill(int * data, int n) +{ + int i; +@%:@pragma omp parallel for + for (i = 0; i < n; ++i) + data[i] = i; +} + +int +main() +{ + int arr[100000]; + omp_set_num_threads(2); + parallel_fill(arr, 100000); + return 0; +} +]])],[ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break],[]) +done +[]_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS +]) +if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then + m4_default([$2],:) +else + if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then + OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp + fi + m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) +fi +])dnl AX_OPENMP diff --git a/missing b/missing deleted file mode 100755 index 1c8ff704..00000000 --- a/missing +++ /dev/null @@ -1,367 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2006-05-10.23 - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program 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 General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - -esac - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). -case $1 in - lex|yacc) - # Not GNU programs, they don't have --version. - ;; - - tar) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $1 in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/perl/IntaRNA_1ui.pl b/perl/IntaRNA_1ui.pl new file mode 100644 index 00000000..5e79bcac --- /dev/null +++ b/perl/IntaRNA_1ui.pl @@ -0,0 +1,130 @@ +#!/usr/bin/env/perl -w + +use strict; +use Getopt::Std; +use File::Basename qw( dirname ); + +my $intaRNAbinPath = dirname(__FILE__)."/"; + +my %args; + +getopt("t:m:v:s:p:w:L:l:T:u:", \%args); + +if (defined $args{h} && $args{h}==1) { +print " +\n +Synopsis : IntaRNA [-t fasta_file] [-m fasta_file] "#[-v energy] +."[-o]\n + [-s number] [-n] [-h] "#[-u[1|2] number] +."[-u number]\n + [-p number] "#[-f pos,pos] +."[-T temp] "#[-U] [-P] +."[-w size]\n + [-L distance] [-l length] \n" +#[-a weight] [-b weight]\n +# [-c threshold] target-RNA-seq binding-RNA-seq\n +."\n +Description : User interface wrapper for intaRNA v1 like calls.\n +\n +Options :\n + === General parameters ===\n + -t fasta_file : use fasta file of target sequences\n + -m fasta_file : use fasta file of binding sequences\n + -v energy : outputs all results below energy in kcal/mol\n + -o : detailed output\n + -s number : max. number of calculated suboptimal results\n + (default:0)\n + -n : use no heuristic for hybridization end\n + (complete approach, more time-consuming)\n + Does not support -s option\n + -h : this help\n +\n + === Seed parameters ===\n + -p number : exact number of paired bases in the seed region\n + (default:6)\n" +# -u[1|2] number : max. number of unpaired bases in the seed\n +# region in\n +# 1: the first sequence (default:0)\n +# 2: the second sequence (default:0)\n +." -u number : max. number of unpaired bases in the seed\n + region in both sequences (default:0)\n" +# -f number,number : search for seed in binding RNA (e.g. ncRNA)\n +# in region between positions start,end\n +# (given in 5' to 3' direction counting from 1)\n + +."\n + === RNA folding parameters ===\n + -T temp : temperature in Celsius (default: 37°C)\n" +# -U : use RNAup to compute ED values of binding RNA\n +# (default)\n +# -P : use RNAplfold to compute ED values of target RNA\n +# (default)\n +." -w size : window size for computation of ED values\n + with RNAplfold (default: length of target RNA)\n + -L distance : max. distance of two paired bases for\n + computation of ED values with RNAplfold\n + (default: window size)\n + -l length : max. length of hybridized region, mainly used\n + for efficient computation (default: window size)\n" +# -a weight : weight for ED values of target RNA in energy\n +# (default: 1.0)\n +# -b weight : weight for ED values of binding RNA in energy\n +# (default: 1.0)\n +# -c threshold : threshold for seed accessibility, requires u=0\n +# EXPERIMENTAL FEATURE, (default: -1.0)\n +.""; +exit 0; +} + + +# generate intaRNA 2 call +my $intaRNA2call = ""; +if (defined $args{t}) { $intaRNA2call .= " -t ".($args{t}); } +if (defined $args{m}) { $intaRNA2call .= " -q ".($args{m}); } +if (defined $args{v}) { $intaRNA2call .= " --outMaxE=".($args{v}); } +if (defined $args{s}) { $intaRNA2call .= " -n ".($args{s}+1); } +if (defined $args{p}) { $intaRNA2call .= " --seedBP=".($args{p}); } +if (defined $args{T}) { $intaRNA2call .= " --temperature=".($args{T}); } +if (defined $args{w}) { + $intaRNA2call .= " --tAccW=".($args{w}); +} else { + $intaRNA2call .= " --tAccW=0"; +} +# always full sequence length for query +$intaRNA2call .= " --qAccW=0"; +if (defined $args{L}) { + $intaRNA2call .= " --tAccL=".($args{L}); +} else { + $intaRNA2call .= " --tAccL=0"; +} +# always full sequence length for query +$intaRNA2call .= " --qAccL=0"; +if (defined $args{l}) { + $intaRNA2call .= " --tIntLenMax=".($args{l}); + $intaRNA2call .= " --qIntLenMax=".($args{l}); +} else { + $intaRNA2call .= " --tIntLenMax=0"; + $intaRNA2call .= " --qIntLenMax=0"; +} +if (defined $args{o} && $args{o}==1) { + # setup detailed v1 output + $intaRNA2call .=" --outMode=O"; +} else { + # setup normal v1 output + $intaRNA2call .=" --outMode=1"; +} +if (defined $args{n} && $args{n}==1) { + $intaRNA2call .= " --mode=E" +} else { + $intaRNA2call .= " --mode=H" +} +if (defined $args{u}) { + $intaRNA2call .= " --seedMaxUP=".$args{u} +} else { + $intaRNA2call .= " --seedMaxUP=0" +} +#$intaRNA2call .=" --seedMaxE=999"; # enable for IntaRNA v1-like seed handling +$intaRNA2call .=" --energy=V"; + +# call intaRNA 2 +system($intaRNAbinPath."IntaRNA"." ".$intaRNA2call); diff --git a/perl/IntaRNA_up_1ui.pl b/perl/IntaRNA_up_1ui.pl new file mode 100644 index 00000000..28fe81bc --- /dev/null +++ b/perl/IntaRNA_up_1ui.pl @@ -0,0 +1,127 @@ +#!/usr/bin/env/perl -w + +use strict; +use Getopt::Std; +use File::Basename qw( dirname ); + +my $intaRNAbinPath = dirname(__FILE__)."/"; + +my %args; + +getopt("t:m:v:s:p:w:L:l:T:u:", \%args); + +if (defined $args{h} && $args{h}==1) { +print " +\n +Synopsis : IntaRNA [-t fasta_file] [-m fasta_file] "#[-v energy] +."[-o]\n + [-s number] [-n] [-h] "#[-u[1|2] number] +."[-u number]\n + [-p number] "#[-f pos,pos] +."[-T temp] "#[-U] [-P] +."[-w size]\n + [-L distance] [-l length] \n" +#[-a weight] [-b weight]\n +# [-c threshold] target-RNA-seq binding-RNA-seq\n +."\n +Description : User interface wrapper for intaRNA v1 like calls.\n +\n +Options :\n + === General parameters ===\n + -t fasta_file : use fasta file of target sequences\n + -m fasta_file : use fasta file of binding sequences\n + -v energy : outputs all results below energy in kcal/mol\n + -o : detailed output\n + -s number : max. number of calculated suboptimal results\n + (default:0)\n + -n : use no seed constraint\n + -h : this help\n +\n + === Seed parameters ===\n + -p number : exact number of paired bases in the seed region\n + (default:6)\n" +# -u[1|2] number : max. number of unpaired bases in the seed\n +# region in\n +# 1: the first sequence (default:0)\n +# 2: the second sequence (default:0)\n +." -u number : max. number of unpaired bases in the seed\n + region in both sequences (default:0)\n" +# -f number,number : search for seed in binding RNA (e.g. ncRNA)\n +# in region between positions start,end\n +# (given in 5' to 3' direction counting from 1)\n + +."\n + === RNA folding parameters ===\n + -T temp : temperature in Celsius (default: 37°C)\n" +# -U : use RNAup to compute ED values of binding RNA\n +# (default)\n +# -P : use RNAplfold to compute ED values of target RNA\n +# (default)\n +." -w size : window size for computation of ED values\n + with RNAplfold (default: length of target RNA)\n + -L distance : max. distance of two paired bases for\n + computation of ED values with RNAplfold\n + (default: window size)\n + -l length : max. length of hybridized region, mainly used\n + for efficient computation (default: window size)\n" +# -a weight : weight for ED values of target RNA in energy\n +# (default: 1.0)\n +# -b weight : weight for ED values of binding RNA in energy\n +# (default: 1.0)\n +# -c threshold : threshold for seed accessibility, requires u=0\n +# EXPERIMENTAL FEATURE, (default: -1.0)\n +.""; +exit 0; +} + + +# generate intaRNA 2 call +my $intaRNA2call = ""; +if (defined $args{t}) { $intaRNA2call .= " -t ".($args{t}); } +if (defined $args{m}) { $intaRNA2call .= " -q ".($args{m}); } +if (defined $args{v}) { $intaRNA2call .= " --outMaxE=".($args{v}); } +if (defined $args{s}) { $intaRNA2call .= " -n ".($args{s}+1); } +if (defined $args{p}) { $intaRNA2call .= " --seedBP=".($args{p}); } +if (defined $args{T}) { $intaRNA2call .= " --temperature=".($args{T}); } +if (defined $args{w}) { + $intaRNA2call .= " --tAccW=".($args{w}); +} else { + $intaRNA2call .= " --tAccW=0"; +} +# always full sequence length for query +$intaRNA2call .= " --qAccW=0"; +if (defined $args{L}) { + $intaRNA2call .= " --tAccL=".($args{L}); +} else { + $intaRNA2call .= " --tAccL=0"; +} +# always full sequence length for query +$intaRNA2call .= " --qAccL=0"; +if (defined $args{l}) { + $intaRNA2call .= " --tIntLenMax=".($args{l}); + $intaRNA2call .= " --qIntLenMax=".($args{l}); +} else { + $intaRNA2call .= " --tIntLenMax=0"; + $intaRNA2call .= " --qIntLenMax=0"; +} +if (defined $args{o} && $args{o}==1) { + # setup detailed v1 output + $intaRNA2call .=" --outMode=O"; +} else { + # setup normal v1 output + $intaRNA2call .=" --outMode=1"; +} +if (defined $args{n} && $args{n}==1) { + $intaRNA2call .= " --noSeed" +} +$intaRNA2call .= " --mode=E"; +if (defined $args{u}) { + $intaRNA2call .= " --seedMaxUP=".$args{u} +} else { + $intaRNA2call .= " --seedMaxUP=0" +} +#$intaRNA2call .=" --seedMaxE=999"; # enable for IntaRNA v1-like seed handling +$intaRNA2call .=" --energy=V"; + +# call intaRNA 2 +system($intaRNAbinPath."IntaRNA"." ".$intaRNA2call); diff --git a/perl/Makefile.am b/perl/Makefile.am new file mode 100644 index 00000000..7a34511d --- /dev/null +++ b/perl/Makefile.am @@ -0,0 +1,10 @@ + +################################################# +# IntaRNA Perl interface files +################################################# + +dist_bin_SCRIPTS = \ + IntaRNA_1ui.pl \ + IntaRNA_up_1ui.pl + + diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..fec7b77d --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,10 @@ +# autotools' temporary files +.deps +config.h +config.h.in +Makefile +Makefile.in +stamp-* + +# generated header +intarna_config.h diff --git a/src/Accessibility.cpp b/src/Accessibility.cpp new file mode 100644 index 00000000..2813b7e9 --- /dev/null +++ b/src/Accessibility.cpp @@ -0,0 +1,114 @@ + + +#include "Accessibility.h" + +//////////////////////////////////////////////////////////////////// + +const E_type Accessibility::ED_UPPER_BOUND = (E_type) E_INF; + +//////////////////////////////////////////////////////////////////// + +std::ostream& +operator<<(std::ostream& out, const Accessibility& acc) +{ + const std::string delimiter = " "; + // print one line for each i + out <<"\n# ED values for "<=0?" ":"") < + +/** + * Abstract interface that represents accessibility data for a given RNA + * sequence. + * + * TODO : init function to trigger accessibility computation for a certain region + * + * @author Martin Mann 2014 + */ +class Accessibility { + +public: + + //! upper bound for all ED return values + const static E_type ED_UPPER_BOUND; + +public: + + /** + * Construction + * @param sequence the sequence the accessibility data belongs to + * @param maxLength the maximal length of accessible regions (>0) to be + * considered. 0 defaults to the full sequence's length, otherwise + * is is internally set to min(maxLength,seq.length). + * @param accConstr optional accessibility constraint + */ + Accessibility( const RnaSequence& sequence + , const size_t maxLength + , const AccessibilityConstraint * const accConstr + ); + + /** + * destruction + */ + virtual ~Accessibility(); + + /** + * Returns the accessibility energy value for the given range in the + * sequence, i.e. the energy difference (ED) to make the region accessible. + * + * @param from the start index of the regions (from <= to) + * @param to the end index of the regions (to < seq.length) + * + * @return the ED value if (j-1+1) <= maxLength or ED_UPPER_BOUND otherwise + * + * @throw std::runtime_error in case it does not hold 0 <= from <= to < seq.length + */ + virtual + E_type + getED( const size_t from, const size_t to ) const = 0; + + /** + * Access to the RnaSequence this accessibility values are accounting for. + * @return the underlying sequence for this accessibility object. + */ + virtual + const RnaSequence & + getSequence() const; + + /** + * Access to the maximal length of accessible regions (>0) to be considered. + * @return the maximal length of accessible regions considered + */ + virtual + size_t + getMaxLength() const; + + /** + * Access to the globally enforced accessibility constraint. Here '.' + * denotes unconstrained positions and 'x' positions that have to be + * unstructured. Regions covering constrained positions will result in + * ED_UPPER_BOUND accessibility values. + * @return the global accessibility constraint applied + */ + virtual + const AccessibilityConstraint& + getAccConstraint() const; + + /** + * Writes the ED values as unpaired probabilities in RNAplfold style to + * stream. + * + * @param out the output stream to write to + * @param RT the scaled temperature value to be used for conversion of + * ED to Pu : Pu = exp( -ED/RT ) + */ + void + writeRNAplfold_Pu_text( std::ostream& out, const E_type RT ) const; + + /** + * Writes the ED values in RNAplfold style to stream. + * + * @param out the output stream to write to + */ + void + writeRNAplfold_ED_text( std::ostream& out ) const; + + /** + * Prints the accessibility values to stream as upper triangular matrix + * @param out the ostream to write to + * @param acc the Accessibility object to add + * @return the altered stream out + */ + friend std::ostream& operator<<(std::ostream& out, const Accessibility& acc); + + +protected: + + //! the RNA sequence the accessibilities correspond to + const RnaSequence & seq; + + //! the maximal length of an unpaired regions to be considered + const size_t maxLength; + + //! accessibility constraint + AccessibilityConstraint accConstraint; + + /** + * Checks the given indices to be in the range 0 <= from <= to < seq.length + * and throws a std::runtime_error if the constraint is not met. + * @param from the start index of the regions + * @param to the end index of the regions + * + * @throw std::runtime_error in case it does not hold 0 <= from <= to < seq.length + */ + virtual + void + checkIndices( const size_t from, const size_t to ) const; + + /** + * Writes the ED values as unpaired probabilities in RNAplfold style to + * stream. + * + * @param out the output stream to write to + * @param RT the scaled temperature value to be used for conversion of + * ED to Pu : Pu = exp( -ED/RT ) + * @param writeProbs (true) write unpaired probabilities; (false) write ED + */ + void + writeRNAplfold_text( std::ostream& out, const E_type RT, const bool writeProbs ) const; + +}; + + + +///////////////////////////////////////////////////////////////////////////// + +inline +Accessibility::Accessibility( const RnaSequence& seq + , const size_t maxLength + , const AccessibilityConstraint * const accConstraint_ ) + : + seq(seq) + // set maxLength to appropriate value + , maxLength( maxLength==0 ? seq.size() : std::min(maxLength,seq.size()) ) + , accConstraint( seq.size() ) +{ + // set constraint if needed + if (accConstraint_ != NULL) { + accConstraint = *accConstraint_; + } +} + +///////////////////////////////////////////////////////////////////////////// + +inline +Accessibility::~Accessibility() +{ +} + +///////////////////////////////////////////////////////////////////////////// + +inline +void +Accessibility:: +checkIndices( const size_t from, const size_t to ) const +{ +#if IN_DEBUG_MODE + if (from > to || to >= getSequence().size()) { + throw std::runtime_error("Accessibility::checkIndices : region ["+toString(from)+","+toString(to)+"] does not fulfill 0 <= from <= to < seq.length"); + } +#endif +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const RnaSequence & +Accessibility:: +getSequence() const +{ + return seq; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +Accessibility:: +getMaxLength() const +{ + return maxLength; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const AccessibilityConstraint& +Accessibility:: +getAccConstraint() const +{ + return accConstraint; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +void +Accessibility:: +writeRNAplfold_ED_text( std::ostream& out ) const +{ + writeRNAplfold_text( out, 1.0, false ); +} + +///////////////////////////////////////////////////////////////////////////// + +inline +void +Accessibility:: +writeRNAplfold_Pu_text( std::ostream& out, const E_type RT ) const +{ + writeRNAplfold_text( out, RT, true ); +} + +///////////////////////////////////////////////////////////////////////////// + + +#endif /* ACCESSIBILITY_H_ */ diff --git a/src/AccessibilityConstraint.cpp b/src/AccessibilityConstraint.cpp new file mode 100644 index 00000000..987c6e74 --- /dev/null +++ b/src/AccessibilityConstraint.cpp @@ -0,0 +1,54 @@ + +#include "AccessibilityConstraint.h" + +//////////////////////////////////////////////////////////////////////// + +// the marker for blocked positions in dot-bracket notation +const char AccessibilityConstraint::dotBracket_blocked = 'b'; +// the marker for accessible positions in dot-bracket notation +const char AccessibilityConstraint::dotBracket_accessible = 'x'; + +const std::string AccessibilityConstraint::dotBracketAlphabet = ".()" + +toString(AccessibilityConstraint::dotBracket_accessible) + +toString(AccessibilityConstraint::dotBracket_blocked); + + +//////////////////////////////////////////////////////////////////////// + +void +AccessibilityConstraint:: +screenDotBracket( const std::string& dotBracket + , const char marker + , IndexRangeList & storage ) +{ + // temporary variable holding the start of the current region + size_t lastRegionStart = std::string::npos; + // screen for consecutive marker regions + for (size_t i=0; i +#include + +/** + * Represents the constraints for accessibility computation, ie. sequence + * regions that are known to be blocked (not available to interaction) or + * for sure accessible. + * + * These constraints are than incorporated into the computation of the + * accessibility (ED) values to be used for interaction prediction. + * + * @author Martin Mann + * + */ +class AccessibilityConstraint { + +public: + + //! the marker for blocked positions in dot-bracket notation + static const char dotBracket_blocked; + //! the marker for accessible positions in dot-bracket notation + static const char dotBracket_accessible; + + //! the alphabet to encode accessibility constraints in dot-bracket notation + static const std::string dotBracketAlphabet; + + +public: + + /** + * Empty constraint construction + * @param length length of the constrained sequence + * @param maxBpSpan the maximal base pair span to be used for accessibility + * computation; set to 0 for full sequence length + */ + AccessibilityConstraint( const size_t length, const size_t maxBpSpan = 0 ); + + /** + * Copy construction + * @param toCopy the constraint to copy + * @param revereseIndices whether or not to reverse indexing (eg to be used + * for ReverseAccessibility) + */ + AccessibilityConstraint( const AccessibilityConstraint& toCopy + , const bool reverseIndices = false ); + + /** + * Constraint construction based on VRNA-like dot-bracket encoding + * @param dotBracket the constraint encoding in VRNA-like dot-bracket encoding + * @param maxBpSpan the maximal base pair span to be used for accessibility + * computation; set to 0 for full sequence length + */ + AccessibilityConstraint( const std::string& dotBracket, const size_t maxBpSpan = 0 ); + + virtual ~AccessibilityConstraint(); + + /** + * Checks whether or not a sequence position is marked as blocked or not + * @param i the position of interest + * @return true if position i is marked blocked + */ + bool + isMarkedBlocked( const size_t i ) const; + + /** + * Checks whether or not a range is marked as blocked or not + * @param from the start of the range of interest + * @param to the end of the range of interest + * @return true if position i is marked blocked + */ + bool + isMarkedBlocked( const size_t from, const size_t to ) const; + + /** + * Checks whether or not a sequence position is marked as accessible or not + * @param i the position of interest + * @return true if position i is marked accessible + */ + bool + isMarkedAccessible( const size_t i ) const; + + /** + * Checks whether or not a range is marked as accessible or not + * @param from the start of the range of interest + * @param to the end of the range of interest + * @return true if position i is marked accessible + */ + bool + isMarkedAccessible( const size_t from, const size_t to ) const; + + /** + * Checks whether or not a sequence position is not constrained + * @param i the position of interest + * @return true if position i is not constrained + */ + bool + isUnconstrained( const size_t i ) const; + + /** + * Checks whether or not a sequence range is not constrained + * @param from the start of the range of interest + * @param to the end of the range of interest + * @return true if position i is not constrained + */ + bool + isUnconstrained( const size_t from, const size_t to ) const; + + /** + * Checks whether or not a position is available for interaction + * @param i the position of interest + * @return true if the position @p i is available interaction; false otherwise + */ + bool + isAccessible( const size_t i ) const; + + /** + * Checks whether or not a range is available for interaction + * @param from the start of the range of interest + * @param to the end of the range of interest + * @return true if the position @p i is available interaction; false otherwise + */ + bool + isAccessible( const size_t from, const size_t to ) const; + + /** + * Checks whether or not any accessibility constraints (base pairs, blocked, + * accessible, etc.) are given + * @return true if no structural constraints are present; false otherwise + */ + bool + isEmpty() const; + + + /** + * Provides the VRNA dot-bracket notation of the constraint for position i + * @param i the position of interest + * @return the VRNA conform constraint encoding for position i + */ + char + getVrnaDotBracket( const size_t i ) const; + + /** + * Provides the maximal base pair span to be considered for accessibility + * computation. + * @return the maximal base pair span for accessibility computation + */ + size_t + getMaxBpSpan() const; + + /** + * Assignment of constraints for the same rna sequence. + * + * @param c the interaction to make this a copy of + */ + AccessibilityConstraint & operator= ( const AccessibilityConstraint & c ); + + +protected: + + //! the overall sequence length this constraint is about + size_t length; + + //! the maximal base pair span to be used for accessibility computation + size_t maxBpSpan; + + //! sorted list of ranges that are marked as blocked + IndexRangeList blocked; + + //! sorted list of ranges that are marked as accessible + IndexRangeList accessible; + +protected: + + /** + * screens the given dot-bracket string for consecutive regions of + * marker characters and pushes the according regions to the storage + * @param dotBracket the dot-bracket encoding to screen + * @param marker the marker character to screen for + * @param storage the container to push the identified regions to + */ + static + void + screenDotBracket( const std::string& dotBracket + , const char marker + , IndexRangeList & storage ); + +}; + + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +inline +AccessibilityConstraint:: +AccessibilityConstraint( const size_t length_, const size_t maxBpSpan_ ) + : + length(length_), + maxBpSpan( maxBpSpan_==0 ? length : std::min(maxBpSpan_,length) ), + blocked(), + accessible() +{ +} + +//////////////////////////////////////////////////////////////////////// + +inline +AccessibilityConstraint:: +AccessibilityConstraint( const std::string& dotBracket, const size_t maxBpSpan_ ) + : + length(dotBracket.size()), + maxBpSpan( maxBpSpan_==0 ? length : std::min(maxBpSpan_,length) ), + blocked(), + accessible() +{ +#if IN_DEBUG_MODE + if (dotBracket.find_first_not_of(dotBracketAlphabet)!=std::string::npos) { + throw std::runtime_error("AccessibilityConstraint("+dotBracket+") contains unsupported characters"); + } +#endif + + // check for base pairs (not implemented yet) + if (dotBracket.find_first_of("()") != std::string::npos) { + NOTIMPLEMENTED("AccessibilityConstraint(dotBracket) contains base pairs... currently only '."+toString(dotBracket_accessible)+toString(dotBracket_blocked)+"' implemented"); + } + + // screen for blocked regions + screenDotBracket( dotBracket, dotBracket_blocked, blocked ); + // screen for accessible regions + screenDotBracket( dotBracket, dotBracket_accessible, accessible ); +} + +//////////////////////////////////////////////////////////////////////// + +inline +AccessibilityConstraint:: +AccessibilityConstraint( const AccessibilityConstraint& toCopy + , const bool reverseIndices) + : + length(toCopy.length) + , maxBpSpan(toCopy.maxBpSpan) + , blocked(toCopy.blocked) + , accessible(toCopy.accessible) +{ + // TODO copy structure constraints etc. + + if (reverseIndices) { + + // reverse blocked + blocked.reverse(length); + + // reverse accessible + accessible.reverse(length); + + // TODO reverse structure constraints + } +} + +//////////////////////////////////////////////////////////////////////// + +inline +AccessibilityConstraint::~AccessibilityConstraint() +{ +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isMarkedBlocked(const size_t i) const +{ + return blocked.covers(i); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isMarkedBlocked(const size_t from, const size_t to) const +{ + return blocked.covers(from,to); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isMarkedAccessible(const size_t i) const +{ + return accessible.covers(i); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isMarkedAccessible(const size_t from, const size_t to) const +{ + return accessible.covers(from,to); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isUnconstrained( const size_t i ) const +{ + return isEmpty() + // TODO handle base pairing constraints etc.. + || !(isMarkedAccessible(i) || isMarkedBlocked(i)); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isUnconstrained( const size_t from, const size_t to ) const +{ + return isEmpty() + // TODO handle base pairing constraints etc.. + || !(isMarkedAccessible(from,to) || isMarkedBlocked(from,to)); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isAccessible( const size_t i ) const +{ + // TODO handle base pairing constraints etc. + return isEmpty() + || !isMarkedBlocked(i); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isAccessible( const size_t from, const size_t to ) const +{ + // TODO handle base pairing constraints etc. + return isEmpty() + || !isMarkedBlocked( from, to ); +} + +//////////////////////////////////////////////////////////////////////// + +inline +bool +AccessibilityConstraint:: +isEmpty() const +{ + // TODO CHECK FOR BASE PAIRS ETC + // check if any constrained regions given + return (accessible.size() + blocked.size()) == 0; +} + +//////////////////////////////////////////////////////////////////////// + +inline +char +AccessibilityConstraint:: +getVrnaDotBracket(const size_t i) const +{ + // check if to be accessible or blocked (==unstructured) + if (isMarkedAccessible(i) || isMarkedBlocked(i)) { + return 'x'; + } + + // TODO add base pair handling etc. + + return '.'; +} + +//////////////////////////////////////////////////////////////////////// + +inline +size_t +AccessibilityConstraint:: +getMaxBpSpan() const +{ + return maxBpSpan; +} + +//////////////////////////////////////////////////////////////////////// + +inline +AccessibilityConstraint & +AccessibilityConstraint:: +operator= ( const AccessibilityConstraint & c ) +{ + // copy data + length = c.length; + maxBpSpan = c.maxBpSpan; + blocked = c.blocked; + accessible = c.accessible; + // TODO copy structure constraints etc. + + return *this; +} + +//////////////////////////////////////////////////////////////////////// + + + +#endif /* ACCESSIBILITYCONSTRAINT_H_ */ diff --git a/src/AccessibilityDisabled.h b/src/AccessibilityDisabled.h new file mode 100644 index 00000000..566a9032 --- /dev/null +++ b/src/AccessibilityDisabled.h @@ -0,0 +1,101 @@ +/* + * AccessibilityDisabled.h + * + * Created on: 25.06.2014 + * Author: Mmann + */ + +#ifndef ACCESSIBILITYDISABLED_H_ +#define ACCESSIBILITYDISABLED_H_ + +#include "Accessibility.h" + +/** + * Implements the Accessibility interface but disables ED value computation, + * i.e. all ED values are set to zero. + * + * @author Martin Mann 2014 + */ +class AccessibilityDisabled: public Accessibility { + +public: + + /** + * Construction + * @param sequence the sequence the accessibility data belongs to + * @param maxLength the maximal length of accessible regions to be + * considered. 0 defaults to the sequence's length. + * @param accConstr optional accessibility constraint + */ + AccessibilityDisabled( const RnaSequence& sequence + , const size_t maxLength + , const AccessibilityConstraint * const accConstr + ); + + /** + * destruction + */ + virtual ~AccessibilityDisabled(); + + /** + * Always returns a zero accessibility energy value. + * + * @param from the start index of the regions (from <= to) + * @param to the end index of the regions (to <= seq.length()) + * + * @return 0 if (j-1+1) <= maxLength or ED_UPPER_BOUND otherwise + */ + virtual + E_type + getED( const size_t from, const size_t to ) const; + +}; + + + +/////////////////////////////////////////////////////////////////////////////// + +inline +AccessibilityDisabled::AccessibilityDisabled(const RnaSequence& seq + , const size_t maxLength + , const AccessibilityConstraint * const accConstr) + : + Accessibility(seq, maxLength, accConstr) +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +inline +AccessibilityDisabled::~AccessibilityDisabled() +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +inline +E_type +AccessibilityDisabled:: +getED( const size_t from, const size_t to ) const +{ + // input check + checkIndices(from,to); + + if ((to-from+1) <= getMaxLength()) { + // check for constrained positions within region + if (!getAccConstraint().isAccessible(from,to)) { + // position covers a blocked position --> omit accessibility + return ED_UPPER_BOUND; + } + // else: no accessibility computation done --> always zero + return (E_type)0; + } else { + // region length exceeds maximally allowed length -> no value + return ED_UPPER_BOUND; + } +} + +/////////////////////////////////////////////////////////////////////////////// + + +#endif /* ACCESSIBILITYDISABLED_H_ */ diff --git a/src/AccessibilityFromStream.cpp b/src/AccessibilityFromStream.cpp new file mode 100644 index 00000000..e7c2ba15 --- /dev/null +++ b/src/AccessibilityFromStream.cpp @@ -0,0 +1,173 @@ + +#include "AccessibilityFromStream.h" + +#include +#include + +///////////////////////////////////////////////////////////////////////// + +AccessibilityFromStream:: +AccessibilityFromStream( + const RnaSequence& sequence + , const size_t maxLength + , const AccessibilityConstraint * const accConstraint + , std::istream & inStream + , const InStreamType inStreamType + , const E_type RT + ) + : Accessibility( sequence, maxLength, accConstraint ) + , edValues() + , availMaxLength( Accessibility::getMaxLength() ) +{ + switch( inStreamType ) { + + case Pu_RNAplfold_Text : + parsePu_RNAplfold_text( inStream, RT ); + break; + + case ED_RNAplfold_Text : + parseED_RNAplfold_text( inStream ); + break; + + } +} + +///////////////////////////////////////////////////////////////////////// + +AccessibilityFromStream:: +~AccessibilityFromStream() +{ +} + +///////////////////////////////////////////////////////////////////////// + + +void +AccessibilityFromStream:: +parseRNAplfold_text( std::istream & inStream, const E_type RT, const bool parseProbs ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"parsing "<<(parseProbs?"unpaired probabilities":"accessibility values")<<" from RNAplfold"<<(parseProbs?"":"-like")<<" input ..."; } + // time logging + TIMED_FUNC_IF(timerObj, VLOG_IS_ON(9)); + + // assume VRNA v2* style = matrix with maxLength rows + + // skip leading white spaces + inStream >>std::skipws; + + // parse first comment line + std::string line; + if ( !std::getline( inStream, line ) ) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : nothing readable"); + } + if ( ! boost::regex_match(line,boost::regex("^#[\\w\\s]+$"), boost::match_perl) ) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : first line != expected header line starting with '#'"); + } + + // parse second line = available lengths + if ( !std::getline( inStream, line ) ) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : length header (2nd line) not found"); + } + if ( ! boost::regex_match(line,boost::regex("^\\s*#i.\\s+l=1(\\s+\\d+)*\\s*$"), boost::match_perl) ) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : second line is no proper lengths header"); + } + // check if maxLength <= max available length + size_t cutEnd = line.find_last_of("1234567890"); + size_t cutStart = line.find_last_not_of("1234567890", cutEnd ); + size_t maxAvailLength = boost::lexical_cast( line.substr(cutStart+1,cutEnd-cutStart)); + if (maxAvailLength < getMaxLength()) { +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { LOG(INFO) <<"initializing ED data for sequence '"<> j ) { + // check if lines are consecutive + if ( j != lastJ+1 ) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : non-consecutive line i="+toString(j)+" was preceeded by "+toString(lastJ)); + } + // check if we line exceeds targeted length + if ( j > getSequence().size() ) { +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { LOG(INFO) <<"AccessibilityFromStream::parseRNAplfold_text() : more lines found than sequence is long.. sure this is the correct file for this sequence?"; } + // stop parsing + break; + } + if ( j == lastJ ) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : duplicate for i=" + + toString(lastJ)); + } + } else { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : could not read next line start (integer i) after parsing " + + toString(lastJ)+" lines of values"); + } + + // parse probabilities for this line and store + double curVal; + size_t minI = j - std::min( j, getMaxLength() ); + for ( size_t i = j; i>minI; i--) { + if ( inStream >>curVal ) { + // check if we parse probabilities + if (parseProbs) { + if (curVal < 0.0 || curVal > 1.0) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_Text(Pu) : in line i="+toString(j) + +" : the "+toString(j+1-i)+". value = "+toString(curVal)+" is no probability in [0,1]"); + } + edValues( i-1, j-1 ) = curVal > 0 + ? std::min(ED_UPPER_BOUND, - RT * std::log( curVal )) + : ED_UPPER_BOUND; + } + // or ED values + else { + if (curVal < 0.0) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_Text(ED) : in line i="+toString(j) + +" : the "+toString(j+1-i)+". value = "+toString(curVal)+" is no ED value >= 0"); + } + edValues( i-1, j-1 ) = std::min(ED_UPPER_BOUND, curVal); + } + } else { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : in line i="+toString(j) + +" : could not parse the "+toString(j+1-i)+". probability"); + } + } + // check if full line was already parsed + if (j < maxAvailLength || minI > 0) { + // skip rest till end of line + inStream.ignore(std::numeric_limits::max(), '\n'); + } + + // update parsing information for next run + lastJ = j; + } + + // check if all needed data was parsed + if (lastJ < edValues.size2()) { + throw std::runtime_error("AccessibilityFromStream::parseRNAplfold_text() : could only parse " + +toString(lastJ)+" lines, but "+toString(edValues.size2()) + +" expected (length of sequence "+getSequence().getId()+")"); + } + +} + +///////////////////////////////////////////////////////////////////////// diff --git a/src/AccessibilityFromStream.h b/src/AccessibilityFromStream.h new file mode 100644 index 00000000..d2755baa --- /dev/null +++ b/src/AccessibilityFromStream.h @@ -0,0 +1,188 @@ + +#ifndef ACCESSIBILITYFROMSTREAM_H_ +#define ACCESSIBILITYFROMSTREAM_H_ + +#include "Accessibility.h" + +#include + +#include + +/** + * Reads accessibility information from a data stream, e.g. from file or STDIN + * + */ +class AccessibilityFromStream: public Accessibility +{ +public: + + enum InStreamType { + Pu_RNAplfold_Text //! Pu values in RNAplfold text format + , ED_RNAplfold_Text //!< ED values in RNAplfold text Pu format + }; + +public: + + /** + * construction + * @param sequence the sequence the accessibility data is about + * @param maxLength the maximal length of accessible regions (>0) to be + * considered. 0 defaults to the full sequence's length, otherwise + * is is internally set to min(maxLength,seq.length). + * @param accConstraint if not NULL, accessibility constraint that enforces some regions + * to be unstructured both in sequence and interaction + * @param inStream the input stream to read the accessibility data from + * @param inStreamType inStream data type to be expected + * @param RT the RT constant to be used to transform the probabilities to + * ED values + */ + AccessibilityFromStream( + const RnaSequence& sequence + , const size_t maxLength + , const AccessibilityConstraint * const accConstraint + , std::istream & inStream + , const InStreamType inStreamType + , const E_type RT + ); + + + /** + * destruction + */ + virtual ~AccessibilityFromStream(); + + + /** + * Returns the accessibility energy value for the given range in the + * sequence, i.e. the energy difference (ED) to make the region accessible. + * + * @param from the start index of the regions (from <= to) + * @param to the end index of the regions (to < seq.length) + * + * @return the ED value if (j-1+1) <= maxLength or ED_UPPER_BOUND otherwise + * + * @throw std::runtime_error in case it does not hold 0 <= from <= to < seq.length + */ + virtual + E_type + getED( const size_t from, const size_t to ) const; + + /** + * Access to the maximal length of accessible regions (>0) to be considered. + * + * Here, it returns the minimum of the originally targeted interaction range + * and the from the data parsed maximal window size. + * + * @return the maximal length of accessible regions considered + */ + virtual + size_t + getMaxLength() const; + + +protected: + + //! type for the ED value matrix (upper triangular matrix banded by maxLength) + typedef boost::numeric::ublas::banded_matrix EdMatrix; + + //! the ED values for the given sequence + EdMatrix edValues; + + //! maximal available window size + size_t availMaxLength; + + /** + * Parses a VRNA unpaired probability file and fills the ED data + * + * @param inStream the stream to read the probabilities from + * @param RT the RT constant to be used to transform the probabilities to + * ED values + */ + void + parsePu_RNAplfold_text( std::istream & inStream, const E_type RT ); + + + /** + * Parses ED values from a VRNA unpaired probability file styled stream + * + * @param inStream the stream to read the ED values from + */ + void + parseED_RNAplfold_text( std::istream & inStream ); + + /** + * Parses ED values from a VRNA unpaired probability file styled stream + * + * @param inStream the stream to read the ED values from + * @param RT the RT constant to be used to transform the probabilities to + * ED values + * @param parseProbs whether or not to expect unpaired probabilities (true) + * or ED values within the file + */ + void + parseRNAplfold_text( std::istream & inStream + , const E_type RT + , const bool parseProbs ); + + +}; + +///////////////////////////////////////////////////////////////////////// + +inline +E_type +AccessibilityFromStream:: +getED( const size_t from, const size_t to ) const +{ + // input range check + checkIndices(from,to); + + if ((to-from+1) <= getMaxLength()) { + // check for constrained positions within region + if (!getAccConstraint().isAccessible(from, to)) { + // position covers a blocked position --> omit accessibility + return ED_UPPER_BOUND; + } + // return according ED value from the precomputed matrix + return edValues (from,to); + } else { + // region length exceeds maximally allowed length -> no value + return ED_UPPER_BOUND; + } +} + +///////////////////////////////////////////////////////////////////////// + +inline +size_t +AccessibilityFromStream:: +getMaxLength() const +{ + return availMaxLength; +} + +///////////////////////////////////////////////////////////////////////// + +inline +void +AccessibilityFromStream:: +parsePu_RNAplfold_text( std::istream & inStream, const E_type RT ) +{ + parseRNAplfold_text( inStream, RT, true ); +} + +///////////////////////////////////////////////////////////////////////// + +inline +void +AccessibilityFromStream:: +parseED_RNAplfold_text( std::istream & inStream ) +{ + parseRNAplfold_text( inStream, 1.0, false ); +} + +///////////////////////////////////////////////////////////////////////// + + + +#endif /* ACCESSIBILITYFROMSTREAM_H_ */ diff --git a/src/AccessibilityVrna.cpp b/src/AccessibilityVrna.cpp new file mode 100644 index 00000000..69742107 --- /dev/null +++ b/src/AccessibilityVrna.cpp @@ -0,0 +1,451 @@ + +#include "AccessibilityVrna.h" + +#include +#include +#include +#include +#include + +// constraint-based ED filling +extern "C" { + #include + #include + #include +} + +// RNAup-like ED filling +extern "C" { + #include + #include + #include + #include + #include +} + +// RNAplfold-like ED filling +extern "C" { + #include + #include + #include + #include + #include + #include +} + + +///////////////////////////////////////////////////////////////////////////// + +AccessibilityVrna::AccessibilityVrna( + const RnaSequence& seq + , const size_t maxLength + , const AccessibilityConstraint * const accConstraint + , const VrnaHandler & vrnaHandler + , const size_t plFoldW + ) + : + Accessibility( seq, maxLength, accConstraint ), + edValues( getSequence().size(), getSequence().size(), 0, getMaxLength() ) +{ + + // check if constraint given + // or sliding window empty + // or larger than sequence length + if ( (! getAccConstraint().isEmpty()) || (plFoldW==0) || (plFoldW >= getSequence().size()) ) { + if (plFoldW > 0 && plFoldW < getSequence().size() ) { + throw std::runtime_error("sequence '"+seq.getId()+"': accuracy constraints provided but sliding window enabled (>0), which is currently not supported"); + } +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_callingVRNA) +#endif + { + // NOTE, THIS FUNCTION IS NOT THREADSAFE ... + fillByRNAup(vrnaHandler + , getAccConstraint().getMaxBpSpan() + ); + // inefficient ED value computation O(n^2)*O(n^5) for debugging +// fillByConstraints(vrnaHandler, (plFoldW==0? getSequence().size() : std::min(plFoldW,getSequence().size())), plFoldL); + } // omp critical(intarna_omp_callingVRNA) + } else { + // VRNA computation not completely threadsafe +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_callingVRNA) +#endif + { + fillByRNAplfold(vrnaHandler + , (plFoldW==0? getSequence().size() : std::min(plFoldW,getSequence().size())) + , getAccConstraint().getMaxBpSpan() + ); + } // omp critical(intarna_omp_callingVRNA) + } + + +} + +///////////////////////////////////////////////////////////////////////////// + +AccessibilityVrna::~AccessibilityVrna() +{ +} + +/////////////////////////////////////////////////////////////////////////////// + + +E_type +AccessibilityVrna:: +calc_ensemble_free_energy( const int start_unfold, const int end_unfold, vrna_exp_param_s * partFoldParams ) +{ +#if IN_DEBUG_MODE + if (start_unfold >= 0 && end_unfold >= 0) { + checkIndices((size_t)start_unfold, (size_t)end_unfold); + } else { + if (start_unfold != -1 || end_unfold != -1) { + throw std::runtime_error("AccessibilityVienna::calc_ensemble_free_energy : range ["+toString(start_unfold)+","+toString(end_unfold)+"] not allowed"); + } + } +#endif + + + // get sequence length + int len = (int)getSequence().size(); + + // generate structure constraint + // ('.' = 'unconstrained' and 'x' = 'unstructured/unpaired') + char c_structure[len+1]; + c_structure[len] = '\0'; + if (start_unfold < 0) { + for (int i=0; i(0.,(calc_ensemble_free_energy(i,j, partFoldParams) - E_all)); + } else { + // region covers constrained elements --> set to upper bound + edValues(i,j) = ED_UPPER_BOUND; + } + + } + } + +} + +/////////////////////////////////////////////////////////////////////////////// + + +void +AccessibilityVrna:: +fillByRNAplfold( const VrnaHandler &vrnaHandler + , const size_t plFoldW + , const size_t plFoldL ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"computing accessibility via plfold routines...";} + // time logging + TIMED_FUNC_IF(timerObj, VLOG_IS_ON(9)); + +#if IN_DEBUG_MODE + // check if structure constraint given + if ( ! getAccConstraint().isEmpty() ) { + throw std::runtime_error("AccessibilityVrna::fillByRNAplfold() called but structure constraint present for sequence "+getSequence().getId()); + } + if (plFoldW < 3) { + throw std::runtime_error("AccessibilityVrna::fillByRNAplfold() : plFoldW < 3"); + } +#endif + + // add maximal BP span + vrna_md_t curModel = vrnaHandler.getModel( plFoldL, plFoldW ); + + const int length = getSequence().size(); + + // copy sequence into C data structure + char * sequence = (char *) vrna_alloc(sizeof(char) * (length + 1)); + for (int i=0; i( 0., -RT*std::log(prob_unpaired)); + } + } + } + + // garbage collection + free(pf_parameters); + if (pl) free(pl); + if (dpp) free(dpp); + for (int i=0; i<=length; i++) { + // delete allocated rows + if (pup[i]) free(pup[i]); + } + free(pup); + free(sequence); + +} + +/////////////////////////////////////////////////////////////////////////////// + + +void +AccessibilityVrna:: +fillByRNAup( const VrnaHandler &vrnaHandler + , const size_t plFoldL ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"computing accessibility via RNAup routines..."; } + // time logging + TIMED_FUNC_IF(timerObj, VLOG_IS_ON(9)); + + const int seqLength = (int)getSequence().size(); + + // get model + vrna_md_t curModel = vrnaHandler.getModel( plFoldL, seqLength ); + + // make model parameters accessible in VRNA2-API + vrna_md_defaults_reset( &curModel ); + fold_constrained=1; + tetra_loop=1; + noLonelyPairs = curModel.noLP; + noGU = curModel.noGU; + no_closingGU = curModel.noGUclosure; + energy_set = curModel.energy_set; + + // TODO CHECK IF TO BE CALLED OR NOT +// update_fold_params(); +// vrna_params_subst(); + + //////// RNAup-like (VRNA2-API) unpaired probability calculation /////// + + char * sequence = (char *) vrna_alloc(sizeof(char) * (seqLength + 1)); + char * structure = (char *) vrna_alloc(sizeof(char) * (seqLength + 1)); + for (int i=0; i0; i--) { + bool regionUnconstrained = getAccConstraint().isUnconstrained(i-1); + // compute only for region lengths (j-i+1) <= maxLength + for(int j=i; j<=std::min((int)seqLength,unstr_out->w);j++) + { + // extend knowledge about "unconstrainedness" for the region + regionUnconstrained = regionUnconstrained && (getAccConstraint().isUnconstrained(j-1)); + // check if unconstrained within region (i,j) + if (regionUnconstrained) { + // compute overall unpaired probability + double prob_unpaired = + unstr_out->H[i][j-i]+ + unstr_out->I[i][j-i]+ + unstr_out->M[i][j-i]+ + unstr_out->E[i][j-i]; + // check if zero before computing its log-value + if ( prob_unpaired == 0.0 ) { + // ED value = ED_UPPER_BOUND + edValues(i-1,j-1) = ED_UPPER_BOUND; + } else { + // compute ED value = E(unstructured in [i,j]) - E_all + edValues(i-1,j-1) = std::max( 0., -RT*std::log(prob_unpaired)); + } + + } else { + // region covers constrained elements --> set to upper bound + edValues(i-1,j-1) = ED_UPPER_BOUND; + } + } + } + + // free data + free_pu_contrib( unstr_out ); + +} + +///////////////////////////////////////////////////////////////////////////// + diff --git a/src/AccessibilityVrna.h b/src/AccessibilityVrna.h new file mode 100644 index 00000000..fad79dfc --- /dev/null +++ b/src/AccessibilityVrna.h @@ -0,0 +1,177 @@ + +#ifndef ACCESSIBILITYVIENNA_H_ +#define ACCESSIBILITYVIENNA_H_ + +#include "Accessibility.h" +#include "VrnaHandler.h" + +#include + +#include + + +extern "C" { + #include "ViennaRNA/fold_vars.h" + #include "ViennaRNA/params.h" +} + + + +/** + * Computes accessibility energy values for _all_ _regions_ using the free + * energies of structure ensembles based on partition function computations + * via the Vienna RNA package. + * + * @author Martin Mann 2014 + */ +class AccessibilityVrna : public Accessibility { + +public: + + + /** + * Construction + * @param sequence the sequence the accessibility data belongs to + * @param maxLength the maximal window size of accessible regions to be + * considered. 0 defaults to the sequence's length. + * @param accConstraint if not NULL, accessibility constraint that enforces some regions + * to be unstructured both in sequence and interaction + * @param vrnaHandler the VRNA parameter handler to be used + * @param plFoldW the sliding window size to be used for plFold computations + */ + AccessibilityVrna( const RnaSequence& sequence + , const size_t maxLength + , const AccessibilityConstraint * const accConstraint + , const VrnaHandler & vrnaHandler + , const size_t plFoldW = 0 + ); + + /** + * destruction + */ + virtual ~AccessibilityVrna(); + + /** + * Returns the accessibility energy value for the given range in the + * sequence, i.e. the energy difference (ED) to make the region accessible. + * + * @param from the start index of the regions (from <= to) + * @param to the end index of the regions (to < seq.length) + * + * @return the ED value if (j-1+1) <= maxLength or ED_UPPER_BOUND otherwise + * + * @throw std::runtime_error in case it does not hold 0 <= from <= to < seq.length + */ + virtual + E_type + getED( const size_t from, const size_t to ) const; + +protected: + + //! type for the ED value matrix (upper triangular matrix banded by maxLength) + typedef boost::numeric::ublas::banded_matrix EdMatrix; + + //! the ED values for the given sequence + EdMatrix edValues; + + /** + * Computes the free energy of the structure ensemble that is unstructured + * in the region [start_unfold,end_unfold] including the boundaries. + * If start and end are set to -1 the full structure ensemble without + * constraints is considered. + * + * @param start_unfold first position to be unstructured, or -1 if no + * structure constraint is to be set + * @param end_unfold last position to be unstructured, or -1 if no + * structure constraint is to be set + * @param partFoldParams the folding parameters to be used + * + * @return the energy of the structure ensemble + */ + E_type + calc_ensemble_free_energy( + const int start_unfold + , const int end_unfold + , vrna_exp_param_s * partFoldParams + ); + + /** + * Computes a scaling factor to avoid overflow in partition function + * computation. + * + * @param seq the sequence the parameter is for + * @param vrnaHandler the VRNA handler to be used + * @param plFoldL the maximal base pair span to be used or 0 for plFoldW + */ + double + getPfScale( const RnaSequence & seq + , const VrnaHandler & vrnaHandler + , const size_t plFoldL ); + + + /** + * Use the old intaRNA way using n^2 constrained folding to fill ED-values + * + * @param vrnaHandler the VRNA handler to be used + * @param plFoldL the maximal base pair span to be used or 0 for plFoldW + */ + void + fillByConstraints( const VrnaHandler &vrnaHandler + , const size_t plFoldL ); + + /** + * Use RNAup-like style to fill ED-values + * + * @param vrnaHandler the VRNA handler to be used + * @param plFoldL the maximal base pair span to be used or 0 for plFoldW + */ + void + fillByRNAup( const VrnaHandler &vrnaHandler + , const size_t plFoldL ); + + /** + * Use RNAplfold-like style to fill ED-values + * + * @param vrnaHandler the VRNA handler to be used + * @param plFoldW the sliding window size to be used or 0 for full length + * @param plFoldL the maximal base pair span to be used or 0 for plFoldW + */ + void + fillByRNAplfold( const VrnaHandler &vrnaHandler + , const size_t plFoldW + , const size_t plFoldL ); + + +}; + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +inline +E_type +AccessibilityVrna:: +getED( const size_t from, const size_t to ) const +{ + // input range check + checkIndices(from,to); + + if ((to-from+1) <= getMaxLength()) { + // check for constrained positions within region + if (!getAccConstraint().isAccessible(from,to)) { + // position covers a blocked position --> omit accessibility + return ED_UPPER_BOUND; + } + // return according ED value from the precomputed matrix + return edValues (from,to); + } else { + // region length exceeds maximally allowed length -> no value + return ED_UPPER_BOUND; + } +} + +///////////////////////////////////////////////////////////////////////////// + + +#endif /* ACCESSIBILITYVIENNA_H_ */ diff --git a/src/CommandLineParsing.cpp b/src/CommandLineParsing.cpp new file mode 100644 index 00000000..123a1757 --- /dev/null +++ b/src/CommandLineParsing.cpp @@ -0,0 +1,1614 @@ + +#include "CommandLineParsing.h" + +#include "general.h" + +#include +#include +#include + +#if INTARNA_MULITHREADING + #include +#endif + +#include +#include +#include +#include +#include + +#include "AccessibilityConstraint.h" + +#include "AccessibilityDisabled.h" +#include "AccessibilityFromStream.h" +#include "AccessibilityVrna.h" + +#include "InteractionEnergyBasePair.h" +#include "InteractionEnergyVrna.h" + +#include "PredictorMfe2dHeuristic.h" +#include "PredictorMfe2d.h" +#include "PredictorMfe4d.h" +#include "PredictorMaxProb.h" + +#include "PredictorMfe2dHeuristicSeed.h" +#include "PredictorMfe2dSeed.h" +#include "PredictorMfe4dSeed.h" + +#include "OutputHandlerText.h" +#include "OutputHandlerCsv.h" +#include "OutputHandlerIntaRNA1.h" + + + + + +//////////////////////////////////////////////////////////////////////////// + +const std::string CommandLineParsing::outCsvCols_default = "id1,start1,end1,id2,start2,end2,subseqDP,hybridDP,E"; + +//////////////////////////////////////////////////////////////////////////// + +CommandLineParsing::CommandLineParsing() + : + stdinUsed(false), + opts_query("Query"), + opts_target("Target"), + opts_seed("Seed"), + opts_inter("Interaction"), + opts_general("General"), + opts_output("Output"), + opts_cmdline_all(), + opts_cmdline_short(), + + parsingCode(NOT_PARSED_YET), + + queryArg(""), + query(), + qAcc("NCPE",'C'), + qAccW( 0, 99999, 150), + qAccL( 0, 99999, 100), + qAccConstr(""), + qAccFile(""), + qIntLenMax( 0, 99999, 0), + qIntLoopMax( 0, 30, 16), + qRegionString(""), + qRegion(), + + targetArg(""), + target(), + tAcc("NCPE",'C'), + tAccW( 0, 99999, 150), + tAccL( 0, 99999, 100), + tAccConstr(""), + tAccFile(""), + tIntLenMax( 0, 99999, 0), + tIntLoopMax( 0, 30, 16), + tRegionString(""), + tRegion(), + + noSeedRequired(false), + seedBP(2,20,7), + seedMaxUP(0,20,0), + seedQMaxUP(-1,20,-1), + seedTMaxUP(-1,20,-1), + seedMaxE(-999,+999,0), + seedMinPu(0,1,0), + seedQRange(""), + seedTRange(""), + seedConstraint(NULL), + + temperature(0,100,37), + + pred( "SP", 'S'), + predMode( "HME", 'H'), +#if INTARNA_MULITHREADING + threads( 1, omp_get_max_threads(), 1), +#endif + + energy("BV",'V'), + energyFile(""), + + out("STDOUT"), + outStream(&(std::cout)), + outMode( "NDC1O", 'N' ), + outNumber( 0, 1000, 1), + outOverlap( "NTQB", 'Q' ), + outDeltaE( 0.0, 100.0, 100.0), + outMaxE( -999.0, +999.0, 0.0), + outCsvCols(outCsvCols_default), + outQAccFile(""), + outTAccFile(""), + outQPuFile(""), + outTPuFile(""), + + vrnaHandler() + +{ + using namespace boost::program_options; + + + //// QUERY SEQUENCE OPTIONS //////////////////////////////////// + + opts_query.add_options() + ("query,q" + , value(&queryArg) + ->required() + ->notifier(boost::bind(&CommandLineParsing::validate_query,this,_1)) + , "either an RNA sequence or the stream/file name from where to read the query sequences (should be the shorter sequences to increase efficiency); use 'STDIN' to read from standard input stream; sequences have to use IUPAC nucleotide encoding") + ("qAcc" + , value(&(qAcc.val)) + ->default_value(qAcc.def) + ->notifier(boost::bind(&CommandLineParsing::validate_qAcc,this,_1)) + , std::string("accessibility computation : 'N'o accessibility contributions" + ", 'C' computation of accessibilities" + ", 'P' unpaired probabilities in RNAplfold format from --qAccFile" + ", 'E' ED values in RNAplfold Pu-like format from --qAccFile" + ).c_str()) + ("qAccW" + , value(&(qAccW.val)) + ->default_value(qAccW.def) + ->notifier(boost::bind(&CommandLineParsing::validate_qAccW,this,_1)) + , std::string("accessibility computation : sliding window size for query accessibility computation (arg in range ["+toString(qAccW.min)+","+toString(qAccW.max)+"]; 0 defaults to the full sequence length)").c_str()) + ("qAccL" + , value(&(qAccL.val)) + ->default_value(qAccL.def) + ->notifier(boost::bind(&CommandLineParsing::validate_qAccL,this,_1)) + , std::string("accessibility computation : sliding window size for query accessibility computation (arg in range ["+toString(qAccL.min)+","+toString(qAccL.max)+"]; 0 defaults to sliding window size 'qAccW')").c_str()) + ; + opts_cmdline_short.add(opts_query); + opts_query.add_options() + ("qAccConstr" + , value(&(qAccConstr)) + ->notifier(boost::bind(&CommandLineParsing::validate_qAccConstr,this,_1)) + , std::string("accessibility computation : structure constraint for each sequence position: '.' no constraint, '"+toString(AccessibilityConstraint::dotBracket_accessible)+"' unpaired, '"+toString(AccessibilityConstraint::dotBracket_blocked)+"' blocked. Note, blocked positions are excluded from interaction prediction and considered unpaired!").c_str()) + ("qAccFile" + , value(&(qAccFile)) + ->notifier(boost::bind(&CommandLineParsing::validate_qAccFile,this,_1)) + , std::string("accessibility computation : if --qAcc is to be read from file, the file/stream to be parsed. Used 'STDIN' if to read from standard input stream.").c_str()) + ("qIntLenMax" + , value(&(qIntLenMax.val)) + ->default_value(qIntLenMax.def) + ->notifier(boost::bind(&CommandLineParsing::validate_qIntLenMax,this,_1)) + , std::string("interaction site : maximal window size to be considered" + " for interaction (and thus accessible) within the query" + " (arg in range ["+toString(qIntLenMax.min)+","+toString(qIntLenMax.max)+"];" + " 0 defaults to the full sequence length)" + " If --qAccW is provided, the smaller window size of both is used." + ).c_str()) + ("qIntLoopMax" + , value(&(qIntLoopMax.val)) + ->default_value(qIntLoopMax.def) + ->notifier(boost::bind(&CommandLineParsing::validate_qIntLoopMax,this,_1)) + , std::string("interaction site : maximal number of unpaired bases between neighbored interacting bases to be considered in interactions within the query (arg in range ["+toString(qIntLoopMax.min)+","+toString(qIntLoopMax.max)+"]; 0 enforces stackings only)").c_str()) + ("qRegion" + , value(&(qRegionString)) + ->notifier(boost::bind(&CommandLineParsing::validate_qRegion,this,_1)) + , std::string("interaction site : query regions to be considered for interaction prediction. Either given as BED file (for multi-sequence FASTA input) or in the format 'from1-to1,from2-to2,..' assuming indexing starts with 1").c_str()) + ; + + //// TARGET SEQUENCE OPTIONS //////////////////////////////////// + + opts_target.add_options() + ("target,t" + , value(&targetArg) + ->required() + ->notifier(boost::bind(&CommandLineParsing::validate_target,this,_1)) + , "either an RNA sequence or the stream/file name from where to read the target sequences (should be the longer sequences to increase efficiency); use 'STDIN' to read from standard input stream; sequences have to use IUPAC nucleotide encoding") + ("tAcc" + , value(&(tAcc.val)) + ->default_value(tAcc.def) + ->notifier(boost::bind(&CommandLineParsing::validate_tAcc,this,_1)) + , std::string("accessibility computation : 'N'o accessibility contributions" + ", 'C' computation of accessibilities" + ", 'P' unpaired probabilities in RNAplfold format from --tAccFile" + ", 'E' ED values in RNAplfold Pu-like format from --tAccFile" + ).c_str()) + ("tAccW" + , value(&(tAccW.val)) + ->default_value(tAccW.def) + ->notifier(boost::bind(&CommandLineParsing::validate_tAccW,this,_1)) + , std::string("accessibility computation : sliding window size for query accessibility computation (arg in range ["+toString(tAccW.min)+","+toString(tAccW.max)+"]; 0 defaults to the full sequence length)").c_str()) + ("tAccL" + , value(&(tAccL.val)) + ->default_value(tAccL.def) + ->notifier(boost::bind(&CommandLineParsing::validate_tAccL,this,_1)) + , std::string("accessibility computation : sliding window size for query accessibility computation (arg in range ["+toString(tAccL.min)+","+toString(tAccL.max)+"]; 0 defaults to sliding window size 'tAccW')").c_str()) + ; + opts_cmdline_short.add(opts_target); + opts_target.add_options() + ("tAccConstr" + , value(&(tAccConstr)) + ->notifier(boost::bind(&CommandLineParsing::validate_tAccConstr,this,_1)) + , std::string("accessibility computation : structure constraint for each sequence position: '.' no constraint, '"+toString(AccessibilityConstraint::dotBracket_accessible)+"' unpaired, '"+toString(AccessibilityConstraint::dotBracket_blocked)+"' blocked. Note, blocked positions are excluded from interaction prediction and considered unpaired!").c_str()) + ("tAccFile" + , value(&(tAccFile)) + ->notifier(boost::bind(&CommandLineParsing::validate_tAccFile,this,_1)) + , std::string("accessibility computation : if --tAcc is to be read from file, the file/stream to be parsed. Used 'STDIN' if to read from standard input stream.").c_str()) + ("tIntLenMax" + , value(&(tIntLenMax.val)) + ->default_value(tIntLenMax.def) + ->notifier(boost::bind(&CommandLineParsing::validate_tIntLenMax,this,_1)) + , std::string("interaction site : maximal window size to be considered for" + " interaction (and thus accessible) within the target" + " (arg in range ["+toString(tIntLenMax.min)+","+toString(tIntLenMax.max)+"];" + " 0 defaults to the full sequence length)." + " If --tAccW is provided, the smaller window size of both is used." + ).c_str()) + ("tIntLoopMax" + , value(&(tIntLoopMax.val)) + ->default_value(tIntLoopMax.def) + ->notifier(boost::bind(&CommandLineParsing::validate_tIntLoopMax,this,_1)) + , std::string("interaction site : maximal number of unpaired bases between neighbored interacting bases to be considered in interactions within the target (arg in range ["+toString(tIntLoopMax.min)+","+toString(tIntLoopMax.max)+"]; 0 enforces stackings only)").c_str()) + ("tRegion" + , value(&(tRegionString)) + ->notifier(boost::bind(&CommandLineParsing::validate_tRegion,this,_1)) + , std::string("interaction site : target regions to be considered for interaction prediction. Either given as BED file (for multi-sequence FASTA input) or in the format 'from1-to1,from2-to2,..' assuming indexing starts with 1").c_str()) + ; + + //// SEED OPTIONS //////////////////////////////////// + + + opts_seed.add_options() + ("noSeed", "if present, no seed is enforced within the predicted interactions") + + ("seedBP" + , value(&(seedBP.val)) + ->default_value(seedBP.def) + ->notifier(boost::bind(&CommandLineParsing::validate_seedBP,this,_1)) + , std::string("number of inter-molecular base pairs within the seed region (arg in range ["+toString(seedBP.min)+","+toString(seedBP.max)+"])").c_str()) + ("seedMaxUP" + , value(&(seedMaxUP.val)) + ->default_value(seedMaxUP.def) + ->notifier(boost::bind(&CommandLineParsing::validate_seedMaxUP,this,_1)) + , std::string("maximal overall number (query+target) of unpaired bases within the seed region (arg in range ["+toString(seedMaxUP.min)+","+toString(seedMaxUP.max)+"])").c_str()) + ; + opts_cmdline_short.add(opts_seed); + opts_seed.add_options() + ("seedQMaxUP" + , value(&(seedQMaxUP.val)) + ->default_value(seedQMaxUP.def) + ->notifier(boost::bind(&CommandLineParsing::validate_seedQMaxUP,this,_1)) + , std::string("maximal number of unpaired bases within the query's seed region (arg in range ["+toString(seedQMaxUP.min)+","+toString(seedQMaxUP.max)+"]); if -1 the value of seedMaxUP is used.").c_str()) + ("seedTMaxUP" + , value(&(seedTMaxUP.val)) + ->default_value(seedTMaxUP.def) + ->notifier(boost::bind(&CommandLineParsing::validate_seedTMaxUP,this,_1)) + , std::string("maximal number of unpaired bases within the target's seed region (arg in range ["+toString(seedTMaxUP.min)+","+toString(seedTMaxUP.max)+"]); if -1 the value of seedMaxUP is used.").c_str()) + ("seedMaxE" + , value(&(seedMaxE.val)) + ->default_value(seedMaxE.def) + ->notifier(boost::bind(&CommandLineParsing::validate_seedMaxE,this,_1)) + , std::string("maximal energy a seed region may have (arg in range ["+toString(seedMaxE.min)+","+toString(seedMaxE.max)+"]).").c_str()) + ("seedMinPu" + , value(&(seedMinPu.val)) + ->default_value(seedMinPu.def) + ->notifier(boost::bind(&CommandLineParsing::validate_seedMinPu,this,_1)) + , std::string("minimal unpaired probability (per sequence) a seed region may have (arg in range ["+toString(seedMinPu.min)+","+toString(seedMinPu.max)+"]).").c_str()) + ("seedQRange" + , value(&(seedQRange)) + ->notifier(boost::bind(&CommandLineParsing::validate_seedQRange,this,_1)) + , std::string("interval(s) in the query to search for seeds in format 'from1-to1,from2-to2,...' (Note, only for single query)").c_str()) + ("seedTRange" + , value(&(seedTRange)) + ->notifier(boost::bind(&CommandLineParsing::validate_seedTRange,this,_1)) + , std::string("interval(s) in the target to search for seeds in format 'from1-to1,from2-to2,...' (Note, only for single target)").c_str()) + ; + + //// INTERACTION/ENERGY OPTIONS //////////////////////// + + opts_inter.add_options() + ("mode,m" + , value(&(predMode.val)) + ->default_value(predMode.def) + ->notifier(boost::bind(&CommandLineParsing::validate_predMode,this,_1)) + , std::string("prediction mode : " + "'H' = heuristic (fast and low memory), " + "'M' = exact and low memory, " + "'E' = exact (high memory)" + ).c_str()) + ; + opts_cmdline_short.add(opts_inter); + opts_inter.add_options() + ("pred" + , value(&(pred.val)) + ->default_value(pred.def) + ->notifier(boost::bind(&CommandLineParsing::validate_pred,this,_1)) + , std::string("prediction target : " + "'S' = single-site minimum-free-energy interaction (interior loops only), " + "'P' = single-site maximum-probability interaction (interior loops only)" + ).c_str()) + ("energy,e" + , value(&(energy.val)) + ->default_value(energy.def) + ->notifier(boost::bind(&CommandLineParsing::validate_energy,this,_1)) + , std::string("energy computation : 'B'ase pair == -1, or 'V' VRNA-based computation (see --energVRNA)").c_str()) + ("energyVRNA" + , value(&energyFile) + ->notifier(boost::bind(&CommandLineParsing::validate_energyFile,this,_1)) + , std::string("energy parameter file of VRNA package to be used. If not provided, the default parameter set of the linked Vienna RNA package is used.").c_str()) + ("temperature" + , value(&(temperature.val)) + ->default_value(temperature.def) + ->notifier(boost::bind(&CommandLineParsing::validate_temperature,this,_1)) + , std::string("temperature in Celsius to setup the VRNA energy parameters (arg in range ["+toString(temperature.min)+","+toString(temperature.max)+"])").c_str()) + ; + + + //// OUTPUT OPTIONS //////////////////////////////////// + + opts_output.add_options() + ("out" + , value(&(out)) + ->default_value(out) + ->notifier(boost::bind(&CommandLineParsing::validate_out,this,_1)) + , std::string("output : provide a file name for output (will be overwritten) or 'STDOUT/STDERR' to write to the according stream").c_str()) + ("outMode" + , value(&(outMode.val)) + ->default_value(outMode.def) + ->notifier(boost::bind(&CommandLineParsing::validate_outMode,this,_1)) + , std::string("output mode :" + " 'N' normal output (ASCII char + energy)," + " 'D' detailed output (ASCII char + energy/position details)," + " 'C' CSV output (see --outCsvCols)," + " '1' backward compatible IntaRNA v1.* normal output," + " 'O' backward compatible IntaRNA v1.* detailed output (former -o)" + ).c_str()) + ("outNumber,n" + , value(&(outNumber.val)) + ->default_value(outNumber.def) + ->notifier(boost::bind(&CommandLineParsing::validate_outNumber,this,_1)) + , std::string("maximal overall number (query+target) of unpaired bases within the seed region (arg in range ["+toString(outNumber.min)+","+toString(outNumber.max)+"])").c_str()) + ("outOverlap" + , value(&(outOverlap.val)) + ->default_value(outOverlap.def) + ->notifier(boost::bind(&CommandLineParsing::validate_outOverlap,this,_1)) + , std::string("suboptimal output : interactions can overlap " + "(N) in none of the sequences, " + "(T) in the target only, " + "(Q) in the query only, " + "(B) in both sequences").c_str()) + ; + opts_cmdline_short.add(opts_output); + opts_output.add_options() + ("outMaxE" + , value(&(outMaxE.val)) + ->default_value(outMaxE.def) + ->notifier(boost::bind(&CommandLineParsing::validate_outMaxE,this,_1)) + , std::string("only interactions with E <= maxE are reported").c_str()) + ("outDeltaE" + , value(&(outDeltaE.val)) + ->default_value(outDeltaE.def) + ->notifier(boost::bind(&CommandLineParsing::validate_outDeltaE,this,_1)) + , std::string("suboptimal output : only interactions with E <= (minE+deltaE) are reported").c_str()) + ("outCsvCols" + , value(&(outCsvCols)) + ->default_value(outCsvCols) + ->notifier(boost::bind(&CommandLineParsing::validate_outCsvCols,this,_1)) + , std::string("output : comma separated list of CSV column IDs to print if outMode=CSV." + " An empty argument prints all possible columns from the following available ID list: " + + boost::replace_all_copy(OutputHandlerCsv::list2string(OutputHandlerCsv::string2list("")), ",", ", ") + ).c_str()) + ("outQAccFile" + , value(&(outQAccFile)) + ->notifier(boost::bind(&CommandLineParsing::validate_outQAccFile,this,_1)) + , std::string("output : writes the query's ED values to the given file/stream" + " in a format similar to RNAplfold unpaired probability output." + " Use STDOUT/STDERR to write to the respective output stream." + ).c_str()) + ("outTAccFile" + , value(&(outTAccFile)) + ->notifier(boost::bind(&CommandLineParsing::validate_outTAccFile,this,_1)) + , std::string("output : writes the target's ED values to the given file/stream" + " in a format similar to RNAplfold unpaired probability output." + " Use STDOUT/STDERR to write to the respective output stream." + ).c_str()) + ("outQPuFile" + , value(&(outQPuFile)) + ->notifier(boost::bind(&CommandLineParsing::validate_outQPuFile,this,_1)) + , std::string("output : writes the query's unpaired probabilities used for ED values to the given file/stream" + " in RNAplfold unpaired probability output format." + " Use STDOUT/STDERR to write to the respective output stream." + ).c_str()) + ("outTPuFile" + , value(&(outTPuFile)) + ->notifier(boost::bind(&CommandLineParsing::validate_outTPuFile,this,_1)) + , std::string("output : writes the target's unpaired probabilities used for ED values to the given file/stream" + " in RNAplfold unpaired probability output format." + " Use STDOUT/STDERR to write to the respective output stream." + ).c_str()) + ("verbose,v", "verbose output") // handled via easylogging++ +// (logFile_argument.c_str(), "name of log file to be used for output") + ; + + //// GENERAL OPTIONS //////////////////////////////////// + + opts_general.add_options() +#if INTARNA_MULITHREADING + ("threads" + , value(&(threads.val)) + ->default_value(threads.def) + ->notifier(boost::bind(&CommandLineParsing::validate_threads,this,_1)) + , std::string("maximal number of threads to be used for parallel computation of query-target-combinations." + " Note, the number of threads multiplies the required memory used for computation!" + " (arg in range ["+toString(threads.min)+","+toString(threads.max)+"])").c_str()) +#endif + ("version", "print version") + ("help,h", "show the help page for basic parameters") + ("fullhelp", "show the extended help page for all available parameters") + ; + opts_cmdline_short.add(opts_general); + + //// GENERAL OPTIONS //////////////////////////////////// + + opts_cmdline_all.add(opts_query).add(opts_target).add(opts_seed).add(opts_inter).add(opts_output).add(opts_general); + + +} + +//////////////////////////////////////////////////////////////////////////// + +CommandLineParsing::~CommandLineParsing() { + + CLEANUP(seedConstraint); + + if (outStream != &std::cout && outStream != &std::cerr) { + std::fstream *outFileStream = dynamic_cast(outStream); + assert(outFileStream != NULL); + // flush and close file stream + outFileStream->flush(); + outFileStream->close(); + // delete file handler + CLEANUP(outFileStream); + } + // reset output stream + outStream = & std::cout; + +} + +//////////////////////////////////////////////////////////////////////////// + +CommandLineParsing::ReturnCode +CommandLineParsing:: +parse(int argc, char** argv) +{ + + // init: nothing parsed yet + parsingCode = ReturnCode::NOT_PARSED_YET; + + using namespace boost::program_options; + + variables_map vm; + try { + int parseStyle = + command_line_style::style_t::allow_long + | command_line_style::style_t::long_allow_adjacent + | command_line_style::style_t::long_allow_next + | command_line_style::style_t::allow_short + | command_line_style::style_t::allow_dash_for_short + | command_line_style::style_t::short_allow_next + | command_line_style::style_t::case_insensitive + ; + store( parse_command_line(argc, argv, opts_cmdline_all, parseStyle), vm); + // parsing fine so far + parsingCode = ReturnCode::KEEP_GOING; + } catch (error& e) { + LOG(ERROR) <(out,std::locale()); + // check if standard stream + if (boost::iequals(out,"STDOUT")) { + outStream = & std::cout; + } else + if (boost::iequals(out,"STDERR")) { + outStream = & std::cerr; + } else { + // open file stream + std::fstream * outFileStream = new std::fstream(); + outFileStream->open( out.c_str(), std::ios_base::out ); + if (!outFileStream->is_open()) { + delete outFileStream; + LOG(ERROR) <<"could not open output file --out='"< 0; + if (noSeedRequired) { + // input sanity check : maybe seed constraints defined -> warn + if (seedBP.val != seedBP.def) LOG(INFO) <<"no seed constraint wanted, but seedBP provided (will be ignored)"; + if (seedMaxUP.val != seedMaxUP.def) LOG(INFO) <<"no seed constraint wanted, but seedMaxUP provided (will be ignored)"; + if (seedQMaxUP.val != seedQMaxUP.def) LOG(INFO) <<"no seed constraint wanted, but seedQMaxUP provided (will be ignored)"; + if (seedTMaxUP.val != seedTMaxUP.def) LOG(INFO) <<"no seed constraint wanted, but seedTMaxUP provided (will be ignored)"; + if (seedMaxE.val != seedMaxE.def) LOG(INFO) <<"no seed constraint wanted, but seedMaxE provided (will be ignored)"; + if (seedMinPu.val != seedMinPu.def) LOG(INFO) <<"no seed constraint wanted, but seedMinPu provided (will be ignored)"; + if (!seedQRange.empty()) LOG(INFO) <<"no seed constraint wanted, but seedQRange provided (will be ignored)"; + if (!seedTRange.empty()) LOG(INFO) <<"no seed constraint wanted, but seedTRange provided (will be ignored)"; + } else { + // check query search ranges + if (!seedQRange.empty()) { + if (query.size()!=1) { + LOG(ERROR) <<"seedQRange given but not only one query sequence provided"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } else { + validate_indexRangeList("seedQRange",seedQRange, 1, query.begin()->size()); + } + } + // check target search ranges + if (!seedTRange.empty()) { + if (target.size()!=1) { + LOG(ERROR) <<"seedTRange given but not only one target sequence provided"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } else { + validate_indexRangeList("seedTRange",seedTRange, 1, target.begin()->size()); + } + } + + // check for minimal sequence length (>=seedBP) + for( size_t i=0; i 0) { + // only for single sequence input supported + if (validateSequenceNumber("qAccConstr",query,1,1)) { + // check length + if (qAccConstr.size() != query.at(0).size()) { + throw error("qAccConstr and query sequence differ in size"); + } + } else { + // TODO report error + NOTIMPLEMENTED("--qAccConstr only supported for single sequence input"); + } + } else { + // generate empty constraint + qAccConstr = std::string(query.at(0).size(),'.'); + } + // check tAccConstr - target sequence compatibility + if (vm.count("tAccConstr") > 0) { + // only for single sequence input supported + if (validateSequenceNumber("tAccConstr",target,1,1)) { + // check length + if (tAccConstr.size() != target.at(0).size()) { + throw error("tAccConstr and target sequence differ in size"); + } + } else { + // TODO report error + NOTIMPLEMENTED("--tAccConstr only supported for single sequence input"); + } + } else { + // generate empty constraint + tAccConstr = std::string(target.at(0).size(),'.'); + } + + // check sanity of accessibility setup + switch(qAcc.val) { + case 'C' : { + if (!qAccFile.empty()) LOG(INFO) <<"qAcc = "<1) throw std::runtime_error("qAcc = "+toString(qAcc.val)+" only supported for single query sequence input"); + } // drop to next handling + case 'N' : { + if (qAccL.val != qAccL.def) LOG(INFO) <<"qAcc = "<1) throw std::runtime_error("tAcc = "+toString(tAcc.val)+" only supported for single target sequence input"); + } // drop to next handling + case 'N' : { + if (tAccL.val != tAccL.def) LOG(INFO) <<"tAcc = "< 0 && energy.val != 'V') { + throw error("--energyVRNA provided but no VRNA energy computation (V) requested (--energy = "+toString(energy.val)+")"); + } + + // check qAcc upper bound + if (qAccL.val > qAccW.val && qAccW.val != 0) { + LOG(ERROR) <<"qAccL = " < tAccW.val && tAccW.val != 0) { + LOG(ERROR) <<"tAccL = " <1) throw std::runtime_error("--outQAccFile only supported for single query sequence input"); + if (!outTAccFile.empty() && getTargetSequences().size()>1) throw std::runtime_error("--outTAccFile only supported for single target sequence input"); + if (!outQPuFile.empty() && getQuerySequences().size()>1) throw std::runtime_error("--outQPuFile only supported for single query sequence input"); + if (!outTPuFile.empty() && getTargetSequences().size()>1) throw std::runtime_error("--outTPuFile only supported for single target sequence input"); + +#if INTARNA_MULITHREADING + // check if multi-threading + if (threads.val > 1 && getTargetSequences().size() > 1) { + // warn if >= 4D space prediction enabled + if (pred.val != 'S' || predMode.val == 'E') { + LOG(WARNING) <<"Multi-threading enabled in high-mem-prediction mode : ensure you have enough memory available!"; + } + if (outMode.val == '1' || outMode.val == 'O') { + throw std::runtime_error("Multi-threading not supported for IntaRNA v1 output"); + } + } +#endif + + // trigger initial output handler output + initOutputHandler(); + + } catch (error& e) { + LOG(ERROR) < 0 ? & energyFile : NULL) ); + } + + + // return validate_* dependent parsing code + return parsingCode; +} + +//////////////////////////////////////////////////////////////////////////// + +void +CommandLineParsing:: +validate_charArgument(const std::string & name, const CommandLineParsing::CharParameter& param, const char & value) +{ + // alphabet check + if ( ! param.isInAlphabet(value) ) { + LOG(ERROR) <<""<isAscending()) { + LOG(ERROR) <to < indexMin || i->to > indexMax) { + LOG(ERROR) <0); + // push full range + r.push_back( IndexRange(0,sequences.at(s++).size()-1) ); + } + return; + } else + // check direct range input + if (boost::regex_match( value, IndexRangeList::regex, boost::match_perl )) { + // ensure single sequence input + if(sequences.size() != 1) { + LOG(ERROR) <size()); + // ensure range list size sufficient + rangeList.resize(1); + // fill range list from string but shift by -1 + rangeList[0] = IndexRangeList( value ).shift(-1, sequences.begin()->size()-1); + return; + } + // might be BED file input + if ( validateFile( value ) ) { + NOTIMPLEMENTED("BED file input for index range list not implemented"); + return; + } + assert(false) /*should never happen*/; +} + +//////////////////////////////////////////////////////////////////////////// + +const CommandLineParsing::RnaSequenceVec & +CommandLineParsing:: +getQuerySequences() const +{ + checkIfParsed(); + return query; +} + +//////////////////////////////////////////////////////////////////////////// + +const CommandLineParsing::RnaSequenceVec & +CommandLineParsing:: +getTargetSequences() const +{ + checkIfParsed(); + return target; +} + +//////////////////////////////////////////////////////////////////////////// + +Accessibility* +CommandLineParsing:: +getQueryAccessibility( const size_t sequenceNumber ) const +{ + checkIfParsed(); + // input check + if (sequenceNumber >= getQuerySequences().size()) { + throw std::runtime_error("CommandLineParsing::getQueryAccessibility : sequence number "+toString(sequenceNumber)+" is out of range (<"+toString(getQuerySequences().size())+")"); + } + const RnaSequence& seq = getQuerySequences().at(sequenceNumber); + + // create temporary constraint object (will be copied) + AccessibilityConstraint accConstraint(qAccConstr,qAccL.val); + // construct selected accessibility object + switch(qAcc.val) { + + case 'N' : // no accessibility + return new AccessibilityDisabled( seq + , qIntLenMax.val + , &accConstraint ); + + case 'E' : // drop to next handling + case 'P' : { // VRNA RNAplfold unpaired probability file output + std::istream * accStream = NULL; + std::ifstream * accFileStream = NULL; + if ( boost::iequals(qAccFile,"STDIN") ) { + accStream = &(std::cin); + } else { + // file support + accFileStream = new std::ifstream(qAccFile); + try { + if(!accFileStream->good()){ + accFileStream->close(); + CLEANUP(accFileStream); + throw std::runtime_error("accessibility parsing of --qAccFile : could not open file '"+qAccFile+"'"); + } + } catch (std::exception & ex) { + accFileStream->close(); + CLEANUP(accFileStream); + throw std::runtime_error("accessibility parsing of --qAccFile : error while opening '"+qAccFile+"' : "+ex.what()); + } + // set file stream as input stream + accStream = accFileStream; + } + Accessibility * acc = new AccessibilityFromStream( seq + , qIntLenMax.val + , &accConstraint + , *accStream + , (qAcc.val == 'P' ? AccessibilityFromStream::Pu_RNAplfold_Text : AccessibilityFromStream::ED_RNAplfold_Text) + , vrnaHandler.getRT() ); + // cleanup + if ( accFileStream != NULL ) { + accFileStream->close(); + CLEANUP( accFileStream ); + } + return acc; + } + + case 'C' : // compute VRNA-based accessibilities + switch( energy.val ) { + // TODO 'B' + case 'V' : // VRNA-based accessibilities + return new AccessibilityVrna( seq + , std::min( qIntLenMax.val == 0 ? seq.size() : qIntLenMax.val + , qAccW.val == 0 ? seq.size() : qAccW.val ) + , &accConstraint + , vrnaHandler + , qAccW.val + ); + default : + NOTIMPLEMENTED("query accessibility computation not implemented for energy = '"+toString(energy.val)+"'. Disable via --qAcc=N."); + } break; + default : + NOTIMPLEMENTED("CommandLineParsing::getQueryAccessibility : qAcc = '"+toString(qAcc.val)+"' is not supported"); + } + return NULL; +} + +//////////////////////////////////////////////////////////////////////////// + +Accessibility* +CommandLineParsing:: +getTargetAccessibility( const size_t sequenceNumber ) const +{ + checkIfParsed(); + // input check + if (sequenceNumber >= getTargetSequences().size()) { + throw std::runtime_error("CommandLineParsing::getTargetAccessibility : sequence number "+toString(sequenceNumber)+" is out of range (<"+toString(getTargetSequences().size())+")"); + } + // create temporary constraint object (will be copied) + AccessibilityConstraint accConstraint(tAccConstr,tAccL.val); + const RnaSequence& seq = getTargetSequences().at(sequenceNumber); + switch(tAcc.val) { + + case 'N' : // no accessibility + return new AccessibilityDisabled( seq + , tIntLenMax.val + , &accConstraint ); + + case 'E' : // drop to next handling + case 'P' : { // VRNA RNAplfold unpaired probability file output + std::istream * accStream = NULL; + std::ifstream * accFileStream = NULL; + // select stream to read from + if ( boost::iequals(tAccFile,"STDIN") ) { + accStream = &(std::cin); + } else { + // file support + accFileStream = new std::ifstream(tAccFile); + try { + if(!accFileStream->good()){ + accFileStream->close(); + CLEANUP(accFileStream); + throw std::runtime_error("accessibility parsing of --tAccFile : could not open file '"+tAccFile+"'"); + } + } catch (std::exception & ex) { + accFileStream->close(); + CLEANUP(accFileStream); + throw std::runtime_error("accessibility parsing of --tAccFile : error while opening '"+tAccFile+"' : "+ex.what()); + } + // set file stream as input stream + accStream = accFileStream; + } + // read data + Accessibility * acc = new AccessibilityFromStream( seq + , tIntLenMax.val + , &accConstraint + , *accStream + , ( tAcc.val == 'P' ? AccessibilityFromStream::Pu_RNAplfold_Text : AccessibilityFromStream::ED_RNAplfold_Text ) + , vrnaHandler.getRT() ); + // cleanup + if ( accFileStream != NULL ) { + accFileStream->close(); + CLEANUP( accFileStream ); + } + return acc; + } + case 'C' : // compute accessibilities + switch( energy.val ) { + // TODO 'B' + case 'V' : // VRNA-based accessibilities + return new AccessibilityVrna( seq + , std::min( tIntLenMax.val == 0 ? seq.size() : tIntLenMax.val + , tAccW.val == 0 ? seq.size() : tAccW.val ) + , &accConstraint + , vrnaHandler + , tAccW.val + ); + default : + NOTIMPLEMENTED("target accessibility computation not implemented for energy = '"+toString(energy.val)+"'. Disable via --tAcc=N."); + } break; + default : + NOTIMPLEMENTED("CommandLineParsing::getTargetAccessibility : tAcc = '"+toString(tAcc.val)+"' is not supported"); + } + return NULL; +} + +//////////////////////////////////////////////////////////////////////////// + +InteractionEnergy* +CommandLineParsing:: +getEnergyHandler( const Accessibility& accTarget, const ReverseAccessibility& accQuery ) const +{ + checkIfParsed(); + + // check whether to compute ES values (for multi-site predictions + const bool initES = std::string("M").find(pred.val) != std::string::npos; + + switch( energy.val ) { + case 'B' : return new InteractionEnergyBasePair( accTarget, accQuery, tIntLoopMax.val, qIntLoopMax.val, initES ); + case 'V' : return new InteractionEnergyVrna( accTarget, accQuery, vrnaHandler, tIntLoopMax.val, qIntLoopMax.val, initES ); + default : + NOTIMPLEMENTED("CommandLineParsing::getEnergyHandler : energy = '"+toString(energy.val)+"' is not supported"); + } + return NULL; + +} + +//////////////////////////////////////////////////////////////////////////// + +OutputConstraint +CommandLineParsing:: +getOutputConstraint() const +{ + checkIfParsed(); + OutputConstraint::ReportOverlap overlap = OutputConstraint::ReportOverlap::OVERLAP_BOTH; + switch(outOverlap.val) { + case 'N' : overlap = OutputConstraint::ReportOverlap::OVERLAP_NONE; break; + case 'T' : overlap = OutputConstraint::ReportOverlap::OVERLAP_SEQ1; break; + case 'Q' : overlap = OutputConstraint::ReportOverlap::OVERLAP_SEQ2; break; + case 'B' : overlap = OutputConstraint::ReportOverlap::OVERLAP_BOTH; break; + default : throw std::runtime_error("CommandLineParsing::getOutputConstraint() : unsupported outOverlap value "+toString(outOverlap.val)); + } + return OutputConstraint( + outNumber.val + , overlap + , static_cast(outMaxE.val) + , static_cast(outDeltaE.val) + ); +} + +//////////////////////////////////////////////////////////////////////////// + +void +CommandLineParsing:: +parseSequences(const std::string & paramName, + const std::string& paramArg, + RnaSequenceVec& sequences ) +{ + // clear sequence container + sequences.clear(); + + // read FASTA from STDIN stream + if (boost::iequals(paramArg,"STDIN")) { + parseSequencesFasta(paramName, std::cin, sequences); + } else + if (RnaSequence::isValidSequenceIUPAC(paramArg)) { + // direct sequence input + sequences.push_back(RnaSequence(paramName,paramArg)); + } else + { + // open file handle + std::ifstream infile(paramArg); + try { + if(!infile.good()){ + LOG(ERROR) <<"FASTA parsing of "<' ){ // Identifier marker + if( !name.empty() ){ // we had read a name before + // store last sequence + // check if data complete + if (sequence.empty()) { + LOG(ERROR) <<"FASTA parsing of "<' plus successive and trailing whitespaces + trimStart = line.find_first_not_of(" \t",1); + line = line.substr( trimStart, std::max(0,(int)line.find_last_not_of(" \t\n\r")+1-trimStart) ); + name = line; + } + // clear sequence data + sequence.clear(); + } else + // has to be a sequence + if( !name.empty() ){ + // trim leading/trailing whitespaces + trimStart = line.find_first_not_of(" \t"); + line = line.substr( trimStart, std::max(0,(int)line.find_last_not_of(" \t\n\r")+1-trimStart) ); + // check for enclosed whitespaces + if( line.find(' ') != std::string::npos ){ // Invalid sequence--no spaces allowed + LOG(ERROR) <<"FASTA parsing of "< max) { + LOG(ERROR) <<""<0 ? std::min(Accessibility::ED_UPPER_BOUND, - energy.getRT() * std::log( seedMinPu.val )) : Accessibility::ED_UPPER_BOUND) // transform unpaired prob to ED value + // shift ranges to start counting with 0 + , IndexRangeList( seedTRange ).shift(-1,energy.size1()-1) + , IndexRangeList( seedQRange ).shift(-1,energy.size2()-1).reverse(energy.size2()) + ); + } + return *seedConstraint; +} + +//////////////////////////////////////////////////////////////////////////// + +const IndexRangeList& +CommandLineParsing:: +getQueryRanges( const size_t sequenceNumber ) const +{ +#if IN_DEBUG_MODE + if (sequenceNumber>=qRegion.size()) + throw std::runtime_error("CommandLineParsing::getQueryRanges("+toString(sequenceNumber)+") out of bounds"); + if (qRegion.at(sequenceNumber).empty()) + throw std::runtime_error("CommandLineParsing::getQueryRanges("+toString(sequenceNumber)+") is empty"); +#endif + return qRegion.at(sequenceNumber); +} + +//////////////////////////////////////////////////////////////////////////// + +const IndexRangeList& +CommandLineParsing:: +getTargetRanges( const size_t sequenceNumber ) const +{ +#if IN_DEBUG_MODE + if (sequenceNumber>=tRegion.size()) + throw std::runtime_error("CommandLineParsing::getTargetRanges("+toString(sequenceNumber)+") out of bounds"); + if (tRegion.at(sequenceNumber).empty()) + throw std::runtime_error("CommandLineParsing::getTargetRanges("+toString(sequenceNumber)+") is empty"); +#endif + return tRegion.at(sequenceNumber); +} + +//////////////////////////////////////////////////////////////////////////// + +void +CommandLineParsing:: +writeAccessibility( const Accessibility& acc, const std::string fileOrStream, const bool writeED ) const +{ + if (fileOrStream.empty()) + return; + + // setup output stream + std::ostream * out = NULL; + std::fstream * outFile = NULL; + if ( boost::iequals(fileOrStream,"STDOUT")) { + out = &std::cout; + } else + if ( boost::iequals(fileOrStream,"STDERR")) { + out = &std::cerr; + } else { + // open file + outFile = new std::fstream(); + outFile->open( fileOrStream.c_str(), std::ios_base::out ); + if (!outFile->is_open()) { + CLEANUP(outFile); + throw std::runtime_error("could not open output file '"+fileOrStream +"' for "+(writeED?"accessibility":"unpaired probability")+" output"); + } else { + out = outFile; + } + } + + // write data to stream + if (writeED) { + acc.writeRNAplfold_ED_text( *out ); + } else { + acc.writeRNAplfold_Pu_text( *out, vrnaHandler.getRT() ); + } + + // clean up + if (outFile != NULL) { outFile->close(); } + CLEANUP(outFile); +} + +//////////////////////////////////////////////////////////////////////////// + + + diff --git a/src/CommandLineParsing.h b/src/CommandLineParsing.h new file mode 100644 index 00000000..3849aa17 --- /dev/null +++ b/src/CommandLineParsing.h @@ -0,0 +1,1379 @@ + +#ifndef COMMANDLINEPARSING_H_ +#define COMMANDLINEPARSING_H_ + +#include "general.h" +#include "RnaSequence.h" + +#include +#include +#include + +#include +#include + +#include "Accessibility.h" +#include "InteractionEnergy.h" +#include "OutputHandler.h" +#include "Predictor.h" +#include "SeedConstraint.h" +#include "VrnaHandler.h" + +/** + * Central handler for all command line arguments etc. + * + */ +class CommandLineParsing { +public: + + //! type for a list of sequences + typedef std::vector< RnaSequence > RnaSequenceVec; + //! type for a list of ranges for the sequences + typedef std::vector IndexRangeListVec; + + //! different exit codes for parsing + enum ReturnCode { + KEEP_GOING = -1, + STOP_ALL_FINE = 0, + STOP_PARSING_ERROR = 1, + NOT_PARSED_YET = 999 + }; + + +public: + + /** + * Constructs a commandline argument parser for IntaRNA. + * + * @param logStream the stream to write validation log messages to + */ + CommandLineParsing(); + virtual ~CommandLineParsing(); + + /** + * Parses the commandline arguments as passed to the 'main' method + * @param argc the number of arguments + * @param argv the argument array + * + * @return the parsing code: KEEP_GOING if all went fine, otherwise the exit code to return + * + */ + ReturnCode + parse( int argc, char ** argv ); + +public: + + ///////// GETTERS /////////////////////////////////////////////////// + + /** + * Parses the query parameter and returns all parsed sequences. + * @return the set of parsed query sequences + */ + const RnaSequenceVec& getQuerySequences() const; + + /** + * Parses the target parameter and returns all parsed sequences. + * @return the set of parsed target sequences + */ + const RnaSequenceVec& getTargetSequences() const; + + /** + * Returns a newly allocated Accessibility object for the given query + * sequence according to the user defined parameters. + * @param sequenceNumber the number of the sequence within the vector + * returned by getQuerySequences() + * @return a newly allocated Accessibility object or NULL in error case + */ + Accessibility* getQueryAccessibility( const size_t sequenceNumber ) const; + + /** + * Returns a newly allocated Accessibility object for the given target + * sequence according to the user defined parameters. + * @param sequenceNumber the number of the sequence within the vector + * returned by getTargetSequences() + * @return a newly allocated Accessibility object or NULL in error case + */ + Accessibility* getTargetAccessibility( const size_t sequenceNumber ) const; + + /** + * Access to the ranges to screen for interactions for the query with the + * according sequence number. + * @param sequenceNumber the number of the sequence within the vector + * returned by getQuerySequences() + * @return the range list for the according sequence. + */ + const IndexRangeList& getQueryRanges( const size_t sequenceNumber ) const; + + /** + * Access to the ranges to screen for interactions for the target with the + * according sequence number. + * @param sequenceNumber the number of the sequence within the vector + * returned by getTargetSequences() + * @return the range list for the according sequence. + */ + const IndexRangeList& getTargetRanges( const size_t sequenceNumber ) const; + + /** + * Returns a newly allocated Energy object according to the user defined + * parameters. + * @param accTarget the accessibility object of the target sequence + * @param accQuery the (reversed) accessibility object of the query sequence + * @return the newly allocated Energy object to be deleted by the calling + * function or NULL in error case + */ + InteractionEnergy* getEnergyHandler( const Accessibility& accTarget, const ReverseAccessibility& accQuery ) const; + + /** + * Provides a newly allocated output handler according to the user request. + * + * @param energy the energy handler used for interaction computation + * + * @return the newly allocated OutputHandler object to be deleted by the + * calling function + */ + OutputHandler* getOutputHandler(const InteractionEnergy & energy) const; + + /** + * Provides a newly allocated predictor according to the user defined + * parameters + * @param energy the interaction energy handler to be used + * @param output the output handler to be used + * @return the newly allocated Predictor object to be deleted by the calling + * function + */ + Predictor* getPredictor( const InteractionEnergy & energy + , OutputHandler & output ) const; + + + /** + * Provides the seed constraint according to the user settings + * @param energy the interaction energy handler to be used + * @return the user defined seed constraints + */ + const SeedConstraint & getSeedConstraint( const InteractionEnergy & energy ) const; + + /** + * Access to the set folding temperature in Celsius. + * @return the chosen temperature in Celsius + */ + T_type getTemperature() const; + + /** + * The constraints to be applied to the interaction output generation + * @return the output constraints to be applied + */ + OutputConstraint getOutputConstraint() const; + + /** + * The stream to write the interaction output to + * @return the output stream to write interaction output to + */ + std::ostream & getOutputStream() const; + + /** + * Writes the query accessibility to file/stream if requested + */ + void + writeQueryAccessibility( const Accessibility & acc ) const; + + /** + * Writes the query accessibility to file/stream if requested + */ + void + writeTargetAccessibility( const Accessibility & acc ) const; + +#if INTARNA_MULITHREADING + /** + * Number of threads to be used for parallel processing of + * query-target-combinations. + * @return number of threads to be used (>0) + */ + size_t + getThreads() const; +#endif + +protected: + + ///////// PRIVATE STUFF //////////////////////////////////////////////// + + /** + * Limits and values for a number parameter + */ + template + class NumberParameter { + public: + //! the value of the parameter + T val; + //! the minimally allowed value + const T min; + //! the maximally allowed value + const T max; + //! the default value + const T def; + /** + * construction feeding the members + * @param min the minimally allowed value + * @param max the maximally allowed value + * @param def the default value + */ + NumberParameter( const T min, const T max, const T def ) + : val(def), min(min), max(max), def(def) + {} + //! checks if the given value is in the allowed range [min,max] + //! @param value the value to check + //! @return true if in range; false otherwise + bool isInRange(const T& value) const { + return value >= min && value <= max; + } + //! checks whether or not val is in the allowed range [min,max] + //! @return true if in range; false otherwise + bool isInRange() const { + return isInRange(val); + } + }; + + /** + * Allowed alphabet for a single char parameter + */ + class CharParameter { + public: + //! the value of the parameter + char val; + //! the set of allowed values for this parameter as a string + const std::string alphabet; + //! the default value of the parameter + const char def; + /** + * Construction and member setup + * @param alphabet the allowed set of character values + * @param def the default value (has to be part of the alphabet) + */ + CharParameter( const std::string& alphabet, const char def ) + : val(def), alphabet(alphabet), def(def) + { + if (alphabet.find(def) == std::string::npos) { + throw std::runtime_error("CharParameter() : default value '"+toString(def)+"' is not within alphabet '"+alphabet+"'"); + } + } + //! checks if the given value is in the allowed alphabet + //! @param value the value to check + //! @return true if in alphabet; false otherwise + bool isInAlphabet(const char value) const { + return alphabet.find(value) != std::string::npos; + } + //! checks whether or not val is in the allowed alphabet + //! @return true if in alphabet; false otherwise + bool isInAlphabet() const { + return isInAlphabet(val); + } + + }; + + //! whether or not STDIN was already requested by one of the following + //! arguments + bool stdinUsed; + + //! query specific options + boost::program_options::options_description opts_query; + //! target specific options + boost::program_options::options_description opts_target; + //! seed specific options + boost::program_options::options_description opts_seed; + //! interaction/energy specific options + boost::program_options::options_description opts_inter; + //! general options + boost::program_options::options_description opts_general; + //! output options + boost::program_options::options_description opts_output; + + //! overall option list + boost::program_options::options_description opts_cmdline_all; + + //! short option list + boost::program_options::options_description opts_cmdline_short; + + //! central result code to be set by validate_* functions in error case + ReturnCode parsingCode; + + //! the query command line argument + std::string queryArg; + //! the container holding all query sequences + RnaSequenceVec query; + //! accessibility computation mode for query sequences + CharParameter qAcc; + //! window length for query accessibility computation (plFold) + NumberParameter qAccW; + //! maximal base pair span for query accessibility computation (plFold) + NumberParameter qAccL; + //! constraint for accessibility computation for query sequences + std::string qAccConstr; + //! the file/stream to read the query's accessibility data from + std::string qAccFile; + //! window length to be considered accessible/interacting within query + NumberParameter qIntLenMax; + //! maximal internal loop length to be considered accessible/interacting within query + NumberParameter qIntLoopMax; + //! the string encoding of the interaction intervals for the query(s) + std::string qRegionString; + //! the list of interaction intervals for each query sequence + IndexRangeListVec qRegion; + + //! the target command line argument + std::string targetArg; + //! the container holding all target sequences + RnaSequenceVec target; + //! accessibility computation mode for target sequences + CharParameter tAcc; + //! window length for target accessibility computation (plFold) + NumberParameter tAccW; + //! maximal base pair span for target accessibility computation (plFold) + NumberParameter tAccL; + //! constraint for accessibility computation for target sequences + std::string tAccConstr; + //! the file/stream to read the query's accessibility data from + std::string tAccFile; + //! window length to be considered accessible/interacting within target + NumberParameter tIntLenMax; + //! maximal internal loop length to be considered accessible/interacting within target + NumberParameter tIntLoopMax; + //! the string encoding of the interaction intervals for the target(s) + std::string tRegionString; + //! the list of interaction intervals for each target sequence + IndexRangeListVec tRegion; + + //! whether or not a seed is to be required for an interaction or not + bool noSeedRequired; + //! number of base pairs in seed + NumberParameter seedBP; + //! max overall unpaired in seed + NumberParameter seedMaxUP; + //! max unpaired in query's seed + NumberParameter seedQMaxUP; + //! max unpaired in target's seed + NumberParameter seedTMaxUP; + //! max energy of a seed to be considered + NumberParameter seedMaxE; + //! minimal unpaired probability (per sequence) of a seed to be considered + NumberParameter seedMinPu; + //! intervals in query for seed search + std::string seedQRange; + //! intervals in target for seed search + std::string seedTRange; + //! the final seed constraint to be used + mutable SeedConstraint * seedConstraint; + + //! the temperature to be used for energy computations + NumberParameter temperature; + + //! the prediction target (mfe-single-site, max-prob-site, ..) + CharParameter pred; + //! the prediction mode (heuristic, space-efficient, exact) + CharParameter predMode; +#if INTARNA_MULITHREADING + //! number of threads = number of parallel predictors running + NumberParameter threads; +#endif + + //! the selected energy model + CharParameter energy; + //! the provided energy parameter file of the VRNA package + std::string energyFile; + + //! where to write the output to + std::string out; + //! output stream + std::ostream * outStream; + //! output mode + CharParameter outMode; + //! number of (sub)optimal interactions to report + NumberParameter outNumber; + //! whether or not reported interactions can to be overlapping + CharParameter outOverlap; + //! deltaE to mfe allowed to report an interaction + NumberParameter outDeltaE; + //! max E allowed to report an interaction + NumberParameter outMaxE; + //! the CSV column selection + std::string outCsvCols; + //! the CSV column selection + static const std::string outCsvCols_default; + //! the stream/file to write the query's ED values to + std::string outQAccFile; + //! the stream/file to write the target's ED values to + std::string outTAccFile; + //! the stream/file to write the query's unpaired probabilities to + std::string outQPuFile; + //! the stream/file to write the target's unpaired probabilities to + std::string outTPuFile; + + //! the vienna energy parameter handler initialized by #parse() + mutable VrnaHandler vrnaHandler; + +protected: + + /** + * sets the stdinUsed member to true if so far false or raises an exception + * if it is already true. + * @return true if stdinUsed was false so far; false otherwise (error logged) + */ + bool setStdinUsed(); + + //////////// INDIVIDUAL TESTS ////////////////// + + /** + * Validates the query sequence argument. + * @param value the argument value to validate + */ + void validate_query(const std::string & value); + + /** + * Validates the query accessibility argument. + * @param value the argument value to validate + */ + void validate_qAcc(const char & value); + + /** + * Validates the query accessibility sliding window size argument. + * @param value the argument value to validate + */ + void validate_qAccW(const int & value); + + /** + * Validates the query accessibility maximal loop length argument. + * @param value the argument value to validate + */ + void validate_qAccL(const int & value); + + /** + * Validates the query accessibility constraint argument. + * @param value the argument value to validate + */ + void validate_qAccConstr(const std::string & value); + + /** + * Validates the qAccFile argument. + * @param value the argument value to validate + */ + void validate_qAccFile(const std::string & value); + + /** + * Validates the query's maximal accessibility argument. + * @param value the argument value to validate + */ + void validate_qIntLenMax(const int & value); + + /** + * Validates the query's maximal internal loop length argument. + * @param value the argument value to validate + */ + void validate_qIntLoopMax(const int & value); + + /** + * Validates the query's region argument. + * @param value the argument value to validate + */ + void validate_qRegion(const std::string & value); + + /** + * Validates the target sequence argument. + * @param value the argument value to validate + */ + void validate_target(const std::string & value); + + /** + * Validates the target accessibility argument. + * @param value the argument value to validate + */ + void validate_tAcc(const char & value); + + /** + * Validates the target accessibility sliding window size argument. + * @param value the argument value to validate + */ + void validate_tAccW(const int & value); + + /** + * Validates the target accessibility maximal loop length argument. + * @param value the argument value to validate + */ + void validate_tAccL(const int & value); + + /** + * Validates the target accessibility constraint argument. + * @param value the argument value to validate + */ + void validate_tAccConstr(const std::string & value); + + /** + * Validates the tAccFile argument. + * @param value the argument value to validate + */ + void validate_tAccFile(const std::string & value); + + /** + * Validates the target's maximal accessibility argument. + * @param value the argument value to validate + */ + void validate_tIntLenMax(const int & value); + + /** + * Validates the target's maximal internal loop length argument. + * @param value the argument value to validate + */ + void validate_tIntLoopMax(const int & value); + + /** + * Validates the target's region argument. + * @param value the argument value to validate + */ + void validate_tRegion(const std::string & value); + + /** + * Validates the seedBP argument. + * @param value the argument value to validate + */ + void validate_seedBP(const int & value); + + /** + * Validates the seedMaxUP argument. + * @param value the argument value to validate + */ + void validate_seedMaxUP(const int & value); + + /** + * Validates the seedQMaxUP argument. + * @param value the argument value to validate + */ + void validate_seedQMaxUP(const int & value); + + /** + * Validates the seedTMaxUP argument. + * @param value the argument value to validate + */ + void validate_seedTMaxUP(const int & value); + + /** + * Validates the seedMaxE argument. + * @param value the argument value to validate + */ + void validate_seedMaxE(const E_type & value); + + /** + * Validates the seedMinPu argument. + * @param value the argument value to validate + */ + void validate_seedMinPu(const E_type & value); + + /** + * Validates the seedQRange argument. + * @param value the argument value to validate + */ + void validate_seedQRange(const std::string & value); + + /** + * Validates the seedTRange argument. + * @param value the argument value to validate + */ + void validate_seedTRange(const std::string & value); + + /** + * Validates the temperature argument. + * @param value the argument value to validate + */ + void validate_temperature(const T_type & value); + + /** + * Validates the prediction target argument. + * @param value the argument value to validate + */ + void validate_pred(const char & value); + + /** + * Validates the prediction mode argument. + * @param value the argument value to validate + */ + void validate_predMode(const char & value); + + /** + * Validates the temperature argument. + * @param value the argument value to validate + */ + void validate_energy(const char & value); + + /** + * Validates the energy parameter file argument. + * @param value the argument value to validate + */ + void validate_energyFile(const std::string & value); + + /** + * Validates the out argument. + * @param value the argument value to validate + */ + void validate_out(const std::string & value); + + /** + * Validates the outMode argument. + * @param value the argument value to validate + */ + void validate_outMode(const char & value); + + /** + * Validates the outNumber argument. + * @param value the argument value to validate + */ + void validate_outNumber(const int & value); + + /** + * Validates the outOverlap argument. + * @param value the argument value to validate + */ + void validate_outOverlap(const char & value); + + /** + * Validates the outDeltaE argument. + * @param value the argument value to validate + */ + void validate_outDeltaE(const double & value); + + /** + * Validates the outMaxE argument. + * @param value the argument value to validate + */ + void validate_outMaxE(const double & value); + + /** + * Validates the outCsvCols argument. + * @param value the argument value to validate + */ + void validate_outCsvCols(const std::string & value); + + /** + * Validates the outQAccFile argument. + * @param value the argument value to validate + */ + void validate_outQAccFile( const std::string & value); + + /** + * Validates the outTAccFile argument. + * @param value the argument value to validate + */ + void validate_outTAccFile( const std::string & value); + + /** + * Validates the outQPuFile argument. + * @param value the argument value to validate + */ + void validate_outQPuFile( const std::string & value); + + /** + * Validates the outTPuFile argument. + * @param value the argument value to validate + */ + void validate_outTPuFile( const std::string & value); + +#if INTARNA_MULITHREADING + /** + * Validates the threads argument. + * @param value the argument value to validate + */ + void validate_threads( const int & value); +#endif + + //////////// GENERIC TESTS ///////////////// + + /** + * Validates a CharParameter. + * @param argName the name of the parameter (for exception handling) + * @param param the parameter object + * @param value the value of the parameter to validate + */ + void validate_charArgument(const std::string & argName, const CharParameter& param, const char & value); + + + /** + * Validates a NumberParameter. + * @param argName the name of the parameter (for exception handling) + * @param param the parameter object + * @param value the value of the parameter to validate + */ + template + void validate_numberArgument(const std::string & name, const NumberParameter & param, const T& value) + { + // alphabet check + if ( ! param.isInRange(value) ) { + LOG(ERROR) < 0 && qAccW.val < 3) { + LOG(ERROR) <<"\n qAccW = " < 3"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void CommandLineParsing::validate_qAccL(const int & value) +{ + // forward check to general method + validate_numberArgument("qAccL", qAccL, value); + // check lower bound + if (qAccL.val > 0 && qAccL.val < 3) { + LOG(ERROR) <<"qAccL = " < 3"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void CommandLineParsing::validate_qAccConstr(const std::string & value) +{ + // forward check to general method + validate_structureConstraintArgument("qAccConstr", value); + // check if no sliding window computation requested + if (qAccW.val > 0 || qAccL.val > 0) { + LOG(ERROR) <<"query accessibility constraint not possible for sliding window computation (qAccL/W > 0)"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void CommandLineParsing::validate_qAccFile(const std::string & value) +{ + // if not empty + if (!value.empty()) { + // if not STDIN + if ( boost::iequals(value,"STDIN") ) { + setStdinUsed(); + } else { + // should be file + if ( ! validateFile( value ) ) { + LOG(ERROR) <<"query accessibility file '"< 0 && tAccW.val < 3) { + LOG(ERROR) <<"tAccW = " < 3"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void CommandLineParsing::validate_tAccL(const int & value) +{ + // forward check to general method + validate_numberArgument("tAccL", tAccL, value); + // check lower bound + if (tAccL.val > 0 && tAccL.val < 3) { + LOG(ERROR) <<"tAccL = " < 3"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void CommandLineParsing::validate_tAccConstr(const std::string & value) +{ + // forward check to general method + validate_structureConstraintArgument("tAccConstr", value); + // check if no sliding window computation requested + if (tAccW.val > 0 || tAccL.val > 0) { + LOG(ERROR) <<"query accessibility constraint not possible for sliding window computation (tAccL/W > 0)"; + updateParsingCode(ReturnCode::STOP_PARSING_ERROR); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void CommandLineParsing::validate_tAccFile(const std::string & value) +{ + // if not empty + if (!value.empty()) { + // if not STDIN + if ( boost::iequals(value,"STDIN") ) { + setStdinUsed(); + } else { + // should be file + if ( ! validateFile( value ) ) { + LOG(ERROR) <<"target accessibility file '"< + +#include + +/** + * Defines an index region with functionality similar to pair + * + * @author Martin Mann + */ +class IndexRange { + +public: + + //! the start of the index range + size_t from; + + //! the end of the index range + size_t to; + + //! regular expression that matches valid IndexRange string encodings + static const boost::regex regex; + +public: + + /** + * Creates a range + * @param from the start index (default 0) + * @param to the end index (default max()) + */ + IndexRange(const size_t from = 0, + const size_t to = RnaSequence::lastPos) + : from(from), to(to) + { + } + + /** + * Creates a range from a string encoding + * @param stringEncoding string encoding of the range as produced by the + * ostream operator + */ + IndexRange(const std::string & stringEncoding) + : from(0), to(RnaSequence::lastPos) + { + fromString(stringEncoding); + } + + /** + * destruction + */ + virtual ~IndexRange() {} + + /** + * Checks whether or not the range encoding is ascending. + * @return from <= to + */ + bool isAscending() const + { + return from <= to; + } + + /** + * Checks whether or not the range encoding is descending. + * @return from >= to + */ + bool isDescending() const + { + return from >= to; + } + + /** + * Checks whether or not the start of this range preceeds the given range. + * @param r the range to compare to + * @return (fromoperator ==(r) ); + } + + + /** + * Prints the range's boundaries to stream + * @param out the ostream to write to + * @param range the IndexRange object to add + * @return the altered stream out + */ + friend std::ostream& operator<<(std::ostream& out, const IndexRange& range) + { + // has to be in accordance to this.regex + return (out <(stringEncoding.substr(0,splitPos)); + to = boost::lexical_cast(stringEncoding.substr(splitPos+1)); + } + +}; + +#endif /* INDEXRANGE_H_ */ diff --git a/src/IndexRangeList.cpp b/src/IndexRangeList.cpp new file mode 100644 index 00000000..355ce08c --- /dev/null +++ b/src/IndexRangeList.cpp @@ -0,0 +1,241 @@ + +#include "IndexRangeList.h" + +#include + +////////////////////////////////////////////////////////////////////// + +const boost::regex IndexRangeList::regex("^(\\d|([123456789]\\d*)-(\\d|[123456789]\\d*),)*(\\d|[123456789]\\d*)-(\\d|[123456789]\\d*)$"); + +////////////////////////////////////////////////////////////////////// + +bool +IndexRangeList:: +covers( const size_t index ) const +{ + // quick check + if (list.empty()) { + return false; + } + + // find first range that with begin > index + const_iterator r = std::upper_bound( list.begin(), list.end(), IndexRange(index,std::numeric_limits::max()) ); + if ( r == list.begin() ) { + return false; + } else { + // go to preceding range and check if <= the end of the blocked range + return index <= (--r)->to; + } +} + +////////////////////////////////////////////////////////////////////// + +bool +IndexRangeList:: +covers( const IndexRange & range ) const +{ + // quick check + if (list.empty()) { + return false; + } + + // find first range with begin > index + const_iterator r = std::upper_bound( list.begin(), list.end(), range ); + + bool isCovered = false; + if ( r != list.end() ) { + // check succeeding range and check + isCovered = r->from <= range.from && range.to <= r->to; + } + if ( !isCovered && r != list.begin() ) { + // go to preceding range and check + --r; + isCovered = r->from <= range.from && range.to <= r->to; + } + + return isCovered; +} + +////////////////////////////////////////////////////////////////////// + +bool +IndexRangeList:: +overlaps( const IndexRange& range ) const +{ +#if IN_DEBUG_MODE + if (!range.isAscending()) { + throw std::runtime_error("IndexRangeList::overlaps("+toString(range)+") range is not ascending"); + } +#endif + + // quick check + if (list.empty()) { + return false; + } + + // find first range that with begin > range.from + const_iterator r = std::upper_bound( list.begin(), list.end(), range ); + + bool isNotOverlapping = true; + + // check if not overlapping with successor + if (isNotOverlapping && r != list.end()) { + // check for overlap + isNotOverlapping = range.to < r->from; + } + + // check if not overlapping with predecessor + if (isNotOverlapping && r != list.begin()) { + // go to predecessor + --r; + // check for overlap + isNotOverlapping = r->to < range.from; + } + + return !isNotOverlapping; + +} + +////////////////////////////////////////////////////////////////////// + +void +IndexRangeList:: +push_back( const IndexRange& range ) +{ +#if IN_DEBUG_MODE + if (!range.isAscending()) { + throw std::runtime_error("IndexRangeList::push_back("+toString(range)+") range is not ascending"); + } + if (!list.empty() && list.rbegin()->from >= range.from) { + throw std::runtime_error("IndexRangeList::push_back("+toString(range)+") violates order given last range = "+toString(*(list.rbegin()))); + } +#endif + if (!list.empty() && list.rbegin()->to >= range.from) { + NOTIMPLEMENTED("IndexRangeList::push_back() : overlapping ranges are currently not supported") + } + // sorting should be OK (in debug mode.. ;) ) + list.push_back( range ); +} + +////////////////////////////////////////////////////////////////////// + +IndexRangeList::iterator +IndexRangeList:: +insert( const IndexRange& range ) +{ +#if IN_DEBUG_MODE + if (!range.isAscending()) { + throw std::runtime_error("IndexRangeList::insert("+toString(range)+") range is not ascending"); + } +#endif + // add first member to list + if (list.empty()) { + list.push_back( range ); + return begin(); + } else + // insert accordingly + { + // find first range that with begin > i + List::iterator r = std::upper_bound( list.begin(), list.end(), range ); + if (r != list.end()) { + // check for overlap + if (range.to >= r->from) { + NOTIMPLEMENTED("IndexRangeList::insert() : overlapping ranges are currently not supported") + } + } + // check if already existing (predecessor) + if (r != list.begin()){ + --r; + // check if already present + if (*r == range) { + // return iterator to already present element + return r; + } + // check for overlap + if (r->to >= range.from) { + NOTIMPLEMENTED("IndexRangeList::insert() : overlapping ranges are currently not supported") + } + ++r; + } + // insert accordingly preserving sorting + return list.insert( r, range ); + } +} + +////////////////////////////////////////////////////////////////////// + +IndexRangeList +IndexRangeList:: +shift( const int indexShift, const size_t indexMax ) const +{ + IndexRangeList l; + IndexRange r2; + for (IndexRangeList::const_iterator r=begin(); r!=end(); r++) { + // skip ranges leaving the valid interval + if ( (indexShift+((int)r->to)) < 0 || (int)indexMax < (indexShift+((int)r->from))) { + continue; + } + // get shifted range boundaries + r2.from = (size_t)std::max(0,indexShift+((int)r->from)); + r2.to = (size_t)std::min((int)indexMax,indexShift+((int)r->to)); + // store shifted and cut range + l.insert(r2); + } + + // final updated range list + return l; +} + +////////////////////////////////////////////////////////////////////// + +IndexRangeList & +IndexRangeList:: +reverse( const size_t seqLength ) +{ + // reverse each entry + size_t tmpFrom; + for (IndexRangeList::iterator r=begin(); r!=end(); r++) { +#if IN_DEBUG_MODE + // check if reversal is possible + if (r->from >= seqLength || r->to >= seqLength) throw std::runtime_error("IndexRangeList::reverse("+toString(seqLength)+") = range "+toString(*r)+" exceeds seqLength"); +#endif + // reverse boundaries + tmpFrom = r->from; + r->from = seqLength -1 - r->to; + r->to = seqLength -1 - tmpFrom; + } + // reverse order of list entries + list.reverse(); + // return access to altered element + return *this; +} + +////////////////////////////////////////////////////////////////////// + +void +IndexRangeList:: +fromString( const std::string & stringEncoding ) +{ + // clear current data + this->clear(); + // check if something to be parsed + if (!stringEncoding.empty()) { + // check if parsable + if( ! boost::regex_match(stringEncoding, IndexRangeList::regex, boost::match_perl) ) { + throw std::runtime_error("IndexRangeList::fromString("+stringEncoding+") uses no valid index range string encoding matching '"+regex.str()+"'"); + } + // find split position + size_t startPos = 0, splitPos = std::string::npos; + while (startPos != splitPos) { + splitPos = stringEncoding.find(',',startPos); + // insert interval + this->insert( IndexRange(stringEncoding.substr(startPos,splitPos-(splitPos==std::string::npos?0:startPos)))); + // update start of next interval encoding to parse + startPos = splitPos + (splitPos != std::string::npos ? 1 : 0); + } + } +} + +////////////////////////////////////////////////////////////////////// + + diff --git a/src/IndexRangeList.h b/src/IndexRangeList.h new file mode 100644 index 00000000..5932b591 --- /dev/null +++ b/src/IndexRangeList.h @@ -0,0 +1,396 @@ + +#ifndef INDEXRANGELIST_H_ +#define INDEXRANGELIST_H_ + +#include "IndexRange.h" + +#include + +#include + +/** + * Sorted list of non-overlapping ascending ranges. + * + * TODO add support for overlapping ranges + * + * @author Martin Mann + * + */ +class IndexRangeList +{ +protected: + + //! List of ranges + typedef std::list< IndexRange > List; + +public: + + //! regular expression that matches valid IndexRangeList string encodings + static const boost::regex regex; + +public: + + typedef List::iterator iterator; + typedef List::const_iterator const_iterator; + typedef List::reverse_iterator reverse_iterator; + typedef List::const_reverse_iterator const_reverse_iterator; + +public: + + /** + * empty construction + */ + IndexRangeList(); + + /** + * String encoding based construction + * + * @param stringEncoding the string encoding to be parsed + * + * @throws std::runtime_error if stringEncoding does not match regex + */ + IndexRangeList( const std::string & stringEncoding ); + + /** + * copy construction + * @param toCopy the list to make this a copy of + */ + IndexRangeList( const IndexRangeList & toCopy ); + + + /** + * destruction + */ + virtual ~IndexRangeList(); + + + /** + * checks whether or not a given index is covered by one of the stored + * index ranges + * @param index the index to check + * @return true if @p index is within one of the index ranges (including + * boundaries); false otherwise + */ + bool covers( const size_t index ) const; + + /** + * checks whether or not a given index range is completely covered by one + * of the stored index ranges + * @param from the start index of the range of interest + * @param to the end index of the range of interest + * @return true if [from,to] is within one of the index ranges (including + * boundaries); false otherwise + */ + bool covers( const size_t from, const size_t to ) const; + + /** + * checks whether or not a given index range is completely covered by one + * of the stored index ranges + * @param range the index range of interest + * @return true if range is within one of the index ranges (including + * boundaries); false otherwise + */ + bool covers( const IndexRange & range ) const; + + /** + * checks whether or not a given ascending index range is overlapping with at least + * one of the stored index ranges + * @param index the index to check + * @return true if @p index is within one of the index ranges (including + * boundaries); false otherwise + */ + bool overlaps( const IndexRange& range ) const; + + /** + * adds an ascending range to the end of the list. + * NOTE: if the insertion would violate range sorting, an exception is raised + * @param range the ascending index range to add (from should be > rbegin()->to) + */ + void push_back( const IndexRange& range ); + + /** + * adds an ascending range to the according position of the sorted list. + * Insertion of duplicates is avoided. + * @param range the ascending index range to add + * @return iterator to the inserted (or already present) element + */ + iterator insert( const IndexRange& range ); + + /** + * removes an element from the list + * @param i the iterator pointing to the element to delete + */ + iterator erase( iterator i ); + + /** + * Access to the first index range within the list + * @return the begin of the list + */ + iterator begin(); + + /** + * Access to the end of the index range iteration + * @return the end of the list + */ + iterator end(); + + /** + * Constant access to the first index range within the list + * @return the begin of the list + */ + const_iterator begin() const; + + /** + * Constant access to the end of the index range iteration + * @return the end of the list + */ + const_iterator end() const; + + /** + * Access to the last index range within the list + * @return the begin of the list + */ + reverse_iterator rbegin(); + + /** + * Access to the end of the reversed index range iteration + * @return the end of the list + */ + reverse_iterator rend(); + + /** + * Constant access to the last index range within the list + * @return the begin of the list + */ + const_reverse_iterator rbegin() const; + + /** + * Constant access to the end of the reversed index range iteration + * @return the end of the list + */ + const_reverse_iterator rend() const; + + /** + * Whether or not an index range is present + * @return true if no index range is stored; false otherwise + */ + bool empty() const; + + /** + * The number of index ranges stored + * @return the number of stored index ranges + */ + size_t size() const; + + /** + * Removes all stored elements + */ + void clear(); + + /** + * updates the range list data from a valid string encoding (matching regex) + * @param stringEncoding the interval list string encoding + * @throws std::runtime_error if stringEncoding does not match regex + */ + void + fromString( const std::string & stringEncoding ); + + /** + * shifts all indices by the given value and returns all intervals within + * the boundaries [0,indexMax] including indexMax + * @param indexShift the shift to be applied to all index range boundaries + * @param indexMax the maximal value any index in the returned list can have + * @return a new range list with shifted ranges where all ranges shifted to + * indices below 0 are (I) removed if range'.to < 0 or (II) cut to + * range'.from = 0; the same holds respectively for upper bound + * violations exceeding indexMax. + */ + IndexRangeList + shift( const int indexShift, const size_t indexMax ) const; + + /** + * Reverses all indices for the given sequence length, i.e. + * (newIdx = seqLength-1-oldIdx) + */ + IndexRangeList & + reverse( const size_t seqLength ); + + /** + * Reverses all indices for the given sequence length, i.e. + * (newIdx = seqLength-1-oldIdx) + */ + IndexRangeList + reverse( const size_t seqLength ) const; + + /** + * Checks whether or not two range lists are equivalent + * @param r the range list to compare to + * @return list == r.list + */ + const bool operator == ( const IndexRangeList &r ) const { + return this->list == r.list; + } + + /** + * Checks whether or not two range lists are inequivalent + * @param r the range list to compare to + * @return list != r.list + */ + const bool operator != ( const IndexRangeList &r ) const { + return this->list != r.list; + } + +protected: + + //! the list of indices + List list; + +}; + +/** + * Prints the boundaries of the list's ranges to stream + * @param out the ostream to write to + * @param l the IndexRangeList object to add + * @return the altered stream out + */ +std::ostream& operator<<(std::ostream& out, const IndexRangeList& l); + + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::IndexRangeList() +: +list() +{ +} + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::IndexRangeList( const std::string & stringEncoding ) +: +list() +{ + fromString(stringEncoding); +} + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::IndexRangeList( const IndexRangeList & toCopy ) +: +list(toCopy.list) +{ +} + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::~IndexRangeList() +{ +} + +////////////////////////////////////////////////////////////////////// + +inline +bool +IndexRangeList:: +covers( const size_t from, const size_t to ) const +{ + return covers( IndexRange(from, to) ); +} + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList +IndexRangeList:: +reverse( const size_t seqLength ) const +{ + // create copy + IndexRangeList tmp(*this); + // reverse and return copy + return tmp.reverse( seqLength ); +} + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::iterator IndexRangeList::erase( IndexRangeList::iterator i ) { return list.erase( i ); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::iterator IndexRangeList::begin() { return list.begin(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::iterator IndexRangeList::end() { return list.end(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::const_iterator IndexRangeList::begin() const { return list.begin(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::const_iterator IndexRangeList::end() const { return list.end(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::reverse_iterator IndexRangeList::rbegin() { return list.rbegin(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::reverse_iterator IndexRangeList::rend() { return list.rend(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::const_reverse_iterator IndexRangeList::rbegin() const { return list.rbegin(); } + +////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList::const_reverse_iterator IndexRangeList::rend() const { return list.rend(); } + +////////////////////////////////////////////////////////////////////// + +inline +bool IndexRangeList::empty() const { return list.empty(); } + +////////////////////////////////////////////////////////////////////// + +inline +size_t IndexRangeList::size() const { return list.size(); } + +////////////////////////////////////////////////////////////////////// + +inline +void IndexRangeList::clear() { return list.clear(); } + +////////////////////////////////////////////////////////////////////// + +inline +std::ostream& operator<<(std::ostream& out, const IndexRangeList& l) +{ + // output according to regex + for (IndexRangeList::const_iterator i=l.begin(); i!=l.end(); i++) + out <<(i==l.begin()?"":",") <<*i; + return out; +} + +////////////////////////////////////////////////////////////////////// + + + + +#endif /* INDEXRANGELIST_H_ */ diff --git a/src/Interaction.cpp b/src/Interaction.cpp new file mode 100644 index 00000000..fc849ba0 --- /dev/null +++ b/src/Interaction.cpp @@ -0,0 +1,141 @@ +/* + * Interaction.cpp + * + * Created on: 14.07.2014 + * Author: Mmann + */ + +#include "Interaction.h" +#include "general.h" + +#include +#include + + +//////////////////////////////////////////////////////////////////////////// + +bool +Interaction:: +isValid() const +{ + + // no or single interaction + if (basePairs.size() < 2) { + // check if at least one interacting base pair + return !isEmpty(); + } + + // multiple interacting base pairs + PairingVec::const_iterator i = basePairs.begin(), j = basePairs.begin(); + // index order and duplicate check + bool isValid = true; + for (++j; isValid && j!=basePairs.end(); ++i,++j ) { + isValid = (i->first < j->first) && (i->second > j->second); + } + + return isValid; + +} + +//////////////////////////////////////////////////////////////////////////// + +void +Interaction:: +setSeedRange( const BasePair ij1, const BasePair ij2, const E_type energy ) +{ + // store seed information + if (seedRange == NULL) { + // create new seed information + seedRange = new InteractionRange( + // sequences + *(s1), *(s2), + // seed ranges + IndexRange(ij1.first,ij2.first), IndexRange(ij1.second,ij2.second), + // hybridization loop energies only + energy + ); + } else { + // overwrite + assert(s1 == seedRange->s1); + assert(s2 == seedRange->s2); + // seed ranges + seedRange->r1 = IndexRange(ij1.first,ij2.first); + seedRange->r2 = IndexRange(ij1.second,ij2.second), + // hybridization loop energies only + seedRange->energy = energy; + } + +} + +//////////////////////////////////////////////////////////////////////////// + +Interaction & +Interaction:: +operator= ( const InteractionRange & range ) +{ +#if IN_DEBUG_MODE + if (!range.isSane()) + throw std::runtime_error("Interaction::=("+toString(range)+") not sane!"); +#endif + // clear current interactions + basePairs.clear(); + + // copy sequence handles + s1 = range.s1; + s2 = range.s2; + + // add left boundary base pair + basePairs.push_back( BasePair(range.r1.from, range.r2.from) ); + // add right boundary base pair if both not singleton ranges + if ( range.r1.from != range.r1.to || range.r2.from != range.r2.to ) { + basePairs.push_back( BasePair(range.r1.to, range.r2.to) ); + } + + // copy energy value + energy = range.energy; + + // undo seed information + CLEANUP(seedRange); + + return *this; +} + + + +//////////////////////////////////////////////////////////////////////////// + +std::string +Interaction:: +dotBar( const Interaction & i ) +{ +#if IN_DEBUG_MODE + if (!i.isValid()) + throw std::runtime_error("Interaction::dotBar("+toString(i)+") not valid!"); +#endif + // compile overall dot-bracket representation + return toString(i.basePairs.begin()->first +1) + + dotSomething(i.basePairs.begin(), i.basePairs.end(), true, '|') + +"&" + +toString(i.basePairs.rbegin()->second +1) + + dotSomething(i.basePairs.rbegin(), i.basePairs.rend(), false, '|') + ; +} + +//////////////////////////////////////////////////////////////////////////// + +std::string +Interaction:: +dotBracket( const Interaction & i, const char symOpen, const char symClose ) +{ +#if IN_DEBUG_MODE + if (!i.isValid()) + throw std::runtime_error("Interaction::dotBracket("+toString(i)+") not valid!"); +#endif + // compile overall dot-bracket representation + return dotSomething(i.basePairs.begin(), i.basePairs.end(), true, symOpen) + +"&" + + dotSomething(i.basePairs.rbegin(), i.basePairs.rend(), false, symClose) + ; +} + +//////////////////////////////////////////////////////////////////////////// diff --git a/src/Interaction.h b/src/Interaction.h new file mode 100644 index 00000000..d5f1c232 --- /dev/null +++ b/src/Interaction.h @@ -0,0 +1,340 @@ + +#ifndef INTERACTION_H_ +#define INTERACTION_H_ + +#include +#include + +#include "general.h" +#include "RnaSequence.h" +#include "InteractionRange.h" + +// dummy declaration to avoid inclusion loop +class InteractionRange; + + +/** + * Data structure to describe and store an Interaction + */ +class Interaction { + +public: + + //! type of a base pair index encoding + typedef std::pair BasePair; + + //! type of a vector encoding base pair indices that are interacting + typedef std::vector PairingVec; + +public: + + //! the first interaction partner + const RnaSequence * s1; + + //! the second interaction partner + const RnaSequence * s2; + + //! interacting indices + PairingVec basePairs; + + //! energy of the interaction (can be NaN) + E_type energy; + + //! optional: range of seed interaction and full seed energy + InteractionRange * seedRange; + + /** + * construction + * @param s1 the sequence of the first interaction partner + * @param s2 the sequence of the second interaction partner + */ + Interaction( const RnaSequence & s1, const RnaSequence & s2 ); + + /** + * construction from interaction range, ie. forming base pairs at the + * beginning and end of the interaction range. + * + * NOTE: the ends have to be complementary nucleotides + * + * @param range the interaction range to be used for initialization + */ + Interaction( const InteractionRange & range ); + + /** + * destruction + */ + virtual ~Interaction(); + + /** + * checks whether or not the current interaction is non-empty, nested and + * sorted. + * @return true if the interaction encoding is non-empty, nested and sorted; + * false otherwise + */ + bool + isValid() const; + + /** + * Checks whether or not the interaction contains no base pairs. + * @return true if the interaction encodes no base pair; false otherwise + */ + bool + isEmpty() const; + + /** + * Sorts the stored interacting base pairs. + */ + void + sort(); + + /** + * Clears all interaction information. + */ + void + clear(); + + /** + * Sets the seedRange member according to the given data + * @param ij1 left most base pair in seed + * @param ij2 right most base pair in seed + * @param energy full energy of the seed interaction + */ + void + setSeedRange( const BasePair ij1, const BasePair ij2, const E_type energy ); + + + /** + * Creates an interaction with one base pair for each interaction range + * boundary. + * + * NOTE: the ends have to be complementary nucleotides + * + * NOTE: the interaction energy is reset too. + * + * @param range the interaction range to get the boundaries from + * @return the altered range object (*this) + */ + Interaction & + operator= ( const InteractionRange & range ); + + + /** + * Compares if an interaction has larger energy that a given value + * + * @param energy the energy to compare to + * @param hasLargerE the interaction that is supposed to have larger energy + * @return (energy < (hasLargerE.energy-precisionDelta)) + */ + static + bool + compareEnergy( const E_type& energy, const Interaction & hasLargerE ); + + /** + * Prints the interacting base pairs to stream + * @param out the ostream to write to + * @param i the Interaction object to add + * @return the altered stream out + */ + friend std::ostream& operator<<(std::ostream& out, const Interaction& i); + + + /** + * Produces a dot-bar encoding of the interaction in the form + * + * startId1 dot-bar-1 & startId2 dot-bar-2 + * + * where dot-bar-1/2 encodes all positions of the first/second sequence + * enclosed by the first and last base pair of the interaction. + * Here, a '|' bar encodes an intermolecular base pair and a '.' dot + * encodes unpaired positions. + * + * Note, within this encoding, the '&' separated parts can be swapped if + * needed yielding still a valid encoding (for the swapped sequences). + * + * @param i interaction to encode + * @return the dot-bracket encoding + */ + static + std::string + dotBar( const Interaction & i ); + + /** + * Produces a dot-bracket encoding of the interaction in VRNA style in the + * form + * + * dot-bracket-1 & dot-bracket-2 + * + * where dot-bracket-1/2 encodes all positions of the first/second sequence + * enclosed by the first and last base pair of the interaction. + * In dot-bracket-1, a closing '(' parenthesis encodes an intermolecular + * base pair and a '.' dot encodes unpaired positions. In dot-bracket-2, + * closing ')' parentheses are used to mark base pairs. + * + * @param i interaction to encode + * @param symOpen the symbol to be used for base pairs in dot-bracket-1 + * @param symClose the symbol to be used for base pairs in dot-bracket-2 + * + * @return the VRNA-styled dot-bracket encoding + */ + static + std::string + dotBracket( const Interaction & i, const char symOpen = '(', const char symClose = ')'); + + +protected: + + template < typename bpIterator > + static + std::string + dotSomething( bpIterator bpBegin, const bpIterator bpEnd, const bool handleSeq1, const char bpSymbol ); + + +}; + +/** + * Prints the interacting base pair to stream + * @param out the ostream to write to + * @param bp the Interaction base pair object to add + * @return the altered stream out + */ +std::ostream& operator<<(std::ostream& out, const Interaction::BasePair& bp); + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + + +inline +Interaction::Interaction( const RnaSequence & s1, const RnaSequence & s2 ) +: + s1(&s1) + , s2(&s2) + , basePairs() + , energy( std::numeric_limits::signaling_NaN() ) + , seedRange( NULL ) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +Interaction::Interaction( const InteractionRange & range ) +: + s1(NULL) + , s2(NULL) + , basePairs() + , energy( std::numeric_limits::signaling_NaN() ) + , seedRange( NULL ) +{ + // init data + this->operator =( range ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +Interaction::~Interaction() +{ + CLEANUP(seedRange); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +Interaction:: +isEmpty() const +{ + return basePairs.size()==0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void +Interaction:: +sort() +{ + // sort based on STL functionalities for vector and pair + std::sort(basePairs.begin(), basePairs.end()); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +void +Interaction:: +clear() +{ + // clear interaction base pairing information + basePairs.clear(); + // clear energy + energy = std::numeric_limits::signaling_NaN(); + // undo seed information + CLEANUP(seedRange); + +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +Interaction:: +compareEnergy( const E_type & energy, const Interaction & hasLargerE ) +{ + return energy < hasLargerE.energy && !(E_equal(energy,hasLargerE.energy)); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +std::ostream& +operator<<(std::ostream& out, const Interaction::BasePair& bp) +{ + out <<"("< +inline +std::string +Interaction:: +dotSomething( bpIterator bp, const bpIterator bpEnd, const bool handleSeq1, const char bpSymbol ) +{ + // stream to compile output + std::stringstream dotBracket; + // compile dotBracket1 + for (bpIterator bpLast = bp; bp!=bpEnd; bp++) { + // fill unpaired up to current bp in seq1 + for ( size_t u = handleSeq1 ? (bp->first - bpLast->first) : (bp->second - bpLast->second); u>1; u-- ) { + dotBracket <<'.'; + } + // add base pair + dotBracket < + +#include + +//////////////////////////////////////////////////////////////////////////// + +InteractionEnergy:: +EnergyContributions +InteractionEnergy:: +getE_contributions( const Interaction & interaction ) const +{ + + // temporary access to range indices + const size_t i1 = interaction.basePairs.begin()->first; + const size_t i2 = getAccessibility2().getReversedIndex(interaction.basePairs.begin()->second); + const size_t j1 = interaction.basePairs.rbegin()->first; + const size_t j2 = getAccessibility2().getReversedIndex(interaction.basePairs.rbegin()->second); + + // fill contribution data structure + EnergyContributions contr; + contr.init = getE_init(); + contr.ED1 = getED1( i1, j1 ); + contr.ED2 = getED2( i2, j2 ); + contr.dangleLeft = (getE_danglingLeft( i1, i2 )*getPr_danglingLeft(i1,j1,i2,j2)); + contr.dangleRight = (getE_danglingRight( j1, j2 )*getPr_danglingRight(i1,j1,i2,j2)); + contr.endLeft = getE_endLeft( i1, i2 ); + contr.endRight = getE_endRight( j1, j2 ); + // compute loop energy + contr.loops = interaction.energy + - contr.init + - contr.ED1 + - contr.ED2 + - contr.dangleLeft + - contr.dangleRight + - contr.endLeft + - contr.endRight + ; + + // final contribution distribution + return contr; +} + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/InteractionEnergy.h b/src/InteractionEnergy.h new file mode 100644 index 00000000..323af3bd --- /dev/null +++ b/src/InteractionEnergy.h @@ -0,0 +1,817 @@ + +#ifndef INTERACTIONENERGY_H_ +#define INTERACTIONENERGY_H_ + + +#include "general.h" +#include "Interaction.h" +#include "Accessibility.h" +#include "ReverseAccessibility.h" + +/** + * Abstract utility class that covers necessary energy related functionalities + * for the interaction energy computation given two RNAs. + * + * @author Martin Mann 2014 + * + */ +class InteractionEnergy { + +public: + + /** + * Container that provides the different energy contributions for an interaction + */ + struct EnergyContributions { + public: + //! the energy for all intermolecular loops + E_type loops; + //! the energy penalty for initiating the interaction + E_type init; + //! the energy penalty for making the interaction site accessible in seq1 + E_type ED1; + //! the energy penalty for making the interaction site accessible in seq2 + E_type ED2; + //! the energy for the dangling ends at the left end of the interaction + E_type dangleLeft; + //! the energy for the dangling ends at the right end of the interaction + E_type dangleRight; + //! the energy penalty for the left end of the interaction + E_type endLeft; + //! the energy penalty for the right end of the interaction + E_type endRight; + }; + + + /** + * Construct energy utility object given the accessibility ED values for + * two RNA sequences. + * + * @param accS1 accessibility of the first sequence + * @param accS2 accessibility of the second sequence (reversed to 3'-5' + * index reading) + * @param maxInternalLoopSize1 maximal number of enclosed unpaired positions + * between two intermolecular base pairs in sequence 1, ie it holds + * for an intermolecular loop closed by base pairs (i1,i2) and + * (j1,j2) : (j1-i1) <= (1+maxInternalLoopSize1) + * @param maxInternalLoopSize2 maximal number of enclosed unpaired positions + * between two intermolecular base pairs in sequence 2, ie it holds + * for an intermolecular loop closed by base pairs (i1,i2) and + * (j1,j2) : (j2-i2) <= (1+maxInternalLoopSize2) + * + */ + InteractionEnergy( const Accessibility & accS1 + , const ReverseAccessibility & accS2 + , const size_t maxInternalLoopSize1 + , const size_t maxInternalLoopSize2 + ); + + /** + * destruction + */ + virtual ~InteractionEnergy(); + + + /** + * Provides the overall energy for an interaction from [i1,j1] in the first + * sequence and [i2,j2] in the second sequence given the hybridization + * energy contribution. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * @param hybridE the hybridization energy for the interaction + * + * @return E = hybridE + * + ED1(i1,j1) + ED2(i2,j2) + * + Edangle(i1,i2) + Edangle(j1,j2) + * + Eend(i1,i2) + Eend(j1,j2) + */ + virtual + E_type + getE( const size_t i1, const size_t j1 + , const size_t i2, const size_t j2 + , const E_type hybridE ) const; + + /** + * Provides details about the energy contributions for the given interaction + * + * @param interaction the interaction of interest + * + * @return the individual energy contributions + */ + virtual + EnergyContributions + getE_contributions( const Interaction & interaction ) const; + + /** + * Checks whether or not two positions can form a base pair + * @param i1 index in first sequence + * @param i2 index in second sequence + * @return true if seq1(i1) can form a base pair with seq2(i2) + */ + virtual + bool + areComplementary( const size_t i1, const size_t i2 ) const; + + /** + * Length of sequence 1 + * @return length of sequence 1 + */ + virtual + size_t + size1() const; + + /** + * Length of sequence 2 + * @return length of sequence 2 + */ + virtual + size_t + size2() const; + + /** + * Provides the ED penalty for making a region with sequence 1 accessible + * + * @param i1 the start of the accessible region + * @param j1 the end of the accessible region + * @return the ED value for [i1,j1] + */ + virtual + E_type + getED1( const size_t i1, const size_t j1 ) const; + + /** + * Provides the ED penalty for making a region with (the reversed) + * sequence 2 accessible + * + * @param i2 the start of the accessible region + * @param j2 the end of the accessible region + * @return the ED value for [i2,j2] + */ + virtual + E_type + getED2( const size_t i2, const size_t j2 ) const; + + /** + * Whether or not position i is accessible for interaction in sequence 1 + * @param i the position of interest in sequence 1 + * @return true if the position can partake in an interaction; false otherwise + */ + virtual + bool + isAccessible1( const size_t i ) const; + + /** + * Whether or not position i is accessible for interaction in sequence 2 + * @param i the position of interest in sequence 2 + * @return true if the position can partake in an interaction; false otherwise + */ + virtual + bool + isAccessible2( const size_t i ) const; + + + /** + * Provides the ensemble energy (ES) of all intramolecular substructures + * that can be formed within a given region of sequence 1 under the + * assumption that the region is part of an (intermolecular) multiloop, + * i.e. at least one base pair is formed by each substructure. + * + * If no structure can be formed within the region, E_INF is returned. + * + * @param i1 the start of the structured region of seq1 + * @param j1 the end of the structured region of seq1 + * @return the ES value for [i1,j1] or E_INF if no intramolecular + * structure can be formed + */ + virtual + E_type + getES1( const size_t i1, const size_t j1 ) const = 0; + + /** + * Provides the ensemble energy (ES) of all intramolecular substructures + * that can be formed within a given region of sequence 2 under the + * assumption that the region is part of an (intermolecular) multiloop, + * i.e. at least one base pair is formed by each substructure. + * + * If no structure can be formed within the region, E_INF is returned. + * + * @param i2 the start of the structured region of seq2 + * @param j2 the end of the structured region of seq2 + * @return the ES value for [i2,j2] or E_INF if no intramolecular + * structure can be formed + */ + virtual + E_type + getES2( const size_t i2, const size_t j2 ) const = 0; + + /** + * Provides the energy contribution for a given number of unpaired + * nucleotides under the + * assumption that the region is part of an (intermolecular) multiloop. + * + * @param numUnpaired the number of unpaired bases + * @return the energy contribution of the given number of unpaired bases + * within an intramolecular multiloop + */ + virtual + E_type + getEU( const size_t numUnpaired ) const = 0; + + /** + * Provides the duplex initiation energy. + * + * @return the energy for duplex initiation + */ + virtual + E_type + getE_init( ) const = 0; + + /** + * Computes the energy estimate for the 'left side' interaction loop region + * closed by the intermolecular base pairs (i1,i2) and enclosing (j1,j2) + * where the regions [i1,j1] and [i2,j2] are considered unpaired or E_INF + * is the internal loop size exceeds the allowed maximum (see constructor). + * + * Note, the right interaction base pair (j1,j2) is not included in the + * returned energy value. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return the energy for the loop + * or E_INF if the allowed loop size is exceeded or no valid internal loop boundaries + */ + virtual + E_type + getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const = 0; + + + /** + * Computes the dangling end energy penalties for the left side + * (i1-1 and i2-1) of the interaction closed by the intermolecular + * base pair (i1,i2). + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the dangling end penalty for the left side of the interaction + */ + virtual + E_type + getE_danglingLeft( const size_t i1, const size_t i2 ) const = 0; + + + /** + * Computes the dangling end energy penalties for the right side + * (j1+1 and j2+1) of the interaction closed by the intermolecular + * base pair (j1,j2). + * + * @param j1 the index of the first sequence interacting with j2 + * @param j2 the index of the second sequence interacting with j1 + * + * @return the dangling end penalty for the right side of the interaction + */ + virtual + E_type + getE_danglingRight( const size_t j1, const size_t j2 ) const = 0; + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "left side" (i1 = 5' end of seq1 of the interaction) + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the loop closure penalty for the left side of the interaction + */ + virtual + E_type + getE_endLeft( const size_t i1, const size_t i2 ) const = 0; + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "right side" (j1 = 3' end of seq1 of the interaction) + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the loop closure penalty for the right side of the interaction + */ + virtual + E_type + getE_endRight( const size_t j1, const size_t j2 ) const = 0; + + /** + * Computes the probability of the dangling ends for the left side + * (i1-1 and i2-1) of the interaction closed by the intermolecular + * base pair (i1,i2) for an interaction of [i1,j1] with [i2,j2]. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return the dangling end probability for the left side of the interaction + */ + virtual + E_type + getPr_danglingLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + /** + * Computes the probability of the dangling ends for the right side + * (j1+1 and j2+1) of the interaction closed by the intermolecular + * base pair (j1,j2) for an interaction of [i1,j1] with [i2,j2]. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return the dangling end probability for the right side of the interaction + */ + virtual + E_type + getPr_danglingRight( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + /** + * Access to the accessibility object of the first sequence + * (including sequence access) + * @return the accessibility object for the first sequence + */ + virtual + const Accessibility & + getAccessibility1() const; + + /** + * Access to the accessibility object of the second sequence + * (including sequence access) + * @return the reverse accessibility object for the second sequence + */ + virtual + const ReverseAccessibility & + getAccessibility2() const; + + /** + * Access to the maximal size of an unpaired stretch within seq1 within + * an interaction. + * @return the maximal internal loop size of an interaction for seq1 + */ + const size_t getMaxInternalLoopSize1() const { + return maxInternalLoopSize1; + } + + /** + * Access to the maximal size of an unpaired stretch within seq2 within + * an interaction. + * @return the maximal internal loop size of an interaction for seq2 + */ + const size_t getMaxInternalLoopSize2() const { + return maxInternalLoopSize2; + } + + /** + * Access to the normalized temperature for Boltzmann weight computation + */ + virtual + E_type + getRT() const = 0; + + + /** + * Provides the best energy gain via stacking possible for this energy + * model + * @return the best stacking energy gain produced by getE_interLoop() + */ + virtual + E_type + getBestE_interLoop() const = 0; + + /** + * Provides the best energy gain possible for left/right dangle + * for this energy model + * @return the best initiation energy gain produced by getE_danglingLeft() or + * getE_danglingRight() + */ + virtual + E_type + getBestE_dangling() const = 0; + + /** + * Provides the best energy gain possible for left/right interaction ends + * for this energy model + * @return the best end energy gain produced by getE_endLeft() or + * getE_endRight() + */ + virtual + E_type + getBestE_end() const = 0; + + + /** + * Provides the Boltzmann weight for a given energy. + * @param energ the energy the Boltzmann weight is to be computed for + * @return the Boltzmann weight, i.e. exp( - energy / RT ); + */ + virtual + E_type + getBoltzmannWeight( const E_type energy ) const ; + + + /** + * Provides the base pair encoding for the given indices. + * @param i1 the index in the first sequence + * @param i2 the index in the (reversed) second sequence + * @return the according base pair (i1,reverseIdx(i2)) + */ + virtual + Interaction::BasePair + getBasePair( const size_t i1, const size_t i2 ) const; + + + /** + * Provides the index within the first sequence of the given base pair. + * @return the index of the first sequence within the base pair encoding + */ + virtual + size_t + getIndex1( const Interaction::BasePair & bp ) const; + + + /** + * Provides the index within the second sequence of the given base pair. + * @return the index of the second sequence within the base pair encoding + */ + virtual + size_t + getIndex2( const Interaction::BasePair & bp ) const; + + +protected: + + //! accessibility values for sequence S1 + const Accessibility & accS1; + + //! accessibility values for sequence S2 (reversed index order) + const ReverseAccessibility & accS2; + + //! maximally allowed unpaired range between two base pairs in sequence S1 + //! forming an intermolecular internal loop + const size_t maxInternalLoopSize1; + + //! maximally allowed unpaired range between two base pairs in sequence S2 + //! forming an intermolecular internal loop + const size_t maxInternalLoopSize2; + + /** + * Checks whether or not the given indices are valid index region within the + * sequence for an intermolecular loop and do not violate the maximal + * internal loop size. + * @param seq the sequence the indices correspond to + * @param i begin index of the region in the sequence + * @param j end index of the region in the sequence + * @param maxInternalLoopSize the maximally allowed distance of i and j, ie. + * (j-i+1) <= maxInternalLoopSize + * + * @return true if the indices are fulfilling 0 <= i <= j < seq.length, + * both sequence positions denote non-ambiguous nucleotides (!= N) + * and (j-i+1) <= maxInternalLoopSize; false otherwise + */ + static + bool + isAllowedLoopRegion( const RnaSequence& seq, const size_t i, const size_t j, const size_t maxInternalLoopSize ); + + /** + * Checks whether or not the given indices mark valid internal loop + * boundaries, i.e. + * - (i1,i2) and (j1,j2) are complementary + * - i1..j1 and i2..j2 are allowed loop regions + * - no boundary overlap ( (j1-i1==0 && j2-i2==0) || (j1-i1>0 && j2-i2>0) ) + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return true if the boundaries are sound for internal loop calculation; + * false otherwise + */ + bool + isValidInternalLoop( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + +}; + + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + + +inline +InteractionEnergy::InteractionEnergy( const Accessibility & accS1 + , const ReverseAccessibility & accS2 + , const size_t maxInternalLoopSize1 + , const size_t maxInternalLoopSize2 + ) + : + accS1(accS1) + , accS2(accS2) + , maxInternalLoopSize1(maxInternalLoopSize1) + , maxInternalLoopSize2(maxInternalLoopSize2) + +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +InteractionEnergy::~InteractionEnergy() +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergy:: +isAllowedLoopRegion( const RnaSequence& seq, const size_t i, const size_t j, const size_t maxInternalLoopSize ) +{ + // ensure index and loop size validity + return i < seq.size() + && j < seq.size() + && seq.asString().at(i) != 'N' + && seq.asString().at(j) != 'N' + && i <= j + && (j-i) <= (1+maxInternalLoopSize); + +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergy:: +areComplementary( const size_t i1, const size_t i2 ) const +{ + return RnaSequence::areComplementary( accS1.getSequence(), accS2.getSequence(), i1, i2); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergy:: +size1() const +{ + return getAccessibility1().getSequence().size(); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergy:: +size2() const +{ + return getAccessibility2().getSequence().size(); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergy:: +isValidInternalLoop( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + return + (j1-i1>0 && j2-i2>0) + && areComplementary( i1, i2) + && areComplementary( j1, j2) + && InteractionEnergy::isAllowedLoopRegion(accS1.getSequence(), i1, j1, maxInternalLoopSize1) + && InteractionEnergy::isAllowedLoopRegion(accS2.getSequence(), i2, j2, maxInternalLoopSize2) + ; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +const Accessibility & +InteractionEnergy:: +getAccessibility1() const +{ + return accS1; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +const ReverseAccessibility & +InteractionEnergy:: +getAccessibility2() const +{ + return accS2; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergy:: +getBoltzmannWeight( const E_type e ) const +{ + // TODO can be optimized when using exp-energies from VRNA + return std::exp( - e / getRT() ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +Interaction::BasePair +InteractionEnergy:: +getBasePair( const size_t i1, const size_t i2 ) const +{ + return Interaction::BasePair( i1, getAccessibility2().getReversedIndex(i2) ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergy:: +getIndex1( const Interaction::BasePair & bp ) const +{ + return bp.first; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergy:: +getIndex2( const Interaction::BasePair & bp ) const +{ + return getAccessibility2().getReversedIndex( bp.second ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergy:: +getED1( const size_t i1, const size_t j1 ) const +{ + return getAccessibility1().getED( i1, j1 ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergy:: +getED2( const size_t i2, const size_t j2 ) const +{ + return getAccessibility2().getED( i2, j2 ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergy:: +isAccessible1( const size_t i ) const +{ + return + (!getAccessibility1().getSequence().isAmbiguous(i)) + && getAccessibility1().getAccConstraint().isAccessible(i) + ; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergy:: +isAccessible2( const size_t i ) const +{ + return + (!getAccessibility2().getSequence().isAmbiguous(i)) + && getAccessibility2().getAccConstraint().isAccessible(i); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergy:: +getPr_danglingLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + // initial probabilities + E_type probDangle1 = 1.0, probDangle2 = 1.0; + + // if dangle1 possible + if (i1>0) { + // Pr( i1-1 is unpaired | i1..j1 unpaired ) + probDangle1 = + std::max( (E_type)0.0 + , std::min( (E_type)1.0 + , getBoltzmannWeight( getED1(i1-1,j1)-getED1(i1,j1) ) + ) + ) + ; + } + // if dangle2 possible + if (i2>0) { + // Pr( i2-1 is unpaired | i2..j2 unpaired ) + probDangle2 = + std::max( (E_type)0.0 + , std::min( (E_type)1.0 + , getBoltzmannWeight( getED2(i2-1,j2)-getED2(i2,j2) ) + ) + ) + ; + } + + // get overall probability + return probDangle1 * probDangle2; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergy:: +getPr_danglingRight( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + // initial probabilities + E_type probDangle1 = 1.0, probDangle2 = 1.0; + + // if dangle1 possible + if (j1+1i1) interacting with j2 + * @param i2 the index of the second sequence (i2) interacting with j1 + * + * @return -1 or E_INF if the allowed loop size is exceeded or no valid internal loop boundaries + */ + virtual + E_type + getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + /** + * Computes the dangling end energy penalty estimate for the left side of + * an interaction loop region closed on the left by the intermolecular + * base pair (i1,i2). + * + * This penalty is always zero for this base pair based energy function. + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return 0 + */ + virtual + E_type + getE_danglingLeft( const size_t i1, const size_t i2 ) const; + + + /** + * Computes the dangling end energy penalty estimate for the right side of + * an interaction loop region closed on the right by the intermolecular + * base pair (j1,j2). + * + * @param j1 the index of the first sequence interacting with j2 + * @param j2 the index of the second sequence interacting with j1 + * + * @return the dangling end penalty for the right side of the interaction + */ + virtual + E_type + getE_danglingRight( const size_t j1, const size_t j2 ) const; + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "left side" (i1 = 5' end of seq1 of the interaction) + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return 0.0 + */ + virtual + E_type + getE_endLeft( const size_t i1, const size_t i2 ) const { + return 0.0; + } + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "right side" (j1 = 3' end of seq1 of the interaction) + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return 0.0 + */ + virtual + E_type + getE_endRight( const size_t j1, const size_t j2 ) const { + return 0.0; + } + + /** + * Returns always RT=1 due to the lack of reasonable values for this energy + * function. + * @return 1.0 + */ + virtual + E_type + getRT() const { + return 1.0; + } + + /** + * Provides the best energy gain via stacking possible for this energy + * model + * @return -1 + */ + virtual + E_type + getBestE_interLoop() const; + + /** + * Provides the best energy gain possible for left/right dangle + * for this energy model + * @return 0 + */ + virtual + E_type + getBestE_dangling() const; + + /** + * Provides the best energy gain possible for left/right interaction ends + * for this energy model + * @return 0 + */ + virtual + E_type + getBestE_end() const { + return 0; + } + +}; + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +inline +InteractionEnergyBasePair::InteractionEnergyBasePair( + const Accessibility & accS1 + , const ReverseAccessibility & accS2 + , const size_t maxInternalLoopSize1 + , const size_t maxInternalLoopSize2 + , const bool initES + ) + : + InteractionEnergy(accS1, accS2, maxInternalLoopSize1, maxInternalLoopSize2) +{ + if (initES) { + NOTIMPLEMENTED("InteractionEnergyVrna() : ES computation missing"); + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +InteractionEnergyBasePair::~InteractionEnergyBasePair() +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getES1( const size_t i1, const size_t j1 ) const +{ +#if IN_DEBUG_MODE + // sanity check + if (i1>j1) throw std::runtime_error("InteractionEnergy::getES1(i1="+toString(i1)+" > j1="+toString(j1)); + if (j1>=size1()) throw std::runtime_error("InteractionEnergy::getES1() : j1="+toString(j1)+" >= size1()="+toString(size1())); +#endif + + NOTIMPLEMENTED("InteractionEnergyVrna::getES2() : ES computation missing"); + // return computed value + return E_INF; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getES2( const size_t i2, const size_t j2 ) const +{ +#if IN_DEBUG_MODE + // sanity check + if (i2>j2) throw std::runtime_error("InteractionEnergy::getES2(i2="+toString(i2)+" > j2="+toString(j2)); + if (j2>=size2()) throw std::runtime_error("InteractionEnergy::getES2() : j2="+toString(j2)+" >= size2()="+toString(size2())); +#endif + + NOTIMPLEMENTED("InteractionEnergyVrna::getES2() : ES computation missing"); + // return computed value + return E_INF; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getEU( const size_t numUnpaired ) const +{ + return 0.0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getE_init() const +{ + return -1.0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + // if valid internal loop + if ( isValidInternalLoop(i1,j1,i2,j2) ) { + // return negated number of gained base pairs by closing this loop = -1 + return getBestE_interLoop(); + } else { + return E_INF; + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getE_danglingLeft( const size_t i1, const size_t i2 ) const +{ + // no dangling end contribution + return (E_type)0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getE_danglingRight( const size_t j1, const size_t j2 ) const +{ + // no dangling end contribution + return (E_type)0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getBestE_interLoop() const +{ + return getE_init(); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyBasePair:: +getBestE_dangling() const +{ + return (E_type)0.0; +} + +//////////////////////////////////////////////////////////////////////////// + + +#endif /* INTERACTIONENERGYBASEPAIR_H_ */ diff --git a/src/InteractionEnergyIdxOffset.cpp b/src/InteractionEnergyIdxOffset.cpp new file mode 100644 index 00000000..01d8f64b --- /dev/null +++ b/src/InteractionEnergyIdxOffset.cpp @@ -0,0 +1,4 @@ + +#include "InteractionEnergyIdxOffset.h" + + diff --git a/src/InteractionEnergyIdxOffset.h b/src/InteractionEnergyIdxOffset.h new file mode 100644 index 00000000..7f4e18e9 --- /dev/null +++ b/src/InteractionEnergyIdxOffset.h @@ -0,0 +1,747 @@ + +#ifndef INTERACTIONENERGYIDXOFFSET_H_ +#define INTERACTIONENERGYIDXOFFSET_H_ + +#include "InteractionEnergy.h" + +/** + * Wrapper for a given InteractionEnergy object where indices are shifted by + * a given positive offset (shifted towards infinity). + * This is useful for local interaction computations. + * + * @author Martin Mann + * + */ +class InteractionEnergyIdxOffset : public InteractionEnergy +{ +public: + + /** + * construction + * + * @param energyOriginal wrapped energy object used for computations + * @param offset1 the index offset for sequence 1 + * @param offset2 the index offset for sequence 2 + */ + InteractionEnergyIdxOffset( const InteractionEnergy & energyOriginal + , const size_t offset1 = 0 + , const size_t offset2 = 0 ); + + + virtual ~InteractionEnergyIdxOffset(); + + /** + * Access to the currently used index offset for sequence 1 + * @return the index offset for sequence 1 used + */ + size_t getOffset1() const; + + /** + * Sets the index offset to be used for sequence 1 + * @param offset1 the index offset for sequence 1 to be used + */ + void setOffset1(size_t offset1); + + /** + * Access to the currently used index offset for sequence 2 + * @return the index offset for sequence 2 used + */ + size_t getOffset2() const; + + /** + * Sets the index offset to be used for sequence 2 + * @param offset1 the index offset for sequence 2 to be used + */ + void setOffset2(size_t offset2); + + + /////////////// OVERWRITTEN MEMBERS USING OFFSET ///////////////// + + /** + * Provides the ED penalty for making a region with sequence 1 accessible + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the start of the accessible region + * @param j1 the end of the accessible region + * @return the ED value for [i1,j1] + */ + virtual + E_type + getED1( const size_t i1, const size_t j1 ) const; + + /** + * Provides the ED penalty for making a region with (the reversed) + * sequence 2 accessible + * + * Note, the indices are shifted by an offset for computation. + * + * @param i2 the start of the accessible region + * @param j2 the end of the accessible region + * @return the ED value for [i2,j2] + */ + virtual + E_type + getED2( const size_t i2, const size_t j2 ) const; + + /** + * Whether or not position i is accessible for interaction in sequence 1 + * + * Note, the index is shifted by an offset for computation. + * + * @param i the position of interest in sequence 1 + * @return true if the position can partake in an interaction; false otherwise + */ + virtual + bool + isAccessible1( const size_t i ) const; + + /** + * Whether or not position i is accessible for interaction in sequence 2 + * + * Note, the index is shifted by an offset for computation. + * + * @param i the position of interest in sequence 2 + * @return true if the position can partake in an interaction; false otherwise + */ + virtual + bool + isAccessible2( const size_t i ) const; + + /** + * Checks whether or not two positions (shifted by offset) can form a base pair + * @param i1 index in first sequence + * @param i2 index in second sequence + * @return true if seq1(i1) can form a base pair with seq2(i2) + */ + virtual + bool + areComplementary( const size_t i1, const size_t i2 ) const; + + + /** + * Length of sequence 1 excluding the index offset + * @return length of sequence 1 excluding index offset + */ + virtual + size_t + size1() const; + + /** + * Length of sequence 2 excluding index offset + * @return length of sequence 2 excluding index offset + */ + virtual + size_t + size2() const; + + /** + * Provides the ensemble energy (ES) of all intramolecular substructures + * that can be formed within a given region of sequence 1 under the + * assumption that the region is part of an (intermolecular) multiloop, + * i.e. at least one base pair is formed by each substructure. + * + * If no structure can be formed within the region, E_INF is returned. + * + * @param i1 the start of the structured region of seq1 + * @param j1 the end of the structured region of seq1 + * @return the ES value for [i1,j1] or E_INF if no intramolecular + * structure can be formed + */ + virtual + E_type + getES1( const size_t i1, const size_t j1 ) const; + + /** + * Provides the ensemble energy (ES) of all intramolecular substructures + * that can be formed within a given region of sequence 2 under the + * assumption that the region is part of an (intermolecular) multiloop, + * i.e. at least one base pair is formed by each substructure. + * + * If no structure can be formed within the region, E_INF is returned. + * + * @param i2 the start of the structured region of seq2 + * @param j2 the end of the structured region of seq2 + * @return the ES value for [i2,j2] or E_INF if no intramolecular + * structure can be formed + */ + virtual + E_type + getES2( const size_t i2, const size_t j2 ) const; + + /** + * Provides the energy contribution for a given number of unpaired + * nucleotides under the + * assumption that the region is part of an (intermolecular) multiloop. + * + * @param numUnpaired the number of unpaired bases + * @return the energy contribution of the given number of unpaired bases + * within an intramolecular multiloop + */ + virtual + E_type + getEU( const size_t numUnpaired ) const; + + /** + * Provides the duplex initiation energy. + * + * @return the energy for duplex initiation + */ + virtual + E_type + getE_init( ) const; + + + /** + * Computes the energy estimate for the 'left side' interaction loop region + * closed by the intermolecular base pairs (i1,i2) and enclosing (j1,j2) + * where the regions [i1,j1] and [i2,j2] are considered unpaired or E_INF + * is the internal loop size exceeds the allowed maximum (see constructor). + * + * Note, the indices are shifted by an offset for computation. + * + * Note, the right interaction base pair (j1,j2) is not included in the + * returned energy value. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return the energy for the loop + * or E_INF if the allowed loop size is exceeded or no valid internal loop boundaries + */ + virtual + E_type + getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + + /** + * Computes the dangling end energy penalties for the left side + * (i1-1 and i2-1) of the interaction closed by the intermolecular + * base pair (i1,i2). + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the dangling end penalty for the left side of the interaction + */ + virtual + E_type + getE_danglingLeft( const size_t i1, const size_t i2 ) const; + + + /** + * Computes the dangling end energy penalties for the right side + * (j1+1 and j2+1) of the interaction closed by the intermolecular + * base pair (j1,j2). + * + * Note, the indices are shifted by an offset for computation. + * + * @param j1 the index of the first sequence interacting with j2 + * @param j2 the index of the second sequence interacting with j1 + * + * @return the dangling end penalty for the right side of the interaction + */ + virtual + E_type + getE_danglingRight( const size_t j1, const size_t j2 ) const; + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "left side" (i1 = 5' end of seq1 of the interaction) + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the loop closure penalty for the left side of the interaction + */ + virtual + E_type + getE_endLeft( const size_t i1, const size_t i2 ) const; + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "right side" (j1 = 3' end of seq1 of the interaction) + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the loop closure penalty for the right side of the interaction + */ + virtual + E_type + getE_endRight( const size_t j1, const size_t j2 ) const; + + /** + * Computes the probability of the dangling ends for the left side + * (i1-1 and i2-1) of the interaction closed by the intermolecular + * base pair (i1,i2) for an interaction of [i1,j1] with [i2,j2]. + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return the dangling end probability for the left side of the interaction + */ + virtual + E_type + getPr_danglingLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + /** + * Computes the probability of the dangling ends for the right side + * (j1+1 and j2+1) of the interaction closed by the intermolecular + * base pair (j1,j2) for an interaction of [i1,j1] with [i2,j2]. + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 with i1<=j1 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 with i2<=j2 + * + * @return the dangling end probability for the right side of the interaction + */ + virtual + E_type + getPr_danglingRight( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + + /** + * Provides the base pair encoding for the given indices after shifting by + * the used offset + * @param i1 the index in the first sequence + * @param i2 the index in the (reversed) second sequence + * @return the according base pair (i1+offset1,reverseIdx(i2+offset2)) + */ + virtual + Interaction::BasePair + getBasePair( const size_t i1, const size_t i2 ) const; + + + /** + * Provides the index within the first sequence of the given base pair + * shifted by the offset. + * @return the shifted index of the first sequence within the base pair encoding + */ + virtual + size_t + getIndex1( const Interaction::BasePair & bp ) const; + + + /** + * Provides the (reversed) index within the second sequence of the given base pair + * shifted by the offset. + * @return the shifted index of the second sequence within the base pair encoding + */ + virtual + size_t + getIndex2( const Interaction::BasePair & bp ) const; + + + /** + * Access to the normalized temperature for Boltzmann weight computation + */ + virtual + E_type + getRT() const; + + + /** + * Provides the best energy gain via stacking possible for this energy + * model + * @return the best stacking energy gain produced by getE_interLoop() + */ + virtual + E_type + getBestE_interLoop() const; + + /** + * Provides the best energy gain possible for left/right dangle + * for this energy model + * @return the best initiation energy gain produced by getE_danglingLeft() or + * getE_danglingRight() + */ + virtual + E_type + getBestE_dangling() const; + + /** + * Provides the best energy gain possible for left/right interaction ends + * for this energy model + * @return the best end energy gain produced by getE_endLeft() or + * getE_endRight() + */ + virtual + E_type + getBestE_end() const; + +protected: + + /** the wrapped energy computation handler */ + const InteractionEnergy & energyOriginal; + + /** the index offset in sequence 1 */ + size_t offset1; + + /** the index offset in sequence 2 */ + size_t offset2; + +}; + + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + + +inline +InteractionEnergyIdxOffset:: +InteractionEnergyIdxOffset( const InteractionEnergy & energyOriginal + , const size_t offset1 + , const size_t offset2 ) + + : + InteractionEnergy( energyOriginal ) + , energyOriginal(energyOriginal) + , offset1(offset1) + , offset2(offset2) +{ +#if IN_DEBUG_MODE + // input sanity checks + setOffset1(offset1); + setOffset2(offset2); +#endif +} + +////////////////////////////////////////////////////////////////////////// + +inline +InteractionEnergyIdxOffset::~InteractionEnergyIdxOffset() +{ +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergyIdxOffset:: +getOffset1() const +{ + return offset1; +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +InteractionEnergyIdxOffset:: +setOffset1(size_t offset1) +{ +#if IN_DEBUG_MODE + if (offset1 >= energyOriginal.size1()) { + throw std::runtime_error("InteractionEnergyIdxOffset : offset1 "+toString(offset1) + +" > seq1.length "+toString(energyOriginal.size1())); + } +#endif + this->offset1 = offset1; +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergyIdxOffset:: +getOffset2() const +{ + return offset2; +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +InteractionEnergyIdxOffset:: +setOffset2(size_t offset2) +{ +#if IN_DEBUG_MODE + if (offset2 >= energyOriginal.size2()) { + throw std::runtime_error("InteractionEnergyIdxOffset : offset2 "+toString(offset2) + +" > seq2.length "+toString(energyOriginal.size2())); + } +#endif + this->offset2 = offset2; +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getED1( const size_t i1, const size_t j1 ) const +{ + return energyOriginal.getED1( i1+offset1, j1+offset1 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getED2( const size_t i2, const size_t j2 ) const +{ + return energyOriginal.getED2( i2+offset2, j2+offset2 ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergyIdxOffset:: +isAccessible1( const size_t i ) const +{ + return energyOriginal.isAccessible1(i+offset1); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergyIdxOffset:: +isAccessible2( const size_t i ) const +{ + return energyOriginal.isAccessible2(i+offset2); +} + +////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergyIdxOffset:: +areComplementary( const size_t i1, const size_t i2 ) const +{ + return energyOriginal.areComplementary( i1+offset1, i2+offset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergyIdxOffset:: +size1() const +{ + return energyOriginal.size1()-offset1; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergyIdxOffset:: +size2() const +{ + return energyOriginal.size2()-offset2; +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getES1( const size_t i1, const size_t j1 ) const +{ + return energyOriginal.getES1( i1+offset1, j1+offset1 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getES2( const size_t i2, const size_t j2 ) const +{ + return energyOriginal.getES2( i2+offset2, j2+offset2 ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getEU( const size_t numUnpaired ) const +{ + return energyOriginal.getEU( numUnpaired ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getE_init( ) const +{ + return energyOriginal.getE_init(); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + return energyOriginal.getE_interLeft(i1+offset1, j1+offset1, i2+offset2, j2+offset2); +} + + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getE_danglingLeft( const size_t i1, const size_t i2 ) const +{ + return energyOriginal.getE_danglingLeft( i1+offset1, i2+offset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getE_danglingRight( const size_t j1, const size_t j2 ) const +{ + return energyOriginal.getE_danglingRight( j1+offset1, j2+offset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getE_endLeft( const size_t i1, const size_t i2 ) const +{ + return energyOriginal.getE_endLeft( i1+offset1, i2+offset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getE_endRight( const size_t j1, const size_t j2 ) const +{ + return energyOriginal.getE_endRight( j1+offset1, j2+offset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getPr_danglingLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + return energyOriginal.getPr_danglingLeft(i1+offset1, j1+offset1, i2+offset2, j2+offset2); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyIdxOffset:: +getPr_danglingRight( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + return energyOriginal.getPr_danglingRight(i1+offset1, j1+offset1, i2+offset2, j2+offset2); +} + +////////////////////////////////////////////////////////////////////////// + +inline +Interaction::BasePair +InteractionEnergyIdxOffset:: +getBasePair( const size_t i1, const size_t i2 ) const +{ + return energyOriginal.getBasePair( i1+offset1, i2+offset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +InteractionEnergyIdxOffset:: +getIndex1( const Interaction::BasePair & bp ) const +{ +#if IN_DEBUG_MODE + if (energyOriginal.getIndex1(bp) +#include + +// ES computation +extern "C" { + #include + #include + #include + #include + #include +} + + +//////////////////////////////////////////////////////////////////////////// + +InteractionEnergyVrna::InteractionEnergyVrna( + const Accessibility & accS1 + , const ReverseAccessibility & accS2 + , VrnaHandler &vrnaHandler + , const size_t maxInternalLoopSize1 + , const size_t maxInternalLoopSize2 + , const bool initES + ) + : + InteractionEnergy(accS1, accS2, maxInternalLoopSize1, maxInternalLoopSize2) +// get final VRNA folding parameters + , foldModel( vrnaHandler.getModel() ) + , foldParams( vrna_params( &foldModel ) ) + , RT(vrnaHandler.getRT()) + , bpCG( BP_pair[RnaSequence::getCodeForChar('C')][RnaSequence::getCodeForChar('G')] ) + , bpGC( BP_pair[RnaSequence::getCodeForChar('G')][RnaSequence::getCodeForChar('C')] ) + , esValues1(NULL) + , esValues2(NULL) +{ + vrna_md_defaults_reset( &foldModel ); + + // init ES values if needed + if (initES) { + // VRNA computation not completely threadsafe +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_callingVRNA) +#endif + { + // create ES container to be filled + esValues1 = new EsMatrix(); + esValues2 = new EsMatrix(); + // fill ES container + computeES( accS1, *esValues1 ); + computeES( accS2, *esValues2 ); + } // omp critical(intarna_omp_callingVRNA) + } +} + +//////////////////////////////////////////////////////////////////////////// + +InteractionEnergyVrna::~InteractionEnergyVrna() +{ + // garbage collection + if (foldParams != NULL) { + free(foldParams); + foldParams = NULL; + } + CLEANUP(esValues1); + CLEANUP(esValues2); + +} + + +//////////////////////////////////////////////////////////////////////////// + +E_type +InteractionEnergyVrna:: +getBestE_interLoop() const +{ + // TODO maybe setup member variable (init=E_INF) with lazy initialization + + // get all possible base pair codes handled + std::set basePairCodes; + for (int i=0; i::const_iterator p1=basePairCodes.begin(); p1!=basePairCodes.end(); p1++) { + for (std::set::const_iterator p2=basePairCodes.begin(); p2!=basePairCodes.end(); p2++) { + minStackingE = std::min( minStackingE + , (E_type)E_IntLoop( 0 // unpaired region 1 + , 0 // unpaired region 2 + , *p1 // type BP (i1,i2) + , *p2 // type BP (j2,j1) + , 0 + , 0 + , 0 + , 0 + , foldParams) + // correct from dcal/mol to kcal/mol + / (E_type)100.0 + ); + } + } + + return minStackingE; +} + + +//////////////////////////////////////////////////////////////////////////// + +E_type +InteractionEnergyVrna:: +getBestE_dangling() const +{ + // TODO maybe setup member variable (init=E_INF) with lazy initialization + + // get all possible base pair codes handled + std::set basePairCodes; + for (int i=0; i::infinity(); + + // get codes for the sequence alphabet + const RnaSequence::CodeSeq_type alphabet = RnaSequence::getCodeForString(RnaSequence::SequenceAlphabet); + + // get minimal + for (std::set::const_iterator p1=basePairCodes.begin(); p1!=basePairCodes.end(); p1++) { + for (size_t i=0; iexp_matrices == NULL) { + throw std::runtime_error("AccessibilityVrna::computeES() : partition functions after computation not available"); + } + if (foldData->exp_matrices->qm == NULL) { + throw std::runtime_error("AccessibilityVrna::computeES() : partition functions Qm after computation not available"); + } + // copy ensemble energies of multi loop parts = ES values + FLT_OR_DBL qm_val = 0.0; + const int minLoopSubseqLength = foldModel.min_loop_size + 2; + for (int i=0; iexp_matrices->qm[foldData->iindx[i+1]-j+1]; + if ( E_equal(qm_val, 0.) ) { + esValues(i,j) = E_INF; + } else { + // ES energy = -RT*log( Qm ) + esValues(i,j) = (E_type)( - RT*( std::log(qm_val) + +((FLT_OR_DBL)(j-i+1))*std::log(foldData->exp_params->pf_scale))); + } + } + } + } + // garbage collection + vrna_fold_compound_free(foldData); + free(structureConstraint); + free(sequence); + +} + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/InteractionEnergyVrna.h b/src/InteractionEnergyVrna.h new file mode 100644 index 00000000..3e85eae7 --- /dev/null +++ b/src/InteractionEnergyVrna.h @@ -0,0 +1,471 @@ + +#ifndef INTERACTIONENERGYVIENNA_H_ +#define INTERACTIONENERGYVIENNA_H_ + +#include "InteractionEnergy.h" +#include "VrnaHandler.h" + +extern "C" { + #include + #include + #include + #include + #include +} +#ifndef VIENNA_RNA_PAIR_MAT_H +#define VIENNA_RNA_PAIR_MAT_H +extern "C" { + #include "ViennaRNA/pair_mat.h" +} +#endif + +#include + + +// http://www.tbi.univie.ac.at/RNA/ViennaRNA/doc/RNAlib-2.3.0.pdf + +/** + * Implements an energy interface based on free energy estimates computed + * with the Vienna RNA package. + * + * @author Martin Mann 2014 + */ +class InteractionEnergyVrna: public InteractionEnergy { + +public: + + /** + * Construct energy utility object given the accessibility ED values for + * two sequences. + * + * @param accS1 accessibility of the first sequence + * @param accS2 accessibility of the second sequence + * @param vrnaHandler the VRNA parameter handler to be used + * @param maxInternalLoopSize1 maximal number of enclosed unpaired positions + * between two intermolecular base pairs in sequence 1, ie it holds + * for an intermolecular loop closed by base pairs (i1,i2) and + * (j1,j2) : (j1-i1+1) <= maxInternalLoopSize + * @param maxInternalLoopSize2 maximal number of enclosed unpaired positions + * between two intermolecular base pairs in sequence 2, ie it holds + * for an intermolecular loop closed by base pairs (i1,i2) and + * (j1,j2) : (j2-i2+1) <= maxInternalLoopSize + * @param initES whether or not ES values are to be computed + * + */ + InteractionEnergyVrna( const Accessibility & accS1 + , const ReverseAccessibility & accS2 + , VrnaHandler &vrnaHandler + , const size_t maxInternalLoopSize1 = 16 + , const size_t maxInternalLoopSize2 = 16 + , const bool initES = false + ); + + virtual ~InteractionEnergyVrna(); + + + /** + * Provides the ensemble energy (ES) of all intramolecular substructures + * that can be formed within a given region of sequence 1 under the + * assumption that the region is part of an (intermolecular) multiloop, + * i.e. at least one base pair is formed by each substructure. + * + * If no structure can be formed within the region, E_INF is returned. + * + * @param i1 the start of the structured region of seq1 + * @param j1 the end of the structured region of seq1 + * @return the ES value for [i1,j1] or E_INF if no intramolecular + * structure can be formed + */ + virtual + E_type + getES1( const size_t i1, const size_t j1 ) const; + + /** + * Provides the ensemble energy (ES) of all intramolecular substructures + * that can be formed within a given region of sequence 2 under the + * assumption that the region is part of an (intermolecular) multiloop, + * i.e. at least one base pair is formed by each substructure. + * + * If no structure can be formed within the region, E_INF is returned. + * + * @param i2 the start of the structured region of seq2 + * @param j2 the end of the structured region of seq2 + * @return the ES value for [i2,j2] or E_INF if no intramolecular + * structure can be formed + */ + virtual + E_type + getES2( const size_t i2, const size_t j2 ) const; + + /** + * Provides the energy contribution for a given number of unpaired + * nucleotides under the + * assumption that the region is part of an (intermolecular) multiloop. + * + * @param numUnpaired the number of unpaired bases + * @return the energy contribution of the given number of unpaired bases + * within an intramolecular multiloop + */ + virtual + E_type + getEU( const size_t numUnpaired ) const; + + /** + * Provides the duplex initiation energy. + * + * @return the energy for duplex initiation + */ + virtual + E_type + getE_init() const; + + /** + * Computes the energy estimate for the interaction loop region closed by + * the intermolecular base pairs (i1,i2) and (j1,j2) where the regions + * [i1,j1] and [i2,j2] are considered unpaired. + * The energy estimate is derived via the Vienna RNA package loop energies + * or is E_INF if the internal loop size exceeds + * the allowed maximum (see constructor). + * + * @param i1 the index of the first sequence (i1) interacting with j2 + * @param i2 the index of the second sequence (i2) interacting with j1 + * + * @return energy in kcal/mol for the loop closed by (i1,i2) + * or + * E_INF if the allowed loop size is exceeded or no valid internal loop boundaries + */ + virtual + E_type + getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const; + + + /** + * Computes the dangling end energy penalties for the left side + * (i1-1 and i2-1) of the interaction closed by the intermolecular + * base pair (i1,i2). + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the dangling end penalty for the left side of the interaction + */ + virtual + E_type + getE_danglingLeft( const size_t i1, const size_t i2 ) const; + + + /** + * Computes the dangling end energy penalties for the right side + * (j1+1 and j2+1) of the interaction closed by the intermolecular + * base pair (j1,j2). + * + * @param j1 the index of the first sequence interacting with j2 + * @param j2 the index of the second sequence interacting with j1 + * + * @return the dangling end penalty for the right side of the interaction + */ + virtual + E_type + getE_danglingRight( const size_t j1, const size_t j2 ) const; + + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "left side" (i1 = 5' end of seq1 of the interaction) + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the loop closure penalty for the left side of the interaction + */ + virtual + E_type + getE_endLeft( const size_t i1, const size_t i2 ) const; + + /** + * Provides the penalty for closing an interaction with the given + * base pair on the "right side" (j1 = 3' end of seq1 of the interaction) + * + * @param i1 the index of the first sequence interacting with i2 + * @param i2 the index of the second sequence interacting with i1 + * + * @return the loop closure penalty for the right side of the interaction + */ + virtual + E_type + getE_endRight( const size_t j1, const size_t j2 ) const; + + + /** + * Returns the normalized energy in mol/kcal unit + * @return R*temperature + */ + virtual + E_type + getRT() const; + + /** + * Provides the minimal energy gain via stacking possible for this energy + * model + * @return the minimal energy possible for any stacking combination + */ + virtual + E_type + getBestE_interLoop() const; + + /** + * Provides the minimal energy gain possible for left/right dangling ends + * for this energy model + * @return the best initiation energy gain produced by getDanglingLef() or + * getE_danglingRight() + */ + virtual + E_type + getBestE_dangling() const; + + /** + * Provides the best energy gain possible for left/right interaction ends + * for this energy model + * @return the best end energy gain produced by getE_endLeft() or + * getE_endRight() + */ + virtual + E_type + getBestE_end() const; + +protected: + + + //! Vienna RNA package : folding model to be used for the energy computation + vrna_md_t foldModel; + + //! Vienna RNA package : folding parameters to be used for the energy + //! computation + vrna_param_t * foldParams; + + //! the RT constant to be used for Boltzmann weight computations + E_type RT; + + //! base pair code for (C,G) + const int bpCG; + + //! base pair code for (G,C) + const int bpGC; + + //! matrix to store ES values (upper triangular matrix) + typedef boost::numeric::ublas::triangular_matrix EsMatrix; + + //! the ES values for seq1 if computed (otherwise NULL) + EsMatrix * esValues1; + + //! the ES values for seq2 if computed (otherwise NULL) + EsMatrix * esValues2; + + /** + * Checks whether or not a given base pair is a GC base pair + * @param i1 the index in the first sequence + * @param i2 the index in the second sequence + * @return true if (seq1(i1),seq2(i2)) is (G,C) or (C,G) + */ + bool + isGC( const size_t i1, const size_t i2 ) const; + + /** + * Computes the ES values and fills esValues container + * @param acc the accessibility object for the sequence to compute the ES values for + * @param esToFill the container to write the ES values to + */ + void + computeES( const Accessibility & acc, EsMatrix & esToFill ); + +}; + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getE_init() const +{ + // init term is sequence independent + return (E_type)foldParams->DuplexInit/(E_type)100.0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getE_endLeft( const size_t i1, const size_t i2 ) const +{ + // VRNA non-GC penalty + return isGC(i1,i2) ? 0.0 : (E_type)foldParams->TerminalAU/(E_type)100.0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getE_endRight( const size_t j1, const size_t j2 ) const +{ + // VRNA non-GC penalty + return isGC(j1,j2) ? 0.0 : (E_type)foldParams->TerminalAU/(E_type)100.0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getRT() const +{ + return RT; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getBestE_end() const +{ + return (E_type)std::min(0,foldParams->TerminalAU)/(E_type)100.0; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getE_interLeft( const size_t i1, const size_t j1, const size_t i2, const size_t j2 ) const +{ + // if valid internal loop + if ( isValidInternalLoop(i1,j1,i2,j2) ) { + assert( i1!=j1 && i2!=j2 ); + // Vienna RNA : compute internal loop / stacking energy for base pair [i1,i2] + return (E_type)E_IntLoop( (int)j1-i1-1 // unpaired region 1 + , (int)j2-i2-1 // unpaired region 2 + , BP_pair[accS1.getSequence().asCodes().at(i1)][accS2.getSequence().asCodes().at(i2)] // type BP (i1,i2) + , BP_pair[accS2.getSequence().asCodes().at(j2)][accS1.getSequence().asCodes().at(j1)] // type BP (j2,j1) + , accS1.getSequence().asCodes().at(i1+1) + , accS2.getSequence().asCodes().at(i2+1) + , accS1.getSequence().asCodes().at(j1-1) + , accS2.getSequence().asCodes().at(j2-1) + , foldParams) + // correct from dcal/mol to kcal/mol + / (E_type)100.0 + ; + } else { + return E_INF; + } +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getE_danglingLeft( const size_t i1, const size_t i2 ) const +{ + // Vienna RNA : dangling end contribution + return (E_type) E_Stem( BP_pair[accS1.getSequence().asCodes().at(i1)][accS2.getSequence().asCodes().at(i2)] + , ( i1==0 ? -1 : accS1.getSequence().asCodes().at(i1-1) ) + , ( i2==0 ? -1 : accS2.getSequence().asCodes().at(i2-1) ) + , 1 // is an external loop + , foldParams + ) + // correct from dcal/mol to kcal/mol + /(E_type)100.0 + // substract closing penalty + - getE_endLeft(i1,i2); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getE_danglingRight( const size_t j1, const size_t j2 ) const +{ + // Vienna RNA : dangling end contribution (reverse base pair to be sequence end conform) + return (E_type) E_Stem( BP_pair[accS2.getSequence().asCodes().at(j2)][accS1.getSequence().asCodes().at(j1)] + , ( j2+1>=accS2.getSequence().size() ? -1 : accS2.getSequence().asCodes().at(j2+1) ) + , ( j1+1>=accS1.getSequence().size() ? -1 : accS1.getSequence().asCodes().at(j1+1) ) + , 1 // is an external loop + , foldParams + ) + // correct from dcal/mol to kcal/mol + /(E_type)100.0 + // substract closing penalty + - getE_endRight(j1,j2); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getES1( const size_t i1, const size_t j1 ) const +{ +#if IN_DEBUG_MODE + // sanity check + if (i1>j1) throw std::runtime_error("InteractionEnergy::getES1(i1="+toString(i1)+" > j1="+toString(j1)); + if (j1>=size1()) throw std::runtime_error("InteractionEnergy::getES1() : j1="+toString(j1)+" >= size1()="+toString(size1())); + if (esValues1 == NULL) throw std::runtime_error("InteractionEnergy::getES1() : ES values not initialized"); +#endif + + // return computed value + return (*esValues1)(i1,j1); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getES2( const size_t i2, const size_t j2 ) const +{ +#if IN_DEBUG_MODE + // sanity check + if (i2>j2) throw std::runtime_error("InteractionEnergy::getES2(i2="+toString(i2)+" > j2="+toString(j2)); + if (j2>=size2()) throw std::runtime_error("InteractionEnergy::getES2() : j2="+toString(j2)+" >= size2()="+toString(size2())); + if (esValues2 == NULL) throw std::runtime_error("InteractionEnergy::getES2() : ES values not initialized"); +#endif + + // return computed value + return (*esValues2)(i2,j2); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +bool +InteractionEnergyVrna:: +isGC( const size_t i1, const size_t i2 ) const +{ + const int bpType = BP_pair[accS1.getSequence().asCodes().at(i1)][accS2.getSequence().asCodes().at(i2)]; + return (bpType==bpCG || bpType==bpGC); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +E_type +InteractionEnergyVrna:: +getEU( const size_t numUnpaired ) const +{ + return numUnpaired * ((E_type)foldParams->MLbase) / (E_type)100.0; +} + +//////////////////////////////////////////////////////////////////////////// + + + + +#endif /* INTERACTIONENERGYVIENNA_H_ */ diff --git a/src/InteractionRange.cpp b/src/InteractionRange.cpp new file mode 100644 index 00000000..0a55b050 --- /dev/null +++ b/src/InteractionRange.cpp @@ -0,0 +1,32 @@ + +#include "Interaction.h" +#include "InteractionRange.h" + +InteractionRange & +InteractionRange:: +operator= ( const Interaction & interaction ) +{ +#if IN_DEBUG_MODE + if (interaction.isEmpty()) + throw std::runtime_error("InteractionRange::=(interaction) is empty!"); + if (!interaction.isValid()) + throw std::runtime_error("InteractionRange::=(interaction) not valid!"); +#endif + // init data + s1 = interaction.s1; + s2 = interaction.s2; + r1.from = interaction.basePairs.begin()->first; + r1.to = interaction.basePairs.rbegin()->first; + r2.from = interaction.basePairs.begin()->second; + r2.to = interaction.basePairs.rbegin()->second; + energy = interaction.energy; + +#if IN_DEBUG_MODE + if (!isSane()) + throw std::runtime_error("InteractionRange::=(interaction)="+toString(*this)+" not sane!"); +#endif + return *this; +} + + + diff --git a/src/InteractionRange.h b/src/InteractionRange.h new file mode 100644 index 00000000..dd3a88b5 --- /dev/null +++ b/src/InteractionRange.h @@ -0,0 +1,119 @@ + +#ifndef INTERACTIONRANGE_H_ +#define INTERACTIONRANGE_H_ + +#include "general.h" +#include "IndexRange.h" +#include "RnaSequence.h" + +// dummy declaration to avoid inclusion loop +class Interaction; + +/** + * Represents two ranges that form an interaction + */ +class InteractionRange { +public: + + //! the first interaction partner + const RnaSequence * s1; + + //! the second interaction partner + const RnaSequence * s2; + + //! the index range of s1 interacting with r2 + IndexRange r1; + + //! the index range of s2 interacting with r1 + IndexRange r2; + + //! the energy value associated with this interaction range + E_type energy; + +public: + + /** + * Construction of an interaction range given two index ranges + * @param rna1 the first RNA interacting + * @param rna2 the second RNA interacting + * @param r1 the range of rna1 interacting + * @param r2 the range of rna2 interacting + * + */ + InteractionRange( + const RnaSequence & rna1 + , const RnaSequence & rna2 + , const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(RnaSequence::lastPos,0) + , const E_type energy = std::numeric_limits::signaling_NaN() ) + : s1(&rna1) + , s2(&rna2) + , r1(r1.from, (r1.to > rna1.size()?rna1.size()-1:r1.to)) + , r2((r2.from > rna2.size()?rna2.size()-1:r2.from), r2.to) + , energy(energy) + { +#if IN_DEBUG_MODE + if (!isSane()) + throw std::runtime_error("InteractionRange("+toString(*this)+") not sane!"); +#endif + } + + /** + * Construction of an interaction range given two index ranges + */ + InteractionRange( const Interaction& interaction ) + : s1(NULL), s2(NULL), r1(), r2(), energy(std::numeric_limits::signaling_NaN()) + { + // copy data + this->operator =(interaction); + } + + /** + * Destruction + */ + virtual ~InteractionRange() + {} + + + /** + * Checks whether or not the range encoding is reasonable. + * @return from <= to + */ + bool isSane() const + { + // range of first sequence ascending + // range of second sequence descending + return r1.isAscending() && r2.isDescending(); + } + + /** + * Prints the range's boundaries to stream + * @param out the ostream to write to + * @param r the InteractionRange object to add + * @return the altered stream out + */ + friend std::ostream& operator<<(std::ostream& out, const InteractionRange& r) + { + return (out <<"("<r.r1) && r2= 0.0"); +} + +///////////////////////////////////////////////////////////////////////////// + +OutputConstraint::~OutputConstraint() +{ +} + +///////////////////////////////////////////////////////////////////////////// + diff --git a/src/OutputConstraint.h b/src/OutputConstraint.h new file mode 100644 index 00000000..f400085a --- /dev/null +++ b/src/OutputConstraint.h @@ -0,0 +1,65 @@ + +#ifndef OUTPUTCONSTRAINT_H_ +#define OUTPUTCONSTRAINT_H_ + +#include "general.h" + +/** + * + * Data structure that contains all constraints to be applied to (suboptimal) + * output generation. + * + * @author Martin Mann + * + */ +class OutputConstraint +{ + +public: + + //! different possibilities to en-/disable overlapping of interaction sites + //! if suboptimal solutions are enumerated + enum ReportOverlap { + OVERLAP_NONE = 0, + OVERLAP_SEQ1 = 1, + OVERLAP_SEQ2 = 2, + OVERLAP_BOTH = 3 + }; + + +public: + + //! the maximal number of (sub)optimal interactions to be reported to the output handler + const size_t reportMax; + + //! defines whether and where overlapping interaction sites are allowed for reporting + const ReportOverlap reportOverlap; + + //! the maximal energy of a reported interaction (<= 0.0) + const E_type maxE; + + //! the maximal energy difference to the mfe of a reported interaction + const E_type deltaE; + +public: + + /** + * Construction of an output constraint + * + * @param reportMax the maximal number of (sub)optimal interactions to be + * reported to the output handler + * @param reportOverlap defines whether and where overlapping interaction + * sites are allowed for reporting + * @param maxE maximal energy of a reported interaction (<= 0.0) + * @param deltaE maximal energy difference of a reported interaction to mfe + */ + OutputConstraint( const size_t reportMax = 1 + , const ReportOverlap reportOverlap = OVERLAP_BOTH + , const E_type maxE = 0.0 + , const E_type deltaE = E_INF ); + + //! destruction + virtual ~OutputConstraint(); +}; + +#endif /* OUTPUTCONSTRAINT_H_ */ diff --git a/src/OutputHandler.cpp b/src/OutputHandler.cpp new file mode 100644 index 00000000..8810b99e --- /dev/null +++ b/src/OutputHandler.cpp @@ -0,0 +1,10 @@ + +#include "OutputHandler.h" + + + + +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/OutputHandler.h b/src/OutputHandler.h new file mode 100644 index 00000000..9a7745b5 --- /dev/null +++ b/src/OutputHandler.h @@ -0,0 +1,124 @@ + +#ifndef OUTPUTHANDLER_H_ +#define OUTPUTHANDLER_H_ + +#include "general.h" +#include "Interaction.h" +#include "InteractionRange.h" +#include + +/** + * Defines an output and storage interface to enable different output formats + * for all predicted RNA-RNA interactions. + * + * @author Martin Mann 2014 + * + */ +class OutputHandler { + +public: + + /** + * Construction + */ + OutputHandler(); + + /** + * Destruction + */ + virtual ~OutputHandler(); + + + /** + * Adds a given RNA-RNA interaction to the storage/output. + * + * NOTE: the given interaction object and its source object might be deleted + * later on. Thus, a deep copy is needed in order to make them completely + * independent. + * + * @param interaction the interaction to add + */ + virtual + void + add( const Interaction & interaction ) = 0; + + /** + * Adds a given RNA-RNA interaction range to the storage/output. + * + * NOTE: the given interaction object and its source object might be deleted + * later on. Thus, a deep copy is needed in order to make them completely + * independent. + * + * @param range the interaction range to add + */ + virtual + void + add( const InteractionRange & range ) = 0; + + /** + * Returns the number of reported interactions. + * @return the number of reported interactions + */ + virtual + size_t + reported() const; + + + /** + * returns the reversed string + * @param str the string to reverse + * @return the reversed string + */ + static + std::string + reverse( const std::string & str ); + + +protected: + + //! number of reported interactions + size_t reportedInteractions; + +}; + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +inline +OutputHandler::OutputHandler() + : reportedInteractions(0) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +OutputHandler::~OutputHandler() { +} + +//////////////////////////////////////////////////////////////////////////// + +inline +std::string +OutputHandler:: +reverse( const std::string & str ) +{ + return std::string(str.rbegin(), str.rend()); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +OutputHandler:: +reported() const +{ + return reportedInteractions; +} + +//////////////////////////////////////////////////////////////////////////// + + +#endif /* OUTPUTHANDLER_H_ */ diff --git a/src/OutputHandlerCsv.cpp b/src/OutputHandlerCsv.cpp new file mode 100644 index 00000000..df85b4bd --- /dev/null +++ b/src/OutputHandlerCsv.cpp @@ -0,0 +1,282 @@ + +#include "OutputHandlerCsv.h" + +#if INTARNA_MULITHREADING + #include +#endif + +#include + + +//////////////////////////////////////////////////////////////////////// + +std::map OutputHandlerCsv::colType2string; + +//////////////////////////////////////////////////////////////////////// + +OutputHandlerCsv::OutputHandlerCsv( + std::ostream & out + , const InteractionEnergy & energy + , const ColTypeList colOrder + , const std::string& colSep + , const bool printHeader + ) + : out(out) + , energy(energy) + , colOrder(colOrder) + , colSep(colSep) +{ + // init mapping of coltypes to string + initColType2string(); + + // print CSV header of column names + if (printHeader) { + // ensure outputs do not intervene +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_outputStreamUpdate) +#endif + { + out < 0 && ! i.isValid() ) { + throw std::runtime_error("OutputHandlerCsv::add() : given interaction is not valid : "+toString(i)); + } +#endif + + // special handling if no base pairs present + if (i.basePairs.size() == 0) { + return; + } + + // get interaction start/end per sequence + const size_t i1 = i.basePairs.begin()->first; + const size_t j1 = i.basePairs.rbegin()->first; + const size_t i2 = i.basePairs.begin()->second; + const size_t j2 = i.basePairs.rbegin()->second; + + // get individual energy contributions + InteractionEnergy::EnergyContributions contr = energy.getE_contributions(i); + + // ensure outputs do not intervene +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_outputStreamUpdate) +#endif + { + + for (auto col = colOrder.begin(); col != colOrder.end(); col++) { + // print separator if needed + if (col != colOrder.begin()) { + out <::signaling_NaN(); + } else { + out <<(i.seedRange->r1.from+1); + } + break; + + case seedEnd1: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <<(i.seedRange->r1.to+1); + } + break; + + case seedStart2: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <<(i.seedRange->r2.to+1); + } + break; + + case seedEnd2: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <<(i.seedRange->r2.from+1); + } + break; + + case seedE: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <energy; + } + break; + + case seedED1: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <r1.from, i.seedRange->r1.to ); + } + break; + + case seedED2: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <r2.to, i.seedRange->r2.from ); + } + break; + + case seedPu1: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <r1.from, i.seedRange->r1.to ) / energy.getRT() ); + } + break; + + case seedPu2: + if (i.seedRange == NULL) { + out <::signaling_NaN(); + } else { + out <r2.to, i.seedRange->r2.from ) / energy.getRT() ); + } + break; + + default : throw std::runtime_error("OutputHandlerCsv::add() : unhandled ColType '"+colType2string[*col]+"'"); + } + } + out <<'\n'; + } // omp critical(intarna_omp_outputStreamUpdate) + +} + +//////////////////////////////////////////////////////////////////////// + diff --git a/src/OutputHandlerCsv.h b/src/OutputHandlerCsv.h new file mode 100644 index 00000000..06a5a2ba --- /dev/null +++ b/src/OutputHandlerCsv.h @@ -0,0 +1,335 @@ + +#ifndef OUTPUTHANDLERCSV_H_ +#define OUTPUTHANDLERCSV_H_ + +#include "general.h" + +#include "OutputHandler.h" +#include "InteractionEnergy.h" + +#include +#include + +#include + +/** + * OutputHandler that stores interactions in CSV stream output. + */ +class OutputHandlerCsv : public OutputHandler +{ + +public: + + //! the column types supported + enum ColType { + id1 = 0, //!< id of first sequence + id2, //!< id of second sequence + seq1, //!< full first sequence + seq2, //!< full second sequence + subseq1, //!< interacting subsequence of first sequence + subseq2, //!< interacting subsequence of second sequence + subseqDP, //!< hybrid subsequences compatible with hybridDP + subseqDB, //!< hybrid subsequences compatible with hybridDB + start1, //!< start index of hybrid in seq1 + end1, //!< end index of hybrid in seq1 + start2, //!< start index of hybrid in seq2 + end2, //!< end index of hybrid in seq2 + hybridDP, //!< hybrid in VRNA dot-bracket notation + hybridDB, //!< hybrid in dot-bar notation + E, //!< overall hybridization energy + ED1, //!< ED value of seq1 + ED2, //!< ED value of seq2 + Pu1, //!< probability to be accessible for seq1 + Pu2, //!< probability to be accessible for seq2 + E_init, //!< initiation energy + E_loops, //!< sum of loop energies (excluding E_init) + E_dangleL, //!< dangling end contribution of base pair (start1,end2) + E_dangleR, //!< dangling end contribution of base pair (end1,start2) + E_endL, //!< penalty of closing base pair (start1,end2) + E_endR, //!< penalty of closing base pair (end1,start2) + seedStart1, //!< start index of the seed in seq1 + seedEnd1, //!< end index of the seed in seq1 + seedStart2, //!< start index of the seed in seq2 + seedEnd2, //!< end index of the seed in seq2 + seedE, //!< overall hybridization energy of the seed only (excluding rest) + seedED1, //!< ED value of seq1 of the seed only (excluding rest) + seedED2, //!< ED value of seq2 of the seed only (excluding rest) + seedPu1, //!< probability of seed region to be accessible for seq1 + seedPu2, //!< probability of seed region to be accessible for seq2 + ColTypeNumber //!< number of column types + }; + + //! list of ColTypes + typedef std::list ColTypeList; + + /** + * Access to the mapping of ColTypes to according strings + */ + static + const std::map & + getColType2string(); + +protected: + + //! mapping of ColTypes to according strings + static std::map colType2string; + + /** + * initializes the mapping of ColType elements to respective strings + */ + static + void + initColType2string() { + if (colType2string.empty()) { + // fill container : ensure strings are non-redundant! + colType2string[id1] = "id1"; + colType2string[id2] = "id2"; + colType2string[seq1] = "seq1"; + colType2string[seq2] = "seq2"; + colType2string[start1] = "start1"; + colType2string[end1] = "end1"; + colType2string[start2] = "start2"; + colType2string[end2] = "end2"; + colType2string[subseq1] = "subseq1"; + colType2string[subseq2] = "subseq2"; + colType2string[subseqDP] = "subseqDP"; + colType2string[subseqDB] = "subseqDB"; + colType2string[hybridDP] = "hybridDP"; + colType2string[hybridDB] = "hybridDB"; + colType2string[E] = "E"; + colType2string[ED1] = "ED1"; + colType2string[ED2] = "ED2"; + colType2string[Pu1] = "Pu1"; + colType2string[Pu2] = "Pu2"; + colType2string[E_init] = "E_init"; + colType2string[E_loops] = "E_loops"; + colType2string[E_dangleL] = "E_dangleL"; + colType2string[E_dangleR] = "E_dangleR"; + colType2string[E_endL] = "E_endL"; + colType2string[E_endR] = "E_endR"; + colType2string[seedStart1] = "seedStart1"; + colType2string[seedEnd1] = "seedEnd1"; + colType2string[seedStart2] = "seedStart2"; + colType2string[seedEnd2] = "seedEnd2"; + colType2string[seedE] = "seedE"; + colType2string[seedED1] = "seedED1"; + colType2string[seedED2] = "seedED2"; + colType2string[seedPu1] = "seedPu1"; + colType2string[seedPu2] = "seedPu2"; + // ensure filling is complete + for (size_t i=0; i(i) ) == colType2string.end() ) { + throw std::runtime_error("OutputHandlerCsv::initColType2string() : ColType "+toString(i)+" without string representative"); + } + } + } + } + +public: + + /** + * Construct a CSV table output handler for interaction reporting. + * + * @param out the stream to write to + * @param energy the interaction energy object used for computation + * @param colOrder the order and list of columns to be printed + * @param colSep the column separator to be used in CSV output + * @param printHeader whether or not to print header information = col names + */ + OutputHandlerCsv( std::ostream & out + , const InteractionEnergy & energy + , const ColTypeList colOrder + , const std::string& colSep = ";" + , const bool printHeader = false + ); + + /** + * destruction + */ + virtual ~OutputHandlerCsv(); + + /** + * Write a given RNA-RNA interaction in simple text format to the output + * stream. + * + * @param interaction the interaction to output + */ + virtual + void + add( const Interaction & interaction ); + + /** + * Handles a given RNA-RNA interaction range as a + * RNA-RNA interaction with two base pairs and writes it in simple + * text format to the output stream. + * + * @param range the interaction range to add + */ + virtual + void + add( const InteractionRange & range ); + + /** + * Converts a list of Coltypes to their string representation. + * @param colTypes the list to convert + * @return the string representation of the list + */ + static + std::string + list2string( const ColTypeList & colTypes ); + + /** + * Converts string representation of a list of Coltypes to the respective + * list. + * + * @param listString the string representation of the list + * @return the parsed list + * + * @throws std::runtime_error in case of parsing problems + */ + static + ColTypeList + string2list( const std::string & listString ); + + /** + * Generates the header line for a given list of columns + * @param colTypes the list of column types to consider + * @param colSep the column separator to be used + * @return the header line of the CSV output + */ + static + std::string + getHeader( const ColTypeList & colTypes, const std::string& colSep = ";" ); + +protected: + + //! the output stream to write to + std::ostream & out; + + //! the interaction energy function used for interaction computation + const InteractionEnergy & energy; + + //! the sequence of columns to be reported + const std::list< ColType > colOrder; + + //! the column separator to be used + std::string colSep; + + + +}; + + +////////////////////////////////////////////////////////////////////////// + +inline +const std::map & +OutputHandlerCsv:: +getColType2string() +{ + return colType2string; +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +OutputHandlerCsv:: +add( const InteractionRange & range ) +{ + // forward to interaction reporting + add( Interaction(range) ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +std::string +OutputHandlerCsv:: +list2string( const ColTypeList & colTypes ) +{ + // init string encodings + initColType2string(); + // convert list + std::stringstream ret; + for (auto it = colTypes.begin(); it!=colTypes.end(); it++) { + if (it!=colTypes.begin()) + ret <<','; + ret <(c) ); + } + } + else { + // find split position + size_t startPos = 0, splitPos = std::string::npos; + while (startPos != splitPos) { + splitPos = stringEncoding.find(',',startPos); + // get current type string + std::string curTypeString = stringEncoding.substr(startPos,splitPos-(splitPos==std::string::npos?0:startPos)); + // trim leading/trailing whitespaces + boost::trim(curTypeString); + // try to find type encoding + bool notFound = true; + for (auto it = colType2string.begin(); notFound && it != colType2string.end(); it++ ) { + // check if type found (case insensitive for being user friendly + if ( boost::iequals( it->second, curTypeString) ) { + list.push_back( it->first ); + notFound = false; + } + } + // check if error to be raised + if (notFound) { + throw std::runtime_error("OutputHandlerCsv::string2list("+stringEncoding+") contains unsupported ColType encoding '"+curTypeString+"'"); + } + // update start of next interval encoding to parse + startPos = splitPos + (splitPos != std::string::npos ? 1 : 0); + } + } + return list; +} + +////////////////////////////////////////////////////////////////////////// + +inline +std::string +OutputHandlerCsv:: +getHeader( const OutputHandlerCsv::ColTypeList & colList, const std::string& colSep ) +{ + // init string encodings + initColType2string(); + + // generate header via stream + std::stringstream header; + for (auto col = colList.begin(); col != colList.end(); col++) { + header <<(col==colList.begin()?"":colSep) + < +#include + +#if INTARNA_MULITHREADING + #include +#endif + +//////////////////////////////////////////////////////////////////////////// + +OutputHandlerIntaRNA1:: +OutputHandlerIntaRNA1( + std::ostream & out + , const InteractionEnergy & energy + , const bool detailedOutput + ) + : + detailedOutput(detailedOutput) + , out(out) + , energy(energy) + , initialOutputDone(false) + , printSeparator(false) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +OutputHandlerIntaRNA1:: +~OutputHandlerIntaRNA1() +{ + out.flush(); +} + +//////////////////////////////////////////////////////////////////////////// + +void +OutputHandlerIntaRNA1:: +add( const Interaction & i ) +{ +#if IN_DEBUG_MODE + // debug checks + if ( i.basePairs.size() > 0 && ! i.isValid() ) { + throw std::runtime_error("OutputHandlerIntaRNA1::add() : given interaction is not valid : "+toString(i)); + } +#endif + + // special handling if no base pairs present + if (i.basePairs.size() == 0) { + // no output for empty interactions + return; + } + + // count report + reportedInteractions++; + + // ensure outputs do not intervene +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_outputStreamUpdate) +#endif + { + if (!initialOutputDone) { + if (printSeparator) { + out <<"\n=========================\n" + <<'\n'; + + + } + // write sequences in FASTA to out + out + <<">" <" <first; + const size_t j1 = i.basePairs.rbegin()->first; + const size_t i2 = i.basePairs.begin()->second; + const size_t j2 = i.basePairs.rbegin()->second; + + // determine maximal length of sequence to the left of first base pair + const size_t flankingLength = 3 + std::max(i1,i.s2->size()-i2-1); + + // decompose printing into several rows + std::ostringstream s1Unbound; + std::ostringstream s1Bound; + std::ostringstream s2Bound; + std::ostringstream s2Unbound; + + // left flanking + // unbound region s1 + s1Unbound.width(flankingLength); + s1Unbound <asString().substr( 0, i1)); + } else { + // prefix shortening needed + s1Unbound <<("5'-" + + i.s1->asString().substr( 0,3) + + "..." + + i.s1->asString().substr( (size_t)std::max(0,(int)i1+6-(int)flankingLength), flankingLength-6) + ); + } + // bound region + s1Bound.width(flankingLength); s1Bound <<' '; + s2Bound.width(flankingLength); s2Bound <<' '; + // unbound region s2 + s2Unbound.width(flankingLength); + s2Unbound < i.s2->size()) { + // add remaining sequence + s2Unbound <<("3'-" + reverse(i.s2->asString().substr(i2+1))); + } else { + // shortening needed + s2Unbound <<("3'-" + + reverse(i.s2->asString().substr(i.s2->size()-3)) + + "..." + + reverse(i.s2->asString().substr(i2+1, flankingLength-6)) + ); + } + + // interaction start left + Interaction::PairingVec::const_iterator leftBP = i.basePairs.begin(); + char nt1 = i.s1->asString().at(leftBP->first); + char nt2 = i.s2->asString().at(leftBP->second); + // print start + s1Unbound.width(1); s1Unbound <asString().at(leftBP->first); + s2Bound.width(1); s2Bound <asString().at(leftBP->second); + s2Unbound.width(1); s2Unbound <first - leftBP->first -1; + loop2 = leftBP->second - curBP->second -1; + loop = std::max(loop1,loop2); + // print unbound loop regions + if (loop>0) { + // unbound region s1 + s1Unbound.width(loop); + if (loop1 > 0) { + s1Unbound <asString().substr( leftBP->first +1, loop1 ); + } else { + s1Unbound <<' '; + } + // bound region + s1Bound.width(loop); s1Bound <<' '; + s2Bound.width(loop); s2Bound <<' '; + // unbound region s2 + s2Unbound.width(loop); + if (loop2 > 0) { + s2Unbound <asString().substr( curBP->second +1, loop2 )); + } else { + s2Unbound <<' '; + } + } + interactionLength += loop; + + // print current base pair (right end of internal loop) + nt1 = i.s1->asString().at(curBP->first); + nt2 = i.s2->asString().at(curBP->second); + s1Unbound.width(1); s1Unbound <<' '; + s1Bound.width(1); s1Bound <asString().substr(j1+1) + <<"-3'"; + // full sequence prefix + s2Unbound <asString().substr( 0, j2)) + <<"-5'"; + + // ensure outputs do not intervene +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_outputStreamUpdate) +#endif + { + + // print full interaction to output stream + out <<'\n' + // print collected interaction stuff + <first +1)<<" -- "<<(i.basePairs.rbegin()->first +1) <<'\n' + <<"positions seed(target): "<<(i.seedRange!=NULL?toString(i.seedRange->r1.from +1):"?")<<" -- "<<(i.seedRange!=NULL?toString(i.seedRange->r1.to +1):"?") <<'\n' + <<"positions with dangle(target): "<<(i.basePairs.begin()->first +1)<<" -- "<<(i.basePairs.rbegin()->first +1) <<'\n' + <<"positions(ncRNA) : "<<(i.basePairs.rbegin()->second +1)<<" -- "<<(i.basePairs.begin()->second +1) <<'\n' + <<"positions seed(ncRNA) : "<<(i.seedRange!=NULL?toString(i.seedRange->r2.to +1):"?")<<" -- "<<(i.seedRange!=NULL?toString(i.seedRange->r2.from +1):"?") <<'\n' + <<"positions with dangle(ncRNA): "<<(i.basePairs.rbegin()->second +1)<<" -- "<<(i.basePairs.begin()->second +1) <<'\n' + <<"ED target need: "< + +/** + * Interaction output handler that writes all interactions directly to stream + * as done by IntaRNA version 1.2.* in detailed output mode. + * + * @author Martin Mann 2016 + */ +class OutputHandlerIntaRNA1: public OutputHandler { +public: + + /** + * Construct a simple text output handler for interaction reporting + * similar to the detailed output of IntaRNA version 1.2.* + * + * @param out the stream to write to + * @param energy the interaction energy object used for computation + * @param detailedOutput whether or not to produce detailed (true) or + * normal (false) IntaRNA v1* output + */ + OutputHandlerIntaRNA1( std::ostream & out + , const InteractionEnergy & energy + , const bool detailedOutput ); + + /** + * destruction, enforces a flush on the output stream. + */ + virtual ~OutputHandlerIntaRNA1(); + + /** + * Write a given RNA-RNA interaction in simple text format to the output + * stream. + * + * @param interaction the interaction to output + */ + virtual + void + add( const Interaction & interaction ); + + /** + * Handles a given RNA-RNA interaction range as a + * RNA-RNA interaction with two base pairs and writes it in simple + * text format to the output stream. + * + * @param range the interaction range to add + */ + virtual + void + add( const InteractionRange & range ); + + /** + * Defines whether or not a leading separator is to be printed before any + * output for this output handler. + * @param yesNo whether or not a separator is to be printed + */ + virtual + void + addSeparator (const bool yesNo ); + +protected: + + //! whether or not to produce detailed (true) or normal (false) output + const bool detailedOutput; + + //! the output stream to write the interaction text representation to + std::ostream & out; + + //! the interaction energy handler used for the energy computations + const InteractionEnergy & energy; + + //! whether or not the initial output was done + bool initialOutputDone; + + //! whether or not to print a leading separator with the initial output + bool printSeparator; + + +}; + +#endif /* OUTPUTHANDLERINTARNA1_H_ */ diff --git a/src/OutputHandlerRangeOnly.cpp b/src/OutputHandlerRangeOnly.cpp new file mode 100644 index 00000000..71ce0366 --- /dev/null +++ b/src/OutputHandlerRangeOnly.cpp @@ -0,0 +1,27 @@ + +#include "OutputHandlerRangeOnly.h" + +OutputHandlerRangeOnly::OutputHandlerRangeOnly( OutputHandler & successiveOutput ) + : + successiveOutput(successiveOutput) +{ +} + +OutputHandlerRangeOnly::~OutputHandlerRangeOnly() { +} + +void +OutputHandlerRangeOnly:: +add( const Interaction & interaction ) +{ + // convert and forward + successiveOutput.add( InteractionRange(interaction) ); +} + +void +OutputHandlerRangeOnly:: +add( const InteractionRange & range ) +{ + // forward + successiveOutput.add( range ); +} diff --git a/src/OutputHandlerRangeOnly.h b/src/OutputHandlerRangeOnly.h new file mode 100644 index 00000000..22c6b936 --- /dev/null +++ b/src/OutputHandlerRangeOnly.h @@ -0,0 +1,59 @@ + +#ifndef OUTPUTHANDLERRANGEONLY_H_ +#define OUTPUTHANDLERRANGEONLY_H_ + +#include "OutputHandler.h" + +/** + * Output handler that transforms a given interaction into an interaction + * range and forwards all reports to a provided successive output handler. + * + * @author Martin Mann + * + */ +class OutputHandlerRangeOnly : public OutputHandler { + +protected: + + //! the output handler to be called for each interaction range + OutputHandler& successiveOutput; + +public: + + /** + * construction + * @param successiveOutput the output handler to be called for each + * interaction range + */ + OutputHandlerRangeOnly( OutputHandler & successiveOutput ); + + /** + * destruction + */ + virtual ~OutputHandlerRangeOnly(); + + + /** + * Converts the given RNA-RNA interaction into an interaction range + * and forwards it to the successive output handler + * + * @param interaction the interaction to transform into an interaction range + */ + virtual + void + add( const Interaction & interaction ); + + /** + * Forwards the given RNA-RNA interaction range to the successive output + * handler + * + * @param range the interaction range to add + */ + virtual + void + add( const InteractionRange & range ); + + +}; + +#endif /* OUTPUTHANDLERRANGEONLY_H_ */ diff --git a/src/OutputHandlerText.cpp b/src/OutputHandlerText.cpp new file mode 100644 index 00000000..0039fe66 --- /dev/null +++ b/src/OutputHandlerText.cpp @@ -0,0 +1,335 @@ + +#include "OutputHandlerText.h" + +#include +#include + +#if INTARNA_MULITHREADING + #include +#endif + +//////////////////////////////////////////////////////////////////////////// + +OutputHandlerText:: +OutputHandlerText( + std::ostream & out, + const InteractionEnergy & energy, + const size_t flankingLength_, + const bool detailedOutput + ) + : + out(out) + , energy(energy) + , flankingLength(flankingLength_) + , detailedOutput(detailedOutput) +{ + if (flankingLength < 10) { + throw std::runtime_error("OutputHandlerText::OutputHandlerText : flankingLength ("+toString(flankingLength_)+") has to be at least 9"); + } +} + +//////////////////////////////////////////////////////////////////////////// + +OutputHandlerText:: +~OutputHandlerText() +{ + out.flush(); +} + +//////////////////////////////////////////////////////////////////////////// + +void +OutputHandlerText:: +add( const Interaction & i ) +{ +#if IN_DEBUG_MODE + // debug checks + if ( i.basePairs.size() > 0 && ! i.isValid() ) { + throw std::runtime_error("OutputHandlerText::add() : given interaction is not valid : "+toString(i)); + } +#endif + + // special handling if no base pairs present + if (i.basePairs.size() == 0) { + // ensure outputs do not intervene +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_outputStreamUpdate) +#endif + { + out <<"\n" + <<"no favorable interaction for "<getId() <<" and "<getId()<first; + const size_t j1 = i.basePairs.rbegin()->first; + const size_t i2 = i.basePairs.begin()->second; + const size_t j2 = i.basePairs.rbegin()->second; + + // decompose printing into several rows + std::ostringstream s1Unbound; + std::ostringstream s1Bound; + std::ostringstream pairing; + std::ostringstream s2Bound; + std::ostringstream s2Unbound; + + // left flanking + // unbound region s1 + s1Unbound.width(flankingLength+3); + s1Unbound <asString().substr( 0, i1)); + } else { + // prefix shortening needed + s1Unbound <<("5'-" + + i.s1->asString().substr( 0,3) + + "..." + + i.s1->asString().substr( (size_t)std::max(0,(int)i1+6-(int)flankingLength), flankingLength-6) + ); + } + // bound region + s1Bound.width(flankingLength+3); s1Bound <<' '; + pairing.width(flankingLength+3); pairing <<' '; + s2Bound.width(flankingLength+3); s2Bound <<' '; + // unbound region s2 + s2Unbound.width(flankingLength+3); + s2Unbound <asString().substr( (size_t)std::max(0,(int)i2-(int)flankingLength), std::min(i2,flankingLength) )); +// if (i2 < flankingLength) { +// // full sequence prefix +// s2Unbound <<("3'-" + i.s2->asString().substr( 0, i2)); +// } else { +// // prefix shortening needed +// s2Unbound <<("3'-" +// + i.s2->asString().substr( 0,3) +// + "..." +// + i.s2->asString().substr( (size_t)std::max(0,(int)i2+6-(int)flankingLength), flankingLength-6) +// ); +// } + if (i2+flankingLength > i.s2->size()) { + // add remaining sequence + s2Unbound <<("3'-" + reverse(i.s2->asString().substr(i2+1))); + } else { + // shortening needed + s2Unbound <<("3'-" + + reverse(i.s2->asString().substr(i.s2->size()-3)) + + "..." + + reverse(i.s2->asString().substr(i2+1, flankingLength-6)) + ); + } + + // interaction start left + Interaction::PairingVec::const_iterator leftBP = i.basePairs.begin(); + char nt1 = i.s1->asString().at(leftBP->first); + char nt2 = i.s2->asString().at(leftBP->second); + // print start + s1Unbound.width(1); s1Unbound <asString().at(leftBP->first); + pairing.width(1); pairing <asString().at(leftBP->second); + s2Unbound.width(1); s2Unbound <first - leftBP->first -1; + loop2 = leftBP->second - curBP->second -1; + loop = std::max(loop1,loop2); + // print unbound loop regions + if (loop>0) { + // unbound region s1 + s1Unbound.width(loop); + if (loop1 > 0) { + s1Unbound <asString().substr( leftBP->first +1, loop1 ); + } else { + s1Unbound <<' '; + } + // bound region + s1Bound.width(loop); s1Bound <<' '; + pairing.width(loop); pairing <<' '; + s2Bound.width(loop); s2Bound <<' '; + // unbound region s2 + s2Unbound.width(loop); + if (loop2 > 0) { + s2Unbound <asString().substr( curBP->second +1, loop2 )); + } else { + s2Unbound <<' '; + } + } + interactionLength += loop; + + // print current base pair (right end of internal loop) + nt1 = i.s1->asString().at(curBP->first); + nt2 = i.s2->asString().at(curBP->second); + s1Unbound.width(1); s1Unbound <<' '; + s1Bound.width(1); s1Bound < i.s1->size()) { + // add remaining sequence + s1Unbound <asString().substr(j1+1); + } else { + // shortening needed + s1Unbound <asString().substr(j1+1, flankingLength-6) + <<"..." + <asString().substr(i.s1->size()-3); + } + s1Unbound <<"-3'"; + // unbound region s2 +// if (j2+flankingLength > i.s2->size()) { +// // add remaining sequence +// s2Unbound <asString().substr(j2+1); +// } else { +// // shortening needed +// s2Unbound <asString().substr(j2+1, flankingLength-6) +// <<"..." +// <asString().substr(i.s2->size()-3); +// } + if (j2 < flankingLength) { + // full sequence prefix + s2Unbound <asString().substr( 0, j2)); + } else { + // prefix shortening needed + s2Unbound <asString().substr( (size_t)std::max(0,(int)j2+6-(int)flankingLength), flankingLength-6)) + <<"..." + <asString().substr( 0,3)) + ; + } + s2Unbound <<"-5'"; + + // position information (first and last interacting positions in sequence) + // start indexing with 1 instead of 0 + std::ostringstream pos1, pos1tag; + pos1 <size()-i2-1); + // put left (3') end only if not overlapping with 5' start position (right) + pos2 < j2) { + pos2 <getId() <<'\n' + // get position in s1 + <getId() <<'\n' + ; + + if (detailedOutput) { + out + // interaction range + <<"\n" + <<"interaction seq1 = "<<(i.basePairs.begin()->first +1)<<" -- "<<(i.basePairs.rbegin()->first +1) <<'\n' + <<"interaction seq2 = "<<(i.basePairs.rbegin()->second +1)<<" -- "<<(i.basePairs.begin()->second +1) <<'\n' + ; + } // detailed + // print energy + out + <<"\n" + <<"interaction energy = "<r1.to +1) <<'\n' + <<"seed seq2 = "<<(i.seedRange->r2.to +1)<<" -- "<<(i.seedRange->r2.from +1) <<'\n' + <<"seed energy = "<<(i.seedRange->energy)<<" kcal/mol\n" + <<"seed ED1 = "<r1.from, i.seedRange->r1.to )<<" kcal/mol\n" + <<"seed ED2 = "<r2.to, i.seedRange->r2.from )<<" kcal/mol\n" + <<"seed Pu1 = "<r1.from, i.seedRange->r1.to ))/energy.getRT())<<'\n' + <<"seed Pu2 = "<r2.to, i.seedRange->r2.from ))/energy.getRT())<<'\n' + ; + } // seed + } // detailed + } // omp critical(intarna_omp_outputStreamUpdate) + +} + + +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/OutputHandlerText.h b/src/OutputHandlerText.h new file mode 100644 index 00000000..516ab6af --- /dev/null +++ b/src/OutputHandlerText.h @@ -0,0 +1,90 @@ + +#ifndef OUTPUTHANDLERTEXT_H_ +#define OUTPUTHANDLERTEXT_H_ + +#include "OutputHandler.h" +#include "InteractionEnergy.h" + +#include + +/** + * Interaction output handler that writes all interactions directly to stream + * in a simple text format. + * + * @author Martin Mann 2014 + */ +class OutputHandlerText: public OutputHandler { +public: + + /** + * Construct a simple text output handler for interaction reporting. + * + * @param out the stream to write to + * @param energy the interaction energy object used for computation + * @param flankingLength maximal number of nucleotides flanking the + * interaction to be printed in the output + * @param detailedOutput if (true) detailed output is provided; normal + * reduced output otherwise + */ + OutputHandlerText( std::ostream & out + , const InteractionEnergy & energy + , const size_t flankingLength = 10 + , const bool detailedOutput = false ); + + /** + * destruction, enforces a flush on the output stream. + */ + virtual ~OutputHandlerText(); + + /** + * Write a given RNA-RNA interaction in simple text format to the output + * stream. + * + * @param interaction the interaction to output + */ + virtual + void + add( const Interaction & interaction ); + + /** + * Handles a given RNA-RNA interaction range as a + * RNA-RNA interaction with two base pairs and writes it in simple + * text format to the output stream. + * + * @param range the interaction range to add + */ + virtual + void + add( const InteractionRange & range ); + +protected: + + //! the output stream to write the interaction text representation to + std::ostream & out; + + //! the interaction energy handler used for the energy computations + const InteractionEnergy & energy; + + //! number of flanking bases left/right of the interaction to print + const size_t flankingLength; + + //! whether or not detailed output has to be provided + const bool detailedOutput; + +}; + + +//////////////////////////////////////////////////////////////////////////// + +inline +void +OutputHandlerText:: +add( const InteractionRange & range ) +{ + // forward to interaction reporting + add( Interaction(range) ); +} + +//////////////////////////////////////////////////////////////////////////// + +#endif /* OUTPUTHANDLERTEXT_H_ */ diff --git a/src/Predictor.cpp b/src/Predictor.cpp new file mode 100644 index 00000000..b8387d8b --- /dev/null +++ b/src/Predictor.cpp @@ -0,0 +1,7 @@ + +#include "Predictor.h" + + + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/Predictor.h b/src/Predictor.h new file mode 100644 index 00000000..339a76b1 --- /dev/null +++ b/src/Predictor.h @@ -0,0 +1,154 @@ + +#ifndef PREDICTOR_H_ +#define PREDICTOR_H_ + +#include "general.h" +#include "InteractionEnergyIdxOffset.h" + +#include "OutputConstraint.h" +#include "OutputHandler.h" + +/** + * RNA-RNA interaction prediction handler interface. + * + * @author Martin Mann 2014 + * + */ +class Predictor { + +public: + + /** + * Constructs an RNA-RNA interaction prediction handler and sets the + * central data members. + * + * @param energy the handler for interaction energy computation + * @param output the output handler for identified interactions + * + */ + Predictor( const InteractionEnergy & energy, OutputHandler & output ); + + /** + * destruction + */ + virtual ~Predictor(); + + /** + * Computes the predictors optimization target for the given sequence + * ranges in the first sequence and second sequence. + * The according optimal interaction is given to the output handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint() ) = 0; + + /** + * Computes the maximal width of an interaction for a given site width and + * maximal size of interaction loops. + * + * @param w the width to compute the maximal interacting width for + * @param maxLoopSize the maximal size of loops within interactions + * + * @return 1 + (w-1)*(maxLoopSize+1): if w>0; 0 otherwise + */ + static + size_t + getMaxInteractionWidth( const size_t w, const size_t maxLoopSize ); + +protected: + + //! energy computation handler + InteractionEnergyIdxOffset energy; + + //! interaction output handler + OutputHandler & output; + + + + /** + * Initializes the list of best solutions to be filled by updateOptima() + * + * @param outConstraint constrains the interactions reported to the output handler + */ + virtual + void + initOptima( const OutputConstraint & outConstraint ) = 0; + + /** + * Updates the global the list of best solutions found so far + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 + * @param energy the energy of the interaction site + * @param isHybridE whether or not the given energy is only the + * hybridization energy (init+loops) or the total interaction energy + */ + virtual + void + updateOptima( const size_t i1, const size_t j1 + , const size_t i2, const size_t j2 + , const E_type energy + , const bool isHybridE ) = 0; + + + + + /** + * Pushes the optimal and suboptimal solutions to the output handler. + * + * @param outConstraint constrains the interactions reported to the output handler + */ + virtual + void + reportOptima( const OutputConstraint & outConstraint ) = 0; + + +}; + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +inline +Predictor::Predictor( const InteractionEnergy & energy, OutputHandler & output ) +: + energy(energy) + , output(output) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +Predictor::~Predictor() +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +Predictor:: +getMaxInteractionWidth( const size_t w, const size_t maxLoopSize ) +{ + // check if no window at all + if (w==0) + return 0; + // compute maximal interaction width, ie each position pairs with max loop size + return 1 + ((w-1)*(maxLoopSize+1)); +} + +//////////////////////////////////////////////////////////////////////////// + + +#endif /* PREDICTOR_H_ */ diff --git a/src/PredictorMaxProb.cpp b/src/PredictorMaxProb.cpp new file mode 100644 index 00000000..72f50b04 --- /dev/null +++ b/src/PredictorMaxProb.cpp @@ -0,0 +1,308 @@ + +#include "PredictorMaxProb.h" + +//////////////////////////////////////////////////////////////////////////// + +PredictorMaxProb:: +PredictorMaxProb( const InteractionEnergy & energy, OutputHandler & output ) + : Predictor(energy,output) + , hybridZ( 0,0 ) + , Z(0.0) + , maxProbInteraction(energy.getAccessibility1().getSequence() + ,energy.getAccessibility2().getAccessibilityOrigin().getSequence()) +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMaxProb:: +~PredictorMaxProb() +{ + // clean up + this->clear(); +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMaxProb:: +predict( const IndexRange & r1 + , const IndexRange & r2 + , const OutputConstraint & outConstraint + ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting maximally probable interactions in O(n^4) space..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + + if (outConstraint.reportMax > 1) { + NOTIMPLEMENTED("PredictorMaxProb::predict(reportMax > 1) : not implemented"); + } + +#if IN_DEBUG_MODE + // check indices (both regions ascending due to reversing of seq2) + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMaxProb::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + // clear data + clear(); + + // setup index offset + energy.setOffset1( r1.from ); + energy.setOffset2( r1.from ); + + // resize matrix + hybridZ.resize( std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ) + , std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ) ); + + size_t debug_count_cells_null=0, debug_count_cells_nonNull = 0, debug_cellNumber=0; + + size_t maxWidthFori1i2 = 0; + + bool i1blocked, i1or2blocked; + // initialize 3rd and 4th dimension of the matrix + for (size_t i1=0; i1size1()<=w1 || hybridZ(i1,i2)->size2()<=w2) { + // interaction not possible: nothing to do + continue; + } + // check if interaction exceeds possible width due to max-loop-length + if ( getMaxInteractionWidth( 1+w1, energy.getMaxInternalLoopSize1() ) < w2 + || getMaxInteractionWidth( 1+w2, energy.getMaxInternalLoopSize2() ) < w1) + { + // ignore this entry + (*hybridZ(i1,i2))(w1,w2) = 0; + continue; + } + + // get window ends j (seq1) and l (seq2) + j1=i1+w1; + j2=i2+w2; + + // check if right boundary is complementary + if (hybridZ(j1,j2) == NULL) { + // not complementary -> ignore this entry + (*hybridZ(i1,i2))(w1,w2) = 0; + continue; + } + // compute entry + curZ = 0; + + // either interaction initiation + if ( w1==0 && w2==0 ) { + curZ += energy.getBoltzmannWeight(energy.getE_init()); + } else { + // or only internal loop energy (nothing between i and j) + if ( (w1+1) <= energy.getMaxInternalLoopSize1() && (w2+1) <= energy.getMaxInternalLoopSize2()) { + curZ += energy.getBoltzmannWeight(energy.getE_interLeft(i1,j1,i2,j2)) + * (*hybridZ(j1,j2))(0,0); + } + } + + if (w1 > 1 && w2 > 1) { + // sum all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + for (k1=std::min(j1-1,i1+energy.getMaxInternalLoopSize1()+1); k1>i1; k1--) { + for (k2=std::min(j2-1,i2+energy.getMaxInternalLoopSize2()+1); k2>i2; k2--) { + // check if (k1,k2) are complementary + if (hybridZ(k1,k2) != NULL && hybridZ(k1,k2)->size1()>(j1-k1) && hybridZ(k1,k2)->size2()>(j2-k2)) { + curZ += energy.getBoltzmannWeight(energy.getE_interLeft(i1,k1,i2,k2)) + * ((*hybridZ(k1,k2))(j1-k1,j2-k2)); + } + } + } + } + // store value + (*hybridZ(i1,i2))(w1,w2) = curZ; + // update max prob interaction + updateOptima( i1,j1,i2,j2, (*hybridZ(i1,i2))(w1,w2), true ); + } + } + } + } + + +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMaxProb:: +initOptima( const OutputConstraint & outConstraint ) +{ + // initialize max prob interaction (partition function value) + maxProbInteraction.energy = 0.0; + // reset boundary base pairs + maxProbInteraction.r1.from = RnaSequence::lastPos; + maxProbInteraction.r1.to = RnaSequence::lastPos; + maxProbInteraction.r2.from = RnaSequence::lastPos; + maxProbInteraction.r2.to = RnaSequence::lastPos; + + if (outConstraint.reportMax > 1) { + NOTIMPLEMENTED("PredictorMaxProb::initOptima(reportMax > 1)"); + } +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMaxProb:: +updateOptima( const size_t i1, const size_t j1 + , const size_t i2, const size_t j2 + , const E_type interZ + , const bool isHybridZ ) +{ +// { LOG(DEBUG) <<"Z( "< maxProbInteraction.energy) { + // store new global min + maxProbInteraction.energy = curZ; + // store interaction boundaries + // left + maxProbInteraction.r1.from = i1+energy.getOffset1(); + maxProbInteraction.r2.from = energy.getAccessibility2().getReversedIndex(i2+energy.getOffset2()); + // right + maxProbInteraction.r1.to = j1+energy.getOffset1(); + maxProbInteraction.r2.to = energy.getAccessibility2().getReversedIndex(j2+energy.getOffset2()); + } +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMaxProb:: +reportOptima( const OutputConstraint & outConstraint ) +{ + + if (outConstraint.reportMax == 0) { + return; + } + + if (outConstraint.reportMax > 1) { + NOTIMPLEMENTED("PredictorMaxProb::reportOptima(reportMax > 1)"); + } + + // maximal probability is + // double maxProb = (double)maxProbInteraction.getEnergy() / Z; + + // convert the partition function into an ensemble energy + maxProbInteraction.energy = ( - energy.getRT() * std::log( maxProbInteraction.energy ) ); + + // push to output handler + output.add( maxProbInteraction ); + +} + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/PredictorMaxProb.h b/src/PredictorMaxProb.h new file mode 100644 index 00000000..ed735128 --- /dev/null +++ b/src/PredictorMaxProb.h @@ -0,0 +1,134 @@ + +#ifndef PREDICTORMAXPROB_H_ +#define PREDICTORMAXPROB_H_ + +#include "Predictor.h" +#include "InteractionRange.h" + +#include + +/** + * Computes the interaction site with maximal probability among all interaction + * sites + * + * @author Martin Mann + * + */ +class PredictorMaxProb: public Predictor { + +protected: + + //! matrix type to cover the energies for different interaction site widths + typedef boost::numeric::ublas::matrix E2dMatrix; + + //! full 4D DP-matrix for computation to hold all start position combinations + //! first index = start positions (i1,i2) of (seq1,seq2) + //! second index = interaction window sizes (w1,w2) or NULL if (i1,i2) not complementary + typedef boost::numeric::ublas::matrix< E2dMatrix* > E4dMatrix; + + +public: + + /** + * Constructs a predictor and stores the energy and output handler + * + * @param energy the interaction energy handler + * @param output the output handler to report optimal interactions to + */ + PredictorMaxProb( const InteractionEnergy & energy, OutputHandler & output ); + + virtual ~PredictorMaxProb(); + + /** + * Computes the interaction site with maximal probability + * for the given sequence ranges (i1-j1) in the first + * sequence and (i2-j2) in the second sequence and reports it to the output + * handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint() ); + +protected: + + //! access to the interaction energy handler of the super class + using Predictor::energy; + + //! access to the output handler of the super class + using Predictor::output; + + //! partition function of all interaction hybrids computed by the recursion with indices + //! hybridZ(i1,i2)->(w1,w2), with interaction start i1 (seq1) and i2 (seq2) and + //! ineraction end j1=i1+w1 and j2=j2+w2 + //! NOTE: hybridZ(i1,i2)==NULL if not complementary(seq1[i1],seq2[i2]) + E4dMatrix hybridZ; + + //! the overall partition function = sum or all hybridZ entries + double Z; + + //! interaction boundaries with maximal probability + InteractionRange maxProbInteraction; + +protected: + + /** + * Removes all temporary data structures and resets the predictor + */ + void + clear(); + + /** + * computes all entries of the hybridZ matrix + */ + void + fillHybridZ( ); + + /** + * Initializes the interaction site with maximal probability + * + * @param outConstraint constrains the interactions reported to the output handler + */ + virtual + void + initOptima( const OutputConstraint & outConstraint ); + + /** + * updates the global optimum if needed + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 + * @param Z partition function for the interaction + * @param isHybridZ whether or not the given hybridZ is only for + * hybridizations (init+loops) or the total interaction energy details + */ + virtual + void + updateOptima( const size_t i1, const size_t j1 + , const size_t i2, const size_t j2 + , const E_type Z + , const bool isHybridZ ); + + + + /** + * Pushes the stored optimal and suboptimal solutions to the output handler. + * + * @param outConstraint constrains the interactions reported to the output handler + */ + virtual + void + reportOptima( const OutputConstraint & outConstraint ); + + +}; + +#endif /* PREDICTORMAXPROB_H_ */ diff --git a/src/PredictorMfe.cpp b/src/PredictorMfe.cpp new file mode 100644 index 00000000..82afb36c --- /dev/null +++ b/src/PredictorMfe.cpp @@ -0,0 +1,233 @@ + +#include "PredictorMfe.h" + +#include +#include + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe::PredictorMfe( const InteractionEnergy & energy, OutputHandler & output ) + : Predictor(energy,output) + , mfeInteractions() + , reportedInteractions() + , minStackingEnergy( energy.getBestE_interLoop() ) + , minInitEnergy( energy.getE_init() ) + , minDangleEnergy( energy.getBestE_dangling() ) + , minEndEnergy( energy.getBestE_end() ) +{ + +} + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe::~PredictorMfe() +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe:: +initOptima( const OutputConstraint & outConstraint ) +{ + // resize to the given number of interactions if overlapping reports allowed + mfeInteractions.resize(outConstraint.reportOverlap!=OutputConstraint::ReportOverlap::OVERLAP_BOTH ? 1 : outConstraint.reportMax + , Interaction(energy.getAccessibility1().getSequence() + ,energy.getAccessibility2().getAccessibilityOrigin().getSequence()) + ); + + // init all interactions to be filled + for (InteractionList::iterator i = mfeInteractions.begin(); i!= mfeInteractions.end(); i++) { + // initialize global E minimum : should be below 0.0 + i->energy = outConstraint.maxE; + // ensure it holds only the boundary + if (i->basePairs.size()!=2) { + i->basePairs.resize(2); + } + // reset boundary base pairs + i->basePairs[0].first = RnaSequence::lastPos; + i->basePairs[0].second = RnaSequence::lastPos; + i->basePairs[1].first = RnaSequence::lastPos; + i->basePairs[1].second = RnaSequence::lastPos; + } + + // clear reported interaction ranges + reportedInteractions.first.clear(); + reportedInteractions.second.clear(); + +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe:: +updateOptima( const size_t i1, const size_t j1 + , const size_t i2, const size_t j2 + , const E_type interE + , const bool isHybridE ) +{ +// LOG(DEBUG) <<"energy( "<energy = (curE); + // store interaction boundaries + // left + mfeInteractions.begin()->basePairs[0] = energy.getBasePair(i1,i2); + // right + mfeInteractions.begin()->basePairs[1] = energy.getBasePair(j1,j2); + } + } else { + + // check if within range of already known suboptimals (< E(worst==last)) + if (curE < mfeInteractions.rbegin()->energy) { + + // identify sorted insertion position (iterator to position AFTER insertion) + InteractionList::iterator toInsert = --(mfeInteractions.end()); + InteractionList::iterator insertSuccPos = + std::upper_bound(mfeInteractions.begin(), toInsert + , curE + , Interaction::compareEnergy ); + + // check if not already within list + bool isToBeInserted = insertSuccPos == mfeInteractions.begin(); + if (!isToBeInserted) { + // go to preceeding interaction to check for equivalence + --insertSuccPos; + // check if not equal + isToBeInserted = + // check energy + ! E_equal(curE,insertSuccPos->energy) + // check boundaries + && insertSuccPos->basePairs.at(0) != energy.getBasePair(i1,i2) + && insertSuccPos->basePairs.at(1) != energy.getBasePair(j1,j2) + ; + // restore insert position + ++insertSuccPos; + } + + // insert current interaction into lowest energy interaction list + if (isToBeInserted) { + + // overwrite last list element + // set current energy + toInsert->energy = (curE); + // store interaction boundaries + // left + toInsert->basePairs[0] = energy.getBasePair(i1,i2); + // right + toInsert->basePairs[1] = energy.getBasePair(j1,j2); + + // relocate last element within list (no reallocation needed, just list-link-update) + mfeInteractions.splice( insertSuccPos, mfeInteractions, toInsert ); + } + + } + } +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe:: +reportOptima( const OutputConstraint & outConstraint ) +{ + // number of reported interactions + size_t reported = 0; + // get maximal report energy = mfe + deltaE + precisionEpsilon + const E_type maxE = std::min(outConstraint.maxE, (E_type)(mfeInteractions.begin()->energy + outConstraint.deltaE + E_precisionEpsilon)); + + // clear reported interaction ranges + reportedInteractions.first.clear(); + reportedInteractions.second.clear(); + + // check if non-overlapping output is wanted + if (outConstraint.reportOverlap!=OutputConstraint::ReportOverlap::OVERLAP_BOTH) { + // check if mfe is worth reporting + Interaction curBest = *mfeInteractions.begin(); + while( curBest.energy < maxE && reported < outConstraint.reportMax ) { + // report current best + // fill interaction with according base pairs + traceBack( curBest ); + // report mfe interaction + output.add( curBest ); + + // store ranges to ensure non-overlapping of next best solution + switch( outConstraint.reportOverlap ) { + case OutputConstraint::ReportOverlap::OVERLAP_BOTH : + break; + case OutputConstraint::ReportOverlap::OVERLAP_SEQ1 : + reportedInteractions.second.insert( IndexRange(energy.getIndex2(*curBest.basePairs.begin()),energy.getIndex2(*curBest.basePairs.rbegin())) ); + break; + case OutputConstraint::ReportOverlap::OVERLAP_SEQ2 : + reportedInteractions.first.insert( IndexRange(energy.getIndex1(*curBest.basePairs.begin()),energy.getIndex1(*curBest.basePairs.rbegin())) ); + break; + case OutputConstraint::ReportOverlap::OVERLAP_NONE : + reportedInteractions.first.insert( IndexRange(energy.getIndex1(*curBest.basePairs.begin()),energy.getIndex1(*curBest.basePairs.rbegin())) ); + reportedInteractions.second.insert( IndexRange(energy.getIndex2(*curBest.basePairs.begin()),energy.getIndex2(*curBest.basePairs.rbegin())) ); + break; + } + + // count + reported++; + // get next best if not already enough found + if (reported < outConstraint.reportMax) { + // get next best + getNextBest( curBest ); + } + } + + } // non-overlapping interactions + + else // overlapping interactions are allowed + { + + // report all (possibly overlapping) interactions with energy below 0 + assert(outConstraint.reportMax <= mfeInteractions.size()); + for (InteractionList::iterator i = mfeInteractions.begin(); + reported < outConstraint.reportMax + && i!= mfeInteractions.end(); i++) + { + // check if interaction is within allowed energy range + if (i->energy < maxE) { + + // fill mfe interaction with according base pairs + traceBack( *i ); + // report mfe interaction + output.add( *i ); + // count + reported++; + } + } + } // overlapping interactions + + // check if nothing was worth reporting but report was expected + if (reported == 0 && outConstraint.reportMax > 0 ) { + // TODO replace with no report and "no-interaction-message" in output destructor + // -> no preferable interactions found !!! + // replace mfeInteraction with no interaction + mfeInteractions.begin()->clear(); + mfeInteractions.begin()->energy = 0.0; + // report mfe interaction + output.add( *(mfeInteractions.begin()) ); + } + +} + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/PredictorMfe.h b/src/PredictorMfe.h new file mode 100644 index 00000000..6f83b33d --- /dev/null +++ b/src/PredictorMfe.h @@ -0,0 +1,130 @@ + +#ifndef PREDICTORMFE_H_ +#define PREDICTORMFE_H_ + + +#include "Predictor.h" + +#include "IndexRangeList.h" + +#include +#include + +/** + * Generic Predictor interface for MFE interaction computation to avoid + * code redundancy + * + * @author Martin Mann + * + */ +class PredictorMfe : public Predictor { + + +public: + + /** + * Construction call the super constructor + */ + PredictorMfe( const InteractionEnergy & energy, OutputHandler & output ); + + virtual ~PredictorMfe(); + +protected: + + + //! access to the interaction energy handler of the super class + using Predictor::energy; + + //! access to the output handler of the super class + using Predictor::output; + + // TODO provide all data structures as arguments to make predict() call threadsafe + + //! list of interactions + typedef std::list InteractionList; + + //! mfe interaction boundaries + InteractionList mfeInteractions; + + //! index ranges of reported interactions to identify non-overlapping + //! interactions (first = seq1, second = seq2) + //! NOTE: the indices for seq2 are reversed + std::pair< IndexRangeList, IndexRangeList > reportedInteractions; + + //! minimal stacking energy + const E_type minStackingEnergy; + //! minimal interaction initiation energy + const E_type minInitEnergy; + //! minimal dangling end energy + const E_type minDangleEnergy; + //! minimal interaction end energy + const E_type minEndEnergy; + + /** + * Initializes the global energy minimum storage + * + * @param outConstraint constrains the interactions reported to the output handler + */ + virtual + void + initOptima( const OutputConstraint & outConstraint ); + + /** + * updates the global optimum to be the mfe interaction if needed + * + * @param i1 the index of the first sequence interacting with i2 + * @param j1 the index of the first sequence interacting with j2 + * @param i2 the index of the second sequence interacting with i1 + * @param j2 the index of the second sequence interacting with j1 + * @param energy the energy of the interaction + * @param isHybridE whether or not the given energy is only the + * hybridization energy (init+loops) or the total interaction energy + */ + virtual + void + updateOptima( const size_t i1, const size_t j1 + , const size_t i2, const size_t j2 + , const E_type energy + , const bool isHybridE ); + + + /** + * Fills a given interaction (boundaries given) with the according + * hybridizing base pairs. + * Note, the + * @param interaction IN/OUT the interaction to fill + */ + virtual + void + traceBack( Interaction & interaction ) = 0; + + + /** + * Identifies the next best interaction with an energy equal to or higher + * than the given interaction. The new interaction will not overlap any + * index range stored in reportedInteractions. + * + * @param curBest IN/OUT the current best interaction to be replaced with one + * of equal or higher energy not overlapping with any reported + * interaction so far; an interaction with energy E_INF is set, if + * there is no better interaction left + */ + virtual + void + getNextBest( Interaction & curBest ) = 0; + + /** + * Calls for the stored mfe and suboptimal solutions traceBack(i) + * and pushes the according interactions to the output handler. + * For non-overlapping interaction enumeration, getNextBest() is called + * iteratively. + * + * @param outConstraint constrains the interactions reported to the output handler + */ + virtual + void + reportOptima( const OutputConstraint & outConstraint ); + +}; + +#endif /* PREDICTORMFE_H_ */ diff --git a/src/PredictorMfe2d.cpp b/src/PredictorMfe2d.cpp new file mode 100644 index 00000000..191da4df --- /dev/null +++ b/src/PredictorMfe2d.cpp @@ -0,0 +1,357 @@ + +#include "PredictorMfe2d.h" + +#include + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe2d:: +PredictorMfe2d( const InteractionEnergy & energy, OutputHandler & output ) + : PredictorMfe(energy,output) + , hybridE_pq( 0,0 ) + , hybridErange( energy.getAccessibility1().getSequence() + , energy.getAccessibility2().getAccessibilityOrigin().getSequence() ) +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe2d:: +~PredictorMfe2d() +{ + // clean up +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2d:: +predict( const IndexRange & r1 + , const IndexRange & r2 + , const OutputConstraint & outConstraint ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting mfe interactions in O(n^2) space..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + + // suboptimal setup check + if (outConstraint.reportMax>1 && outConstraint.reportOverlap != OutputConstraint::ReportOverlap::OVERLAP_BOTH) { + throw std::runtime_error("PredictorMfe2d : the enumeration of non-overlapping suboptimal interactions is not supported in this prediction mode"); + } + +#if IN_DEBUG_MODE + // check indices + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMfe2d::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + + // set index offset + energy.setOffset1(r1.from); + energy.setOffset2(r2.from); + + // resize matrix + hybridE_pq.resize( std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ) + , std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ) ); + + // initialize mfe interaction for updates + initOptima( outConstraint ); + + // for all right ends j1 + for (size_t j1 = hybridE_pq.size1(); j1-- > 0; ) { + // check if j1 is accessible + if (!energy.isAccessible1(j1)) + continue; + // iterate over all right ends j2 + for (size_t j2 = hybridE_pq.size2(); j2-- > 0; ) { + // check if j2 is accessible + if (!energy.isAccessible2(j2)) + continue; + // check if base pair (j1,j2) possible + if (!energy.areComplementary( j1, j2 )) + continue; + + // fill matrix and store best interaction + fillHybridE( j1, j2, outConstraint ); + + } + } + + // report mfe interaction + reportOptima( outConstraint ); +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2d:: +initHybridE( const size_t j1, const size_t j2 + , const OutputConstraint & outConstraint + , const size_t i1init, const size_t i2init + ) +{ +#if IN_DEBUG_MODE + if (i1init > j1) + throw std::runtime_error("PredictorMfe2d::initHybridE() : i1init > j1 : "+toString(i1init)+" > "+toString(j1)); + if (i2init > j2) + throw std::runtime_error("PredictorMfe2d::initHybridE() : i2init > j2 : "+toString(i2init)+" > "+toString(j2)); +#endif + + // global vars to avoid reallocation + size_t i1,i2,w1,w2,k1,k2; + + // to mark as to be computed + const E_type E_MAX = std::numeric_limits::max(); + // to test whether computation is reasonable + const E_type minInitDangleEndEnergy = minInitEnergy + 2.0*minDangleEnergy + 2.0*minEndEnergy; + + hybridErange.r1.from = std::max(i1init,j1-std::min(j1,energy.getAccessibility1().getMaxLength()+1)); + hybridErange.r1.to = j1; + hybridErange.r2.from = std::max(i2init,j2-std::min(j2,energy.getAccessibility2().getMaxLength()+1)); + hybridErange.r2.to = j2; + + // temporary variable to reduce lookups + E_type curED1 = 0.0; + + // init used part with E_INF - 1 and E_INF if ED test fails + // iterating decreasing window size seq1 (only sane windows) + for (i1=hybridErange.r1.from; i1<=j1; i1++ ) { + w1 = j1-i1+1; + curED1 = energy.getED1(i1,j1); + // iterating decreasing window size seq2 (only sane windows) + for (i2=hybridErange.r2.from; i2<=j2; i2++) { + w2 = j2-i2+1; + // check if all larger windows needing this site are already set to INF + bool largerWindowsINF = i1==hybridErange.r1.from && i2==hybridErange.r2.from; + // check all larger windows w1 + i2p..j2 (that might need this window for computation) + for (size_t i2p=hybridErange.r2.from; largerWindowsINF && i2p>i2; i2p++) { + // check if larger window is E_INF + largerWindowsINF = E_isINF(hybridE_pq(i1,i2p)); + } + // check all larger windows w2 + w1p (that might need this window for computation) + for (size_t i1p=hybridErange.r1.from; largerWindowsINF && i1p>i1; i1p++) { + // check if larger window is E_INF + largerWindowsINF = E_isINF(hybridE_pq(i1,i2)); + } + + // if it holds for all w'>=w: ED1(i1+w1')+ED2(i2+w2')-outConstraint.maxE > -1*(min(w1',w2')*EmaxStacking + Einit + 2*Edangle + 2*Eend) + // ie. the ED values exceed the max possible energy gain of an interaction + if( largerWindowsINF + && ( -1.0*(std::min(w1,w2)*minStackingEnergy + minInitDangleEndEnergy) + < (curED1 + energy.getED2(i2,j2) - outConstraint.maxE)) + ) + { + // mark as NOT to be computed + hybridE_pq(i1,i2) = E_INF; + continue; + } + + // mark as to be computed (has to be < E_INF) + hybridE_pq(i1,i2) = E_MAX; + } + } + +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2d:: +fillHybridE( const size_t j1, const size_t j2 + , const OutputConstraint & outConstraint + , const size_t i1init, const size_t i2init ) +{ + + // init for right interaction end (j1,j2) + initHybridE( j1, j2, outConstraint, i1init, i2init ); + // sanity check of initialization + assert(hybridErange.r1.to == j1); + assert(hybridErange.r2.to == j2); + + // global vars to avoid reallocation + size_t i1,i2,w1,w2,k1,k2; + + ////////// FIRST ROUND : COMPUTE HYBRIDIZATION ENERGIES ONLY //////////// + + // current minimal value + E_type curMinE = E_INF; + // iterate over all window starts i1 (seq1) and i2 (seq2) + // TODO PARALLELIZE THIS DOUBLE LOOP ?! + for (i1=hybridErange.r1.to+1; i1-- > hybridErange.r1.from; ) { + w1 = j1-i1+1; + // w1 width check obsolete due to hybridErange setup + // get maximal w2 for this w1 + const size_t maxW2 = getMaxInteractionWidth( w1, energy.getMaxInternalLoopSize1()); + // screen for left boundaries in seq2 + for (i2=hybridErange.r2.to+1; i2-- > hybridErange.r2.from; ) { + w2 = j2-i2+1; + // w2 width check obsolete due to hybridErange setup + // check if widths' combination possible + if ( w2 > maxW2 || w1 > getMaxInteractionWidth( w2, energy.getMaxInternalLoopSize2()) ) + { + // combination not possible + hybridE_pq(i1,i2) = E_INF; + continue; + } + // check if left boundary (i1,i2) is complementary + if (!energy.areComplementary(i1,i2)) { + // interaction not possible + hybridE_pq(i1,i2) = E_INF; + continue; + } + + // check if this cell is to be computed (!=E_INF) + if( E_isNotINF( hybridE_pq(i1,i2) ) ) { + + // compute entry + + // either interaction initiation + if ( w1==1 && w2==1 ) { + curMinE = energy.getE_init(); + } else { + // or only internal loop energy (nothing between i and j) + curMinE = energy.getE_interLeft(i1,j1,i2,j2) + + hybridE_pq(j1,j2); + } + + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + if (w1 > 2 && w2 > 2) { + for (k1=std::min(j1-1,i1+energy.getMaxInternalLoopSize1()+1); k1>i1; k1--) { + for (k2=std::min(j2-1,i2+energy.getMaxInternalLoopSize2()+1); k2>i2; k2--) { + // check if (k1,k2) are valid left boundary + if ( E_isNotINF( hybridE_pq(k1,k2) ) ) { + curMinE = std::min( curMinE, + (energy.getE_interLeft(i1,k1,i2,k2) + + hybridE_pq(k1,k2) ) + ); + } + } + } + } + // store value + hybridE_pq(i1,i2) = curMinE; + // update mfe if needed + updateOptima( i1,j1,i2,j2, hybridE_pq(i1,i2), true ); + continue; + } + } + } + +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2d:: +traceBack( Interaction & interaction ) +{ + // check if something to trace + if (interaction.basePairs.size() < 2) { + return; + } + +#if IN_DEBUG_MODE + // sanity checks + if ( ! interaction.isValid() ) { + throw std::runtime_error("PredictorMfe2d::traceBack() : given interaction not valid"); + } + if ( interaction.basePairs.size() != 2 ) { + throw std::runtime_error("PredictorMfe2d::traceBack() : given interaction does not contain boundaries only"); + } +#endif + + // check for single interaction + if (interaction.basePairs.at(0).first == interaction.basePairs.at(1).first) { + // delete second boundary (identical to first) + interaction.basePairs.resize(1); + // update done + return; + } + + // ensure sorting + interaction.sort(); + // get indices in hybridE for boundary base pairs + size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), + j1 = energy.getIndex1(interaction.basePairs.at(1)), + i2 = energy.getIndex2(interaction.basePairs.at(0)), + j2 = energy.getIndex2(interaction.basePairs.at(1)); + + + // refill submatrix of mfe interaction + fillHybridE( j1, j2, i1, i2 ); + + // the currently traced value for i1-j1, i2-j2 + E_type curE = hybridE_pq(i1,i2); + + // trace back + while( i1 != j1 ) { + // check if just internal loop + if ( E_equal( curE, (energy.getE_interLeft(i1,j1,i2,j2) ) + + hybridE_pq(j1,j2)) ) + { + break; + } + // check all interval splits + if ( (j1-i1) > 1 && (j2-i2) > 1) { + // temp variables + size_t k1,k2; + bool traceNotFound = true; + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + for (k1=std::min(j1-1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { + for (k2=std::min(j2-1,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { + // check if (k1,k2) are valid left boundary + if ( E_isNotINF( hybridE_pq(k1,k2) ) ) { + if ( E_equal( curE, + (energy.getE_interLeft(i1,k1,i2,k2) + + hybridE_pq(k1,k2)) ) ) + { + // stop searching + traceNotFound = false; + // store splitting base pair + interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); + // trace right part of split + i1=k1; + i2=k2; + curE = hybridE_pq(i1,i2); + } + } + } + } + } + // do until only right boundary is left over + } + + // sort final interaction (to make valid) (faster than calling sort()) + if (interaction.basePairs.size() > 2) { + Interaction::PairingVec & bps = interaction.basePairs; + // shift all added base pairs to the front + for (size_t i=2; i + +/** + * Memory efficient predictor for RNAup-like computation, i.e. full + * DP-implementation without seed-heuristic, using 2D matrices + * + * @author Martin Mann + * + */ +class PredictorMfe2d: public PredictorMfe { + +protected: + + //! matrix type to hold the mfe energies for interaction site starts + typedef boost::numeric::ublas::matrix E2dMatrix; + +public: + + /** + * Constructs a predictor and stores the energy and output handler + * + * @param energy the interaction energy handler + * @param output the output handler to report mfe interactions to + */ + PredictorMfe2d( const InteractionEnergy & energy, OutputHandler & output ); + + virtual ~PredictorMfe2d(); + + /** + * Computes the mfe for the given sequence ranges (i1-j1) in the first + * sequence and (i2-j2) in the second sequence and reports it to the output + * handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint() + ); + +protected: + + //! access to the interaction energy handler of the super class + using PredictorMfe::energy; + + //! access to the output handler of the super class + using PredictorMfe::output; + + // TODO provide all data structures as arguments to make predict() call threadsafe + + //! energy of all interaction hybrids that end in position p (seq1) and + //! q (seq2) + E2dMatrix hybridE_pq; + + //! the current range of computed entries within hybridE_pq set by initHybridE() + InteractionRange hybridErange; + +protected: + + /** + * Initializes the hybridE_pq table for the computation for interactions + * ending in p=j1 and q=j2 + * + * @param j1 end of the interaction within seq 1 + * @param j2 end of the interaction within seq 2 + * @param outConstraint constrains the interactions reported to the output handler + * @param i1init smallest value for i1 + * @param i2init smallest value for i2 + */ + void + initHybridE( const size_t j1, const size_t j2 + , const OutputConstraint & outConstraint + , const size_t i1init=0, const size_t i2init=0 + ); + + /** + * Computes all entries of the hybridE matrix for interactions ending in + * p=j1 and q=j2 and report all valid interactions to updateOptima() + * + * @param j1 end of the interaction within seq 1 + * @param j2 end of the interaction within seq 2 + * @param outConstraint constrains the interactions reported to the output handler + * @param i1init smallest value for i1 + * @param i2init smallest value for i2 + * + */ + void + fillHybridE( const size_t j1, const size_t j2 + , const OutputConstraint & outConstraint + , const size_t i1init=0, const size_t i2init=0 + ); + + /** + * Fills a given interaction (boundaries given) with the according + * hybridizing base pairs. + * @param interaction IN/OUT the interaction to fill + */ + void + traceBack( Interaction & interaction ); + + /** + * Identifies the next best interaction with an energy equal to or higher + * than the given interaction. The new interaction will not overlap any + * index range stored in reportedInteractions. + * + * NOTE: this is not possible for this predictor (unless a full recomputation + * of the matrices is done). Thus, calling this method raises an exception. + * + * @param curBest ignored (see method comment) + */ + virtual + void + getNextBest( Interaction & curBest ); + +}; + +#endif /* PREDICTORMFE2D_H_ */ diff --git a/src/PredictorMfe2dHeuristic.cpp b/src/PredictorMfe2dHeuristic.cpp new file mode 100644 index 00000000..a435b55e --- /dev/null +++ b/src/PredictorMfe2dHeuristic.cpp @@ -0,0 +1,337 @@ + +#include "PredictorMfe2dHeuristic.h" + +#include + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe2dHeuristic:: +PredictorMfe2dHeuristic( const InteractionEnergy & energy, OutputHandler & output ) + : PredictorMfe(energy,output) + , hybridE( 0,0 ) +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe2dHeuristic:: +~PredictorMfe2dHeuristic() +{ + // clean up +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dHeuristic:: +predict( const IndexRange & r1 + , const IndexRange & r2 + , const OutputConstraint & outConstraint + ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting mfe interactions heuristically in O(n^2) space and time..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + +#if IN_DEBUG_MODE + // check indices + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMfe2dHeuristic::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + + // set index offset + energy.setOffset1(r1.from); + energy.setOffset2(r2.from); + + // resize matrix + hybridE.resize( std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ) + , std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ) ); + + // temp vars + size_t i1,i2,w1,w2; + + // init matrix + bool isValidCell = true; + for (i1=0; i1 0;) { + for (i2=hybridE.size2(); i2-- > 0;) { + // direct cell access + curCell = &(hybridE(i1,i2)); + // check if left side can pair + if (E_isINF(curCell->E)) { + continue; + } + // current + curCellEtotal = energy.getE(i1,curCell->j1,i2,curCell->j2,curCell->E); + + // TODO PARALLELIZE THIS DOUBLE LOOP ?! + // iterate over all loop sizes w1 (seq1) and w2 (seq2) (minus 1) + for (w1=1; w1-1 <= energy.getMaxInternalLoopSize1() && i1+w1E)) { + continue; + } + // check if interaction length is within boundary + if ( (rightExt->j1 +1 -i1) > energy.getAccessibility1().getMaxLength() + || (rightExt->j2 +1 -i2) > energy.getAccessibility2().getMaxLength() ) + { + continue; + } + // compute energy for this loop sizes + curE = energy.getE_interLeft(i1,i1+w1,i2,i2+w2) + rightExt->E; + // check if this combination yields better energy + curEtotal = energy.getE(i1,rightExt->j1,i2,rightExt->j2,curE); + if ( curEtotal < curCellEtotal ) + { + // update current best for this left boundary + // copy right boundary + *curCell = *rightExt; + // set new energy + curCell->E = curE; + // store total energy to avoid recomputation + curCellEtotal = curEtotal; + } + + } // w2 + } // w1 + + // update mfe if needed + updateOptima( i1,curCell->j1, i2,curCell->j2, curCellEtotal, false ); + + } // i2 + } // i1 + +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dHeuristic:: +traceBack( Interaction & interaction ) +{ + // check if something to trace + if (interaction.basePairs.size() < 2) { + return; + } + +#if IN_DEBUG_MODE + // sanity checks + if ( ! interaction.isValid() ) { + throw std::runtime_error("PredictorMfe2dHeuristic::traceBack() : given interaction not valid"); + } + if ( interaction.basePairs.size() != 2 ) { + throw std::runtime_error("PredictorMfe2dHeuristic::traceBack() : given interaction does not contain boundaries only"); + } +#endif + + // check for single interaction + if (interaction.basePairs.at(0).first == interaction.basePairs.at(1).first) { + // delete second boundary (identical to first) + interaction.basePairs.resize(1); + // update done + return; + } + + // ensure sorting + interaction.sort(); + // get indices in hybridE for boundary base pairs + size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), + i2 = energy.getIndex2(interaction.basePairs.at(0)); + const size_t j1 = energy.getIndex1(interaction.basePairs.at(1)); + const size_t j2 = energy.getIndex2(interaction.basePairs.at(1)); + + + // the currently traced value for i1-j1, i2-j2 + E_type curE = hybridE(i1,i2).E; + assert( hybridE(i1,i2).j1 == j1 ); + assert( hybridE(i1,i2).j2 == j2 ); + assert( i1 <= j1 ); + assert( i2 <= j2 ); + assert( j1 < hybridE.size1() ); + assert( j2 < hybridE.size2() ); + + // trace back + // temp variables + size_t k1,k2; + // do until only right boundary is left over + while( (j1-i1) > 1 ) { + const BestInteraction * curCell = NULL; + bool traceNotFound = true; + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + for (k1=std::min(j1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { + for (k2=std::min(j2,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { + // temp access to current cell + curCell = &(hybridE(k1,k2)); + // check if right boundary is equal (part of the heuristic) + if ( curCell->j1 == j1 && curCell->j2 == j2 && + // and energy is the source of curE + E_equal( curE, (energy.getE_interLeft(i1,k1,i2,k2) + curCell->E ) ) ) + { + // stop searching + traceNotFound = false; + // store splitting base pair if not last one of interaction range + if ( k1 < j1 ) { + interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); + } + // trace right part of split + i1=k1; + i2=k2; + curE = curCell->E; + } + } + } + assert( !traceNotFound ); + } +#if IN_DEBUG_MODE + if ( (j2-i2) > 1 ) { + throw std::runtime_error("PredictorMfe2dHeuristic::traceBack() : trace leaves ji 2) { + Interaction::PairingVec & bps = interaction.basePairs; + // shift all added base pairs to the front + for (size_t i=2; i 0;) { + // ensure interaction site start is not covered + if (reportedInteractions.first.covers(i1)) { + continue; + } + for (i2=hybridE.size2(); i2-- > 0;) { + // ensure interaction site start is not covered + if (reportedInteractions.second.covers(i2)) { + continue; + } + // direct cell access + curCell = &(hybridE(i1,i2)); + // check if left side can pair + if (E_isINF(curCell->E)) + { + continue; + } + // get overall energy of the interaction + curCellE = energy.getE(i1,curCell->j1,i2,curCell->j2,curCell->E); + // or energy is too low to be considered + // or energy is higher than current best found so far + if (curCellE < curBestE || curCellE >= curBestCellE ) + { + continue; + } + // ensure site is not overlapping + r1.from = i1; + r1.to = curCell->j1; + if ( reportedInteractions.first.overlaps( r1 )) { + continue; + } + r2.from = i2; + r2.to = curCell->j2; + if ( reportedInteractions.second.overlaps( r2 )) { + continue; + } + //// FOUND THE NEXT BETTER SOLUTION + // overwrite current best found so far + curBestCell = curCell; + curBestCellE = curCellE; + curBestCellStart.first = i1; + curBestCellStart.second = i2; + + } // i2 + } // i1 + + // overwrite curBest + curBest.energy = curBestCellE; + curBest.basePairs.resize(2); + if (E_isNotINF(curBestCellE)) { + curBest.basePairs[0] = energy.getBasePair( curBestCellStart.first, curBestCellStart.second ); + curBest.basePairs[1] = energy.getBasePair( curBestCell->j1, curBestCell->j2 ); + } +} + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/PredictorMfe2dHeuristic.h b/src/PredictorMfe2dHeuristic.h new file mode 100644 index 00000000..113aab49 --- /dev/null +++ b/src/PredictorMfe2dHeuristic.h @@ -0,0 +1,129 @@ + +#ifndef PREDICTORMFE2DHEURISTIC_H_ +#define PREDICTORMFE2DHEURISTIC_H_ + +#include "PredictorMfe.h" +#include "Interaction.h" + +#include + +/** + * Memory efficient interaction predictor that uses a heuristic to + * find the mfe or a close-to-mfe interaction. + * + * To this end, for each interaction start i1,i2 only the optimal right side + * interaction with boundaries j1,j2 is considered in the recursion instead of + * all possible interaction ranges. + * + * This yields a quadratic time and space complexity. + * + * @author Martin Mann + * + */ +class PredictorMfe2dHeuristic: public PredictorMfe { + +protected: + + /** + * Describes the currently best interaction found for a left interaction + * boundary i1,i2 + */ + class BestInteraction { + public: + + //! init data + BestInteraction( const E_type E=E_INF, const size_t j1=RnaSequence::lastPos, const size_t j2=RnaSequence::lastPos ) + : E(E), j1(j1), j2(j2) + {} + + public: + //! energy of the interaction + E_type E; + //! right end of the interaction in seq1 + size_t j1; + //! right end of the interaction in seq2 + size_t j2; + }; + + //! matrix type to hold the mfe energies and boundaries for interaction site starts + typedef boost::numeric::ublas::matrix E2dMatrix; + +public: + + /** + * Constructs a predictor and stores the energy and output handler + * + * @param energy the interaction energy handler + * @param output the output handler to report mfe interactions to + */ + PredictorMfe2dHeuristic( const InteractionEnergy & energy, OutputHandler & output ); + + virtual ~PredictorMfe2dHeuristic(); + + /** + * Computes the mfe for the given sequence ranges (i1-j1) in the first + * sequence and (i2-j2) in the second sequence and reports it to the output + * handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint() ); + +protected: + + //! access to the interaction energy handler of the super class + using PredictorMfe::energy; + + //! access to the output handler of the super class + using PredictorMfe::output; + + //! access to the list of reported interaction ranges of the super class + using PredictorMfe::reportedInteractions; + + // TODO provide all data structures as arguments to make predict() call threadsafe + + //! energy of all interaction hybrids starting in i1,i2 + E2dMatrix hybridE; + +protected: + + /** + * Computes all entries of the hybridE matrix + */ + virtual + void + fillHybridE(); + + /** + * Fills a given interaction (boundaries given) with the according + * hybridizing base pairs. + * @param interaction IN/OUT the interaction to fill + */ + virtual + void + traceBack( Interaction & interaction ); + + /** + * Identifies the next best interaction with an energy equal to or higher + * than the given interaction. The new interaction will not overlap any + * index range stored in reportedInteractions. + * + * @param curBest IN/OUT the current best interaction to be replaced with one + * of equal or higher energy not overlapping with any reported + * interaction so far; an interaction with energy E_INF is set, if + * there is no better interaction left + */ + virtual + void + getNextBest( Interaction & curBest ); + +}; + +#endif /* PREDICTORMFE2DHEURISTIC_H_ */ diff --git a/src/PredictorMfe2dHeuristicSeed.cpp b/src/PredictorMfe2dHeuristicSeed.cpp new file mode 100644 index 00000000..046d51d0 --- /dev/null +++ b/src/PredictorMfe2dHeuristicSeed.cpp @@ -0,0 +1,428 @@ + +#include "PredictorMfe2dHeuristicSeed.h" + +#include + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe2dHeuristicSeed:: +PredictorMfe2dHeuristicSeed( const InteractionEnergy & energy + , OutputHandler & output + , const SeedConstraint & seedConstraint + ) + : PredictorMfe2dHeuristic(energy,output) + , seedHandler( energy, seedConstraint ) +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe2dHeuristicSeed:: +~PredictorMfe2dHeuristicSeed() +{ + // clean up +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dHeuristicSeed:: +predict( const IndexRange & r1 + , const IndexRange & r2 + , const OutputConstraint & outConstraint ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting mfe interactions with seed heuristically in O(n^2) space and time..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + +#if IN_DEBUG_MODE + // check indices + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMfe2dHeuristicSeed::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + + // set index offset + energy.setOffset1(r1.from); + energy.setOffset2(r2.from); + seedHandler.setOffset1(r1.from); + seedHandler.setOffset2(r2.from); + + const size_t hybridEsize1 = std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ); + const size_t hybridEsize2 = std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ); + + + // compute seed interactions for whole range + // and check if any seed possible + if (seedHandler.fillSeed( 0, hybridEsize1-1, 0, hybridEsize2-1 ) == 0) { + // trigger empty interaction reporting + initOptima(outConstraint); + reportOptima(outConstraint); + // stop computation + return; + } + + // resize matrix + hybridE.resize( hybridEsize1, hybridEsize2 ); + + // temp vars + size_t i1,i2,w1,w2; + + // init hybridE matrix + bool isValidCell = true; + for (i1=0; i1 no hybrid update since updateOptima overwritten + PredictorMfe2dHeuristic::fillHybridE(); + + // check if any interaction possible + // if not no seed-containing interaction is possible neither + if (!(this->mfeInteractions.begin()->energy < tmpOutConstraint.maxE)) { + // stop computation since no favorable interaction found + reportOptima(tmpOutConstraint); + return; + } + + // init mfe for later updates + initOptima( outConstraint ); + + // compute entries + // current minimal value + E_type curE = E_INF, curEtotal = E_INF, curCellEtotal = E_INF; + BestInteraction * curCell = NULL; + const BestInteraction * rightExt = NULL; + + // iterate (decreasingly) over all left interaction starts + hybridE_seed.resize( hybridE.size1(), hybridE.size2() ); + for (i1=hybridE_seed.size1(); i1-- > 0;) { + for (i2=hybridE_seed.size2(); i2-- > 0;) { + + // check if left side can pair + if (E_isINF(hybridE(i1,i2).E)) { + continue; + } + // direct cell access + curCell = &(hybridE_seed(i1,i2)); + // reset temporary variables + curEtotal = E_INF; + curCellEtotal = E_INF; + + /////////////////////////////////////////////////////////////////// + // check all extensions of interactions CONTAINING a seed already + /////////////////////////////////////////////////////////////////// + + // TODO PARALLELIZE THIS DOUBLE LOOP ?! + // iterate over all loop sizes w1 (seq1) and w2 (seq2) + for (w1=1; w1-1 <= energy.getMaxInternalLoopSize1() && i1+w1E)) { + continue; + } + // check if interaction length is within boundary + if ( (rightExt->j1 +1 -i1) > energy.getAccessibility1().getMaxLength() + || (rightExt->j2 +1 -i2) > energy.getAccessibility2().getMaxLength() ) + { + continue; + } + // compute energy for this loop sizes + curE = energy.getE_interLeft(i1,i1+w1,i2,i2+w2) + rightExt->E; + // check if this combination yields better energy + curEtotal = energy.getE(i1,rightExt->j1,i2,rightExt->j2,curE); + if ( curEtotal < curCellEtotal ) + { + // update current best for this left boundary + // copy right boundary + *curCell = *rightExt; + // set new energy + curCell->E = curE; + // store overall energy + curCellEtotal = curEtotal; + } + } // w2 + } // w1 + + /////////////////////////////////////////////////////////////////// + // check if seed is starting here + /////////////////////////////////////////////////////////////////// + + // check if seed is possible for this left boundary + if ( E_isNotINF( seedHandler.getSeedE(i1,i2) ) ) { + // get right extension + w1 = seedHandler.getSeedLength1(i1,i2)-1; assert(i1+w1 < hybridE.size1()); + w2 = seedHandler.getSeedLength2(i1,i2)-1; assert(i2+w2 < hybridE.size2()); + rightExt = &(hybridE(i1+w1,i2+w2)); + // get energy of seed interaction with best right extension + curE = seedHandler.getSeedE(i1,i2) + rightExt->E; + // check if this combination yields better energy + curEtotal = energy.getE(i1,rightExt->j1,i2,rightExt->j2,curE); + if ( curEtotal < curCellEtotal ) + { + // update current best for this left boundary + // copy right boundary + *curCell = *rightExt; + // set new energy + curCell->E = curE; + // store total energy + curCellEtotal = curEtotal; + } + } + + // update mfe if needed (call superclass update routine) + PredictorMfe2dHeuristic::updateOptima( i1,curCell->j1, i2,curCell->j2, curCellEtotal, false ); + + } // i2 + } // i1 + + + // report mfe interaction + reportOptima( outConstraint ); + +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dHeuristicSeed:: +traceBack( Interaction & interaction ) +{ + // check if something to trace + if (interaction.basePairs.size() < 2) { + return; + } + +#if IN_DEBUG_MODE + // sanity checks + if ( ! interaction.isValid() ) { + throw std::runtime_error("PredictorMfe2dHeuristicSeed::traceBack() : given interaction not valid"); + } + if ( interaction.basePairs.size() != 2 ) { + throw std::runtime_error("PredictorMfe2dHeuristicSeed::traceBack() : given interaction does not contain boundaries only"); + } +#endif + + // check for single interaction + if (interaction.basePairs.at(0).first == interaction.basePairs.at(1).first) { + // delete second boundary (identical to first) + interaction.basePairs.resize(1); + // update done + return; + } + + // ensure sorting + interaction.sort(); + // get indices in hybridE for boundary base pairs + size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), + i2 = energy.getIndex2(interaction.basePairs.at(0)); + const size_t j1 = energy.getIndex1(interaction.basePairs.at(1)); + const size_t j2 = energy.getIndex2(interaction.basePairs.at(1)); + + + // the currently traced value for i1-j1, i2-j2 + E_type curE = hybridE_seed(i1,i2).E; + assert( hybridE_seed(i1,i2).j1 == j1 ); + assert( hybridE_seed(i1,i2).j2 == j2 ); + assert( i1 <= j1 ); + assert( i2 <= j2 ); + assert( j1 < hybridE_seed.size1() ); + assert( j2 < hybridE_seed.size2() ); + + // trace back + // temp variables + size_t k1,k2; + // do until only right boundary is left over + while( (j1-i1) > 1 ) { + const BestInteraction * curCell = NULL; + bool traceNotFound = true; + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + for (k1=std::min(j1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { + for (k2=std::min(j2,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { + // temp access to current cell + curCell = &(hybridE_seed(k1,k2)); + // check if right boundary is equal (part of the heuristic) + if ( curCell->j1 == j1 && curCell->j2 == j2 && + // and energy is the source of curE + E_equal( curE, (energy.getE_interLeft(i1,k1,i2,k2) + curCell->E ) ) ) + { + // stop searching + traceNotFound = false; + // store splitting base pair + if (k1 < j1) { + interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); + } + // trace right part of split + i1=k1; + i2=k2; + curE = curCell->E; + } + } + } + // has to be interaction with seed on the left starting at (i1,i2)..seed..(k1,k2)..rest..(j1,j2) + if (traceNotFound) { + assert(E_isNotINF(seedHandler.getSeedE(i1,i2))); + k1 = i1+seedHandler.getSeedLength1(i1,i2)-1; assert(k1E) )); + // store seed information + interaction.setSeedRange( + energy.getBasePair(i1,i2), + energy.getBasePair(k1,k2), + energy.getE(i1,k1,i2,k2,seedHandler.getSeedE(i1,i2))+energy.getE_init()); + // traceback seed base pairs (excludes right most = (k1,k2)) + seedHandler.traceBackSeed( interaction, i1, i2 ); + // update position to point after seed interaction + i1 = k1; + i2 = k2; + // traceback remaining right interaction via hybridE + if (i1 1 ) { + throw std::runtime_error("PredictorMfe2dHeuristicSeed::traceBack() : trace leaves ji 2) { + Interaction::PairingVec & bps = interaction.basePairs; + // shift all added base pairs to the front + for (size_t i=2; i 0;) { + // ensure interaction site start is not covered + if (reportedInteractions.first.covers(i1)) { + continue; + } + for (i2=hybridE_seed.size2(); i2-- > 0;) { + // ensure interaction site start is not covered + if (reportedInteractions.second.covers(i2)) { + continue; + } + // direct cell access + curCell = &(hybridE_seed(i1,i2)); + // check if left side can pair + if (E_isINF(curCell->E)) + { + continue; + } + // get overall energy of the interaction + curCellE = energy.getE(i1,curCell->j1,i2,curCell->j2,curCell->E); + // or energy is too low to be considered + // or energy is higher than current best found so far + if (curCellE < curBestE || curCellE >= curBestCellE ) + { + continue; + } + // ensure site is not overlapping + r1.from = i1; + r1.to = curCell->j1; + if ( reportedInteractions.first.overlaps( r1 )) { + continue; + } + r2.from = i2; + r2.to = curCell->j2; + if ( reportedInteractions.second.overlaps( r2 )) { + continue; + } + //// FOUND THE NEXT BETTER SOLUTION + // overwrite current best found so far + curBestCell = curCell; + curBestCellE = curCellE; + curBestCellStart.first = i1; + curBestCellStart.second = i2; + + } // i2 + } // i1 + + // overwrite curBest + curBest.basePairs.resize(2); + curBest.energy = curBestCellE; + if (E_isNotINF(curBestCellE)) { + curBest.basePairs[0] = energy.getBasePair( curBestCellStart.first, curBestCellStart.second ); + curBest.basePairs[1] = energy.getBasePair( curBestCell->j1, curBestCell->j2 ); + } + +} + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/PredictorMfe2dHeuristicSeed.h b/src/PredictorMfe2dHeuristicSeed.h new file mode 100644 index 00000000..f6adb3e2 --- /dev/null +++ b/src/PredictorMfe2dHeuristicSeed.h @@ -0,0 +1,114 @@ + +#ifndef PREDICTORMFE2DHEURISTICSEED_H_ +#define PREDICTORMFE2DHEURISTICSEED_H_ + +#include "PredictorMfe2dHeuristic.h" +#include "SeedHandlerIdxOffset.h" + + +/** + * Memory efficient interaction predictor that uses both qualitative heuristics + * (interactions have to have a seed interaction) and performance heuristics + * (not all possible interactions considered) + * + * To this end, for each interaction start i1,i2 only the optimal right side + * interaction with boundaries j1,j2 is considered in the recursion instead of + * all possible interaction ranges. + * + * This yields a quadratic time and space complexity. + * + * @author Martin Mann + * + */ +class PredictorMfe2dHeuristicSeed: public PredictorMfe2dHeuristic { + + + //! matrix type to hold the mfe energies and boundaries for interaction site starts + typedef PredictorMfe2dHeuristic::E2dMatrix E2dMatrix; + +public: + + /** + * Constructs a predictor and stores the energy and output handler + * + * @param energy the interaction energy handler + * @param output the output handler to report mfe interactions to + * @param seedConstraint the seed constraint to be applied + */ + PredictorMfe2dHeuristicSeed( const InteractionEnergy & energy + , OutputHandler & output + , const SeedConstraint & seedConstraint ); + + virtual ~PredictorMfe2dHeuristicSeed(); + + /** + * Computes the mfe for the given sequence ranges (i1-j1) in the first + * sequence and (i2-j2) in the second sequence and reports it to the output + * handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint()); + +protected: + + //! access to the interaction energy handler of the super class + using PredictorMfe2dHeuristic::energy; + + //! access to the output handler of the super class + using PredictorMfe2dHeuristic::output; + + //! access to the list of reported interaction ranges of the super class + using PredictorMfe2dHeuristic::reportedInteractions; + + // TODO provide all data structures as arguments to make predict() call threadsafe + + //! energy of all interaction hybrids that end in position p (seq1) and + //! q (seq2) + using PredictorMfe2dHeuristic::hybridE; + + //! the best hybridization energy including a seed for start i1,i2 + E2dMatrix hybridE_seed; + + //! handler to generate and access seed information with idx offset + SeedHandlerIdxOffset seedHandler; + +protected: + + /** + * Fills a given interaction (boundaries given) with the according + * hybridizing base pairs. + * @param interaction IN/OUT the interaction to fill + */ + virtual + void + traceBack( Interaction & interaction ); + + + /** + * Identifies the next best interaction (containing a seed) + * with an energy equal to or higher + * than the given interaction. The new interaction will not overlap any + * index range stored in reportedInteractions. + * + * @param curBest IN/OUT the current best interaction to be replaced with one + * of equal or higher energy not overlapping with any reported + * interaction so far; an interaction with energy E_INF is set, if + * there is no better interaction left + */ + virtual + void + getNextBest( Interaction & curBest ); + + +}; + + +#endif /* PREDICTORMFE2DHEURISTICSEED_H_ */ diff --git a/src/PredictorMfe2dSeed.cpp b/src/PredictorMfe2dSeed.cpp new file mode 100644 index 00000000..9f14f107 --- /dev/null +++ b/src/PredictorMfe2dSeed.cpp @@ -0,0 +1,352 @@ + +#include "PredictorMfe2dSeed.h" + +////////////////////////////////////////////////////////////////////////// + +PredictorMfe2dSeed:: +PredictorMfe2dSeed( + const InteractionEnergy & energy + , OutputHandler & output + , const SeedConstraint & seedConstraint ) + : + PredictorMfe2d(energy,output) + , seedHandler(energy,seedConstraint) + , hybridE_pq_seed() +{ + assert( seedHandler.getConstraint().getBasePairs() > 1 ); +} + +////////////////////////////////////////////////////////////////////////// + +PredictorMfe2dSeed:: +~PredictorMfe2dSeed() +{ +} + +////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dSeed:: +predict( const IndexRange & r1, const IndexRange & r2 + , const OutputConstraint & outConstraint ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting mfe interactions with seed in O(n^2) space and O(n^4) time..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + + // suboptimal setup check + if (outConstraint.reportMax>1 && outConstraint.reportOverlap != OutputConstraint::ReportOverlap::OVERLAP_BOTH) { + throw std::runtime_error("PredictorMfe2dSeed : the enumeration of non-overlapping suboptimal interactions is not supported in this prediction mode"); + } + +#if IN_DEBUG_MODE + // check indices + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMfe2d::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + // setup index offset + energy.setOffset1(r1.from); + energy.setOffset2(r2.from); + seedHandler.setOffset1(r1.from); + seedHandler.setOffset2(r2.from); + + const size_t hybridE_pqsize1 = std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ); + const size_t hybridE_pqsize2 = std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ); + + + // compute seed interactions for whole range + // and check if any seed possible + if (seedHandler.fillSeed( 0, hybridE_pqsize1-1, 0, hybridE_pqsize2-1 ) == 0) { + // trigger empty interaction reporting + initOptima(outConstraint); + reportOptima(outConstraint); + // stop computation + return; + } + + // resize matrix + hybridE_pq.resize( hybridE_pqsize1, hybridE_pqsize2 ); + hybridE_pq_seed.resize( hybridE_pqsize1, hybridE_pqsize2 ); + + // initialize mfe interaction for updates + initOptima( outConstraint ); + + // for all right ends j1 + for (size_t j1 = hybridE_pq.size1(); j1-- > 0; ) { + // check if j1 is accessible + if (!energy.isAccessible1(j1)) + continue; + // iterate over all right ends j2 + for (size_t j2 = hybridE_pq.size2(); j2-- > 0; ) { + // check if j2 is accessible + if (!energy.isAccessible2(j2)) + continue; + // check if base pair (j1,j2) possible + if (!energy.areComplementary( j1, j2 )) + continue; + + // compute hybridE_pq_seed and update mfe via PredictorMfe2d::updateOptima() + fillHybridE_seed( j1, j2 ); + } + } + + // report mfe interaction + reportOptima( outConstraint ); + +} + +////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dSeed:: +fillHybridE_seed( const size_t j1, const size_t j2, const size_t i1min, const size_t i2min ) +{ + + // compute hybridE_pq + fillHybridE( j1, j2, i1min, i2min ); + + assert(i1min <= j1); + assert(i2min <= j2); + assert(hybridErange.r1.from <= i1min); + assert(hybridErange.r2.from <= i2min); + assert(j1==hybridErange.r1.to); + assert(j2==hybridErange.r2.to); + assert(j1 i1range.from; ) { + // screen for left boundaries i2 in seq2 + for (i2=1+i2range.to; i2-- > i2range.from; ) { + + // compute entry + curMinE = E_INF; + + // check if this cell is to be computed (!=E_INF) + if( E_isNotINF( hybridE_pq(i1,i2) ) ) { + + // base case = incorporate mfe seed starting at (i1,i2) + // + interaction on right side up to (p,q) + if ( E_isNotINF( seedHandler.getSeedE(i1,i2) ) ) { + // decode right mfe boundary + k1 = i1+seedHandler.getSeedLength1(i1,i2)-1; + k2 = i2+seedHandler.getSeedLength2(i1,i2)-1; + // compute overall energy of seed+upToPQ + if ( k1 <= j1 && k2 <= j2 && E_isNotINF(hybridE_pq(k1,k2))) { + curMinE = seedHandler.getSeedE(i1,i2) + hybridE_pq(k1,k2); + } + } + + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + // where k1..j1 contains a seed + for (k1=std::min(i1range.to,i1+energy.getMaxInternalLoopSize1()+1); k1>i1; k1--) { + for (k2=std::min(i2range.to,i2+energy.getMaxInternalLoopSize2()+1); k2>i2; k2--) { + // check if (k1,k2) are valid left boundaries including a seed + if ( E_isNotINF( hybridE_pq_seed(k1,k2) ) ) { + curMinE = std::min( curMinE, + (energy.getE_interLeft(i1,k1,i2,k2) + + hybridE_pq_seed(k1,k2) ) + ); + } + } + } + // update mfe if needed (call super class) + if (E_isNotINF(curMinE)) { + PredictorMfe2d::updateOptima( i1,j1,i2,j2, curMinE, true ); + } + } + + // store value + hybridE_pq_seed(i1,i2) = curMinE; + } + } + +} + +////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe2dSeed:: +traceBack( Interaction & interaction ) +{ + // check if something to trace + if (interaction.basePairs.size() < 2) { + return; + } + +#if IN_DEBUG_MODE + // sanity checks + if ( ! interaction.isValid() ) { + throw std::runtime_error("PredictorMfe2dSeed::traceBack() : given interaction not valid"); + } + if ( interaction.basePairs.size() != 2 ) { + throw std::runtime_error("PredictorMfe2dSeed::traceBack() : given interaction does not contain boundaries only"); + } +#endif + + // check for single interaction + if (interaction.basePairs.at(0).first == interaction.basePairs.at(1).first) { + // delete second boundary (identical to first) + interaction.basePairs.resize(1); + // update done + return; + } + + // ensure sorting + interaction.sort(); + // get indices in hybridE for boundary base pairs + size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), + j1 = energy.getIndex1(interaction.basePairs.at(1)), + i2 = energy.getIndex2(interaction.basePairs.at(0)), + j2 = energy.getIndex2(interaction.basePairs.at(1)) + ; + +#if IN_DEBUG_MODE + // check if intervals are larger enough to contain a seed + if (std::min(j1-i1,j2-i2)+1 < seedHandler.getConstraint().getBasePairs()) { + // no seed possible, abort computation + throw std::runtime_error("PredictorMfe2dSeed::traceBack() : given boundaries "+toString(interaction)+" can not hold a seed of "+toString(seedHandler.getConstraint().getBasePairs())+" base pairs"); + } +#endif + + // temp variables + size_t k1,k2; + + + // refill submatrices of mfe interaction + fillHybridE_seed( j1, j2, i1, i2 ); + + // the currently traced value for i1-j1, i2-j2 + E_type curE = hybridE_pq_seed(i1,i2); + + // trace back + bool seedNotTraced = true; + while( i1 != j1 ) { + + // check if we still have to find the seed + if (seedNotTraced) { + + // check base case == seed only + if ( E_isNotINF( seedHandler.getSeedE(i1,i2) ) ) { + + // right boundary of seed + k1 = i1 + seedHandler.getSeedLength1(i1,i2) -1; + k2 = i2 + seedHandler.getSeedLength2(i1,i2) -1; + + // check if correct trace + if ( E_equal( curE, seedHandler.getSeedE(i1,i2) + hybridE_pq(k1,k2) ) ) { + // store seed information + interaction.setSeedRange( + energy.getBasePair(i1,i2), + energy.getBasePair(k1,k2), + energy.getE(i1,k1,i2,k2,seedHandler.getSeedE(i1,i2))+energy.getE_init()); + // trace back seed base pairs + seedHandler.traceBackSeed( interaction, i1, i2 ); + // continue after seed + i1 = k1; + i2 = k2; + curE = hybridE_pq(k1,k2); + seedNotTraced = false; + continue; + } + } + // check all interval splits + if ( (j1-i1) > 1 && (j2-i2) > 1) { + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + // where k1..j1 contains a seed + bool traceNotFound = true; + for (k1=std::min(j1-seedHandler.getConstraint().getBasePairs()+1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { + for (k2=std::min(j2-seedHandler.getConstraint().getBasePairs()+1,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { + // check if (k1,k2) are valid left boundaries including a seed + if ( E_isNotINF( hybridE_pq_seed(k1,k2) ) ) { + // check if correct split + if (E_equal ( curE, + (energy.getE_interLeft(i1,k1,i2,k2) + + hybridE_pq_seed(k1,k2) ) + ) ) + { + // update trace back boundary + i1=k1; + i2=k2; + curE= hybridE_pq_seed(k1,k2); + // stop search splits + traceNotFound = false; + // store splitting base pair + interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); + } + } + } // k2 + } // k1 + assert(!traceNotFound); + } + } + // seed was already traced, do "normal" interaction trace + else { + // create temporary data structure to be filed + Interaction rightSide( *interaction.s1, *interaction.s2 ); + rightSide.basePairs.push_back( energy.getBasePair(i1,i2) ); + rightSide.basePairs.push_back( energy.getBasePair(j1,j2) ); + // call traceback of super class + PredictorMfe2d::traceBack( rightSide ); + // copy base pairs (excluding last) + for (size_t i=0; i+1 2) { + Interaction::PairingVec & bps = interaction.basePairs; + // shift all added base pairs to the front + for (size_t i=2; i +#include + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe4d:: +PredictorMfe4d( const InteractionEnergy & energy, OutputHandler & output ) + : PredictorMfe(energy,output) + , hybridE( 0,0 ) +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe4d:: +~PredictorMfe4d() +{ + // clean up + this->clear(); +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe4d:: +predict( const IndexRange & r1 + , const IndexRange & r2 + , const OutputConstraint & outConstraint + ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting mfe interactions in O(n^4) space and time..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + +#if IN_DEBUG_MODE + // check indices + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMfe4d::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + // clear data + clear(); + + // setup index offset + energy.setOffset1(r1.from); + energy.setOffset2(r2.from); + + // resize matrix + hybridE.resize( std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ) + , std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ) ); + + size_t debug_count_cells_null=0 + , debug_count_cells_nonNull = 0 + , debug_count_cells_inf = 0 + , debug_cellNumber=0 + , w1, w2; + + + size_t maxWidthFori1i2 = 0; + + bool i1blocked, i1or2blocked, skipw1w2; + // initialize 3rd and 4th dimension of the matrix + for (size_t i1=0; i10; w1x--) { + w1 = w1x-1; + + for (size_t w2x = (*hybridE(i1,i2)).size2(); w2x>0; w2x--) { + w2 = w2x-1; + + // check if window size too large + skipw1w2 = false; + + // check if ED penalty exceeds maximal energy gain + if (w1 > 0 && w2 > 0){ + // check if all larger windows needing this site are already set to INF + bool largerWindowsINF = w1x==(*hybridE(i1,i2)).size1() && w2x==(*hybridE(i1,i2)).size2(); + // check all larger windows w1 + w2p (that might need this window for computation) + for (size_t w2p=(*hybridE(i1,i2)).size2()-1; largerWindowsINF && w2p>w2; w2p++) { + // check if larger window is E_INF + largerWindowsINF = (std::numeric_limits::max() < (*hybridE(i1,i2))(w1+1,w2p)); + } + // check all larger windows w2 + w1p (that might need this window for computation) + for (size_t w1p=(*hybridE(i1,i2)).size1()-1; largerWindowsINF && w1p>w1; w1p++) { + // check if larger window is E_INF + largerWindowsINF = (std::numeric_limits::max() < (*hybridE(i1,i2))(w1p,w2+1)); + } + + // if it holds for all w'>=w: ED1(i1+w1')+ED2(i2+w2')-outConstraint.maxE > -1*(min(w1',w2')*EmaxStacking + Einit + 2*Edangle + 2*Eend) + // ie. the ED values exceed the max possible energy gain of an interaction + skipw1w2 = skipw1w2 + || ( largerWindowsINF && + ( -1.0*(std::min(w1,w2)*minStackingEnergy + minInitEnergy + 2.0*minDangleEnergy + 2.0*minEndEnergy) + < (energy.getED1(i1,i1+w1) + energy.getED2(i2,i2+w2) - outConstraint.maxE) ) + ) + ; + } + + if (skipw1w2) { + // init with infinity to mark that this cell is not to be computed later on + (*hybridE(i1,i2))(w1,w2) = E_INF; + debug_count_cells_inf++; + } + + } + } + + } else { + // reduce memory consumption and avoid computation for this start index combination + hybridE(i1,i2) = NULL; + debug_count_cells_null += debug_cellNumber; + } + } + } + +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { LOG(DEBUG) <<"init 4d matrix : "<<(debug_count_cells_nonNull-debug_count_cells_inf)<<" (-"<size1()<=w1 || hybridE(i1,i2)->size2()<=w2) { + // interaction not possible: nothing to do, since no storage reserved + continue; + } + // check if interaction exceeds possible width due to max-loop-length + if ( getMaxInteractionWidth( 1+w1, energy.getMaxInternalLoopSize1() ) < w2 + || getMaxInteractionWidth( 1+w2, energy.getMaxInternalLoopSize2() ) < w1) + { + // ignore this entry + (*hybridE(i1,i2))(w1,w2) = E_INF; + continue; + } + + // get window ends j (seq1) and l (seq2) + j1=i1+w1; + j2=i2+w2; + + // check if right boundary is complementary + if (hybridE(j1,j2) == NULL) { + // not complementary -> ignore this entry + (*hybridE(i1,i2))(w1,w2) = E_INF; + continue; + } + // check if this cell is to be computed (!=E_INF) + if( E_isNotINF( (*hybridE(i1,i2))(w1,w2) ) ) { + + // compute entry + + // either interaction initiation + if ( w1==0 && w2==0 ) { + curMinE = energy.getE_init(); + } else { + + // or only internal loop energy (nothing between i and j) + curMinE = energy.getE_interLeft(i1,j1,i2,j2) + + (*hybridE(j1,j2))(0,0) ; + + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + if (w1 > 1 && w2 > 1) { + for (k1=std::min(j1-1,i1+energy.getMaxInternalLoopSize1()+1); k1>i1; k1--) { + for (k2=std::min(j2-1,i2+energy.getMaxInternalLoopSize2()+1); k2>i2; k2--) { + // check if (k1,k2) are complementary + if (hybridE(k1,k2) != NULL && hybridE(k1,k2)->size1() > (j1-k1) && hybridE(k1,k2)->size2() > (j2-k2)) { + curMinE = std::min( curMinE, + (energy.getE_interLeft(i1,k1,i2,k2) + + (*hybridE(k1,k2))(j1-k1,j2-k2)) + ); + } + } + } + } + } + + + // store value + (*hybridE(i1,i2))(w1,w2) = curMinE; + // update mfe if needed + updateOptima( i1,j1,i2,j2 , (*hybridE(i1,i2))(w1,w2), true ); + + continue; + } + } + } + } + } + +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe4d:: +traceBack( Interaction & interaction ) +{ + // check if something to trace + if (interaction.basePairs.size() < 2) { + return; + } + +#if IN_DEBUG_MODE + // sanity checks + if ( ! interaction.isValid() ) { + throw std::runtime_error("PredictorMfe4d::traceBack() : given interaction not valid"); + } + if ( interaction.basePairs.size() != 2 ) { + throw std::runtime_error("PredictorMfe4d::traceBack() : given interaction does not contain boundaries only"); + } +#endif + + // check for single interaction + if (interaction.basePairs.at(0).first == interaction.basePairs.at(1).first) { + // delete second boundary (identical to first) + interaction.basePairs.resize(1); + // update done + return; + } + + // ensure sorting + interaction.sort(); + // get indices in hybridE for boundary base pairs + size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), + j1 = energy.getIndex1(interaction.basePairs.at(1)), + i2 = energy.getIndex2(interaction.basePairs.at(0)), + j2 = energy.getIndex2(interaction.basePairs.at(1)); + + // the currently traced value for i1-j1, i2-j2 + E_type curE = (*hybridE(i1,i2))(j1-i1,j2-i2); + + // trace back + // do until only right boundary is left over + while( i1 != j1 ) { + // check if + // check if just internal loop + if ( E_equal( curE, + (energy.getE_interLeft(i1,j1,i2,j2) + + (*hybridE(j1,j2))(0,0) )) ) + { + break; + } + // check all interval splits + if ( (j1-i1) > 1 && (j2-i2) > 1) { + // temp variables + size_t k1,k2; + bool traceNotFound = true; + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + for (k1=std::min(j1-1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { + for (k2=std::min(j2-1,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { + // check if (k1,k2) are complementary + if (hybridE(k1,k2) != NULL && hybridE(k1,k2)->size1() > (j1-k1) && hybridE(k1,k2)->size2() > (j2-k2)) { + if ( E_equal( curE, + (energy.getE_interLeft(i1,k1,i2,k2) + + (*hybridE(k1,k2))(j1-k1,j2-k2)) ) ) + { + // stop searching + traceNotFound = false; + // store splitting base pair + interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); + // trace right part of split + i1=k1; + i2=k2; + curE = (*hybridE(i1,i2))(j1-i1,j2-i2); + } + } + } + } + } + } + + // sort final interaction (to make valid) (faster than calling sort()) + if (interaction.basePairs.size() > 2) { + Interaction::PairingVec & bps = interaction.basePairs; + // shift all added base pairs to the front + for (size_t i=2; i 0;) { + + // ensure interaction site start is not covered + if (reportedInteractions.first.covers(r1.from)) { + continue; + } + + for (r2.from=hybridE.size2(); r2.from-- > 0;) { + + // ensure interaction site start is not covered + if (reportedInteractions.second.covers(r2.from)) { + continue; + } + // check if left boundary is complementary + if (hybridE(r1.from,r2.from) == NULL) { + // interaction not possible: nothing to do, since no storage reserved + continue; + } + + curTable = hybridE(r1.from,r2.from); + + for (r1.to=r1.from; r1.tosize1(); r1.to++) { + + // check of overlapping + if (reportedInteractions.first.overlaps(r1)) { + // stop since all larger sites will overlap as well + break;; + } + + for (r2.to=r2.from; r2.tosize2(); r2.to++) { + + // check of overlapping + if (reportedInteractions.second.overlaps(r2)) { + // stop since all larger sites will overlap as well + break;; + } + + // get overall energy of entry + curE = energy.getE( r1.from, r1.to, r2.from, r2.to, (*curTable)(r1.to,r2.to)); + + // skip sites with energy too low + // or higher than current best found so far + if ( curE< curBestE || curE >= curBest.energy ) { + continue; + } + + //// FOUND THE NEXT BETTER SOLUTION + // overwrite current best found so far + curBest.energy = curE; + curBest.basePairs[0] = energy.getBasePair( r1.from, r2.from ); + curBest.basePairs[1] = energy.getBasePair( r1.to, r2.to ); + + } // j2 + } // j1 + + + } // i2 + } // i1 + +} + + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/PredictorMfe4d.h b/src/PredictorMfe4d.h new file mode 100644 index 00000000..3a58f8e7 --- /dev/null +++ b/src/PredictorMfe4d.h @@ -0,0 +1,116 @@ + +#ifndef PREDICTORMFE4D_H_ +#define PREDICTORMFE4D_H_ + +#include "PredictorMfe.h" +#include "Interaction.h" + +#include + +/** + * Predictor for RNAup-like computation, i.e. full DP-implementation without + * seed-heuristic using a 4D matrix + * + * @author Martin Mann + * + */ +class PredictorMfe4d: public PredictorMfe { + +protected: + + //! matrix type to cover the energies for different interaction site widths + typedef boost::numeric::ublas::matrix E2dMatrix; + + //! full 4D DP-matrix for computation to hold all start position combinations + //! first index = start positions (i1,i2) of (seq1,seq2) + //! second index = interaction window sizes (w1,w2) or NULL if (i1,i2) not complementary + typedef boost::numeric::ublas::matrix< E2dMatrix* > E4dMatrix; + + +public: + + /** + * Constructs a predictor and stores the energy and output handler + * + * @param energy the interaction energy handler + * @param output the output handler to report mfe interactions to + */ + PredictorMfe4d( const InteractionEnergy & energy, OutputHandler & output ); + + virtual ~PredictorMfe4d(); + + /** + * Computes the mfe for the given sequence ranges (i1-j1) in the first + * sequence and (i2-j2) in the second sequence and reports it to the output + * handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint() ); + +protected: + + //! access to the interaction energy handler of the super class + using PredictorMfe::energy; + + //! access to the output handler of the super class + using PredictorMfe::output; + + //! access to the list of reported interaction ranges of the super class + using PredictorMfe::reportedInteractions; + + // TODO provide all data structures as arguments to make predict() call threadsafe + + //! energy of all interaction hybrids computed by the recursion with indices + //! hybridE(i1,i2)->(w1,w2), with interaction start i1 (seq1) and i2 (seq2) and + //! interaction end j1=i1+w1 and j2=j2+w2 + //! NOTE: hybridE(i1,i2)==NULL if not complementary(seq1[i1],seq2[i2]) + E4dMatrix hybridE; + +protected: + + /** + * Removes all temporary data structures and resets the predictor + */ + void + clear(); + + /** + * computes all entries of the hybridE matrix + */ + void + fillHybridE( ); + + /** + * Fills a given interaction (boundaries given) with the according + * hybridizing base pairs. + * @param interaction IN/OUT the interaction to fill + */ + void + traceBack( Interaction & interaction ); + + + /** + * Identifies the next best interaction with an energy equal to or higher + * than the given interaction. The new interaction will not overlap any + * index range stored in reportedInteractions. + * + * @param curBest IN/OUT the current best interaction to be replaced with one + * of equal or higher energy not overlapping with any reported + * interaction so far; an interaction with energy E_INF is set, if + * there is no better interaction left + */ + virtual + void + getNextBest( Interaction & curBest ); + +}; + +#endif /* PREDICTORMFE4D_H_ */ diff --git a/src/PredictorMfe4dSeed.cpp b/src/PredictorMfe4dSeed.cpp new file mode 100644 index 00000000..5c14185c --- /dev/null +++ b/src/PredictorMfe4dSeed.cpp @@ -0,0 +1,563 @@ + +#include "PredictorMfe4dSeed.h" + +#include +#include + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe4dSeed:: +PredictorMfe4dSeed( const InteractionEnergy & energy + , OutputHandler & output + , const SeedConstraint & seedConstraint ) + : PredictorMfe4d(energy,output) + , seedHandler(energy,seedConstraint) + , hybridE_seed(0,0) +{ +} + + +//////////////////////////////////////////////////////////////////////////// + +PredictorMfe4dSeed:: +~PredictorMfe4dSeed() +{ + // clean up + this->clear(); +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe4dSeed:: +predict( const IndexRange & r1 + , const IndexRange & r2 + , const OutputConstraint & outConstraint + ) +{ +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"predicting mfe interactions with seed in O(n^4) space and time..."; } + // measure timing + TIMED_FUNC_IF(timerObj,VLOG_IS_ON(9)); + +#if IN_DEBUG_MODE + // check indices + if (!(r1.isAscending() && r2.isAscending()) ) + throw std::runtime_error("PredictorMfe4dSeed::predict("+toString(r1)+","+toString(r2)+") is not sane"); +#endif + + // clear data + clear(); + + // setup index offset + energy.setOffset1(r1.from); + energy.setOffset2(r2.from); + seedHandler.setOffset1(r1.from); + seedHandler.setOffset2(r2.from); + + const size_t hybridEsize1 = std::min( energy.size1() + , (r1.to==RnaSequence::lastPos?energy.size1()-1:r1.to)-r1.from+1 ); + const size_t hybridEsize2 = std::min( energy.size2() + , (r2.to==RnaSequence::lastPos?energy.size2()-1:r2.to)-r2.from+1 ); + + + // compute seed interactions for whole range + // and check if any seed possible + if (seedHandler.fillSeed( 0, hybridEsize1-1, 0, hybridEsize2-1 ) == 0) { + // trigger empty interaction reporting + initOptima(outConstraint); + reportOptima(outConstraint); + // stop computation + return; + } + + + // resize matrix + hybridE.resize( hybridEsize1, hybridEsize2 ); + hybridE_seed.resize( hybridEsize1, hybridEsize2 ); + + size_t debug_count_cells_null=0 + , debug_count_cells_nonNull = 0 + , debug_count_cells_inf = 0 + , debug_cellNumber=0 + , w1, w2; + + + size_t maxWidthFori1i2 = 0; + + bool i1blocked, i1or2blocked, skipw1w2; + // initialize 3rd and 4th dimension of the matrix + for (size_t i1=0; i1size1(), hybridE(i1,i2)->size2() ); + + debug_count_cells_nonNull += debug_cellNumber; + + // screen for cells that can be skipped from computation (decreasing window sizes) + for (size_t w1x = (*hybridE(i1,i2)).size1(); w1x>0; w1x--) { + w1 = w1x-1; + + for (size_t w2x = (*hybridE(i1,i2)).size2(); w2x>0; w2x--) { + w2 = w2x-1; + + // check if window size too large + skipw1w2 = false; + + // check if ED penalty exceeds maximal energy gain + if (w1 > 0 && w2 > 0){ + // check if all larger windows needing this site are already set to INF + bool largerWindowsINF = w1x==(*hybridE(i1,i2)).size1() && w2x==(*hybridE(i1,i2)).size2(); + // check all larger windows w1 + w2p (that might need this window for computation) + for (size_t w2p=(*hybridE(i1,i2)).size2()-1; largerWindowsINF && w2p>w2; w2p++) { + // check if larger window is E_INF + largerWindowsINF = (std::numeric_limits::max() < (*hybridE(i1,i2))(w1+1,w2p)); + } + // check all larger windows w2 + w1p (that might need this window for computation) + for (size_t w1p=(*hybridE(i1,i2)).size1()-1; largerWindowsINF && w1p>w1; w1p++) { + // check if larger window is E_INF + largerWindowsINF = (std::numeric_limits::max() < (*hybridE(i1,i2))(w1p,w2+1)); + } + + // if it holds for all w'>=w: ED1(i1+w1')+ED2(i2+w2')-outConstraint.maxE > -1*(min(w1',w2')*EmaxStacking + Einit + 2*Edangle + 2*Eend) + // ie. the ED values exceed the max possible energy gain of an interaction + skipw1w2 = skipw1w2 + || ( largerWindowsINF && + ( -1.0*(std::min(w1,w2)*minStackingEnergy + minInitEnergy + 2.0*minDangleEnergy + 2.0*minEndEnergy) < + (energy.getED1(i1,i1+w1) + energy.getED2(i2,i2+w2) - outConstraint.maxE)) + ) + ; + } + + if (skipw1w2) { + // init with infinity to mark that this cell is not to be computed later on + (*hybridE(i1,i2))(w1,w2) = E_INF; + (*hybridE_seed(i1,i2))(w1,w2) = E_INF; + debug_count_cells_inf++; + } + + } + } + + } else { + // reduce memory consumption and avoid computation for this start index combination + hybridE(i1,i2) = NULL; + hybridE_seed(i1,i2) = NULL; + debug_count_cells_null += debug_cellNumber; + } + } + } + +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { LOG(DEBUG) <<"init 2x 4d matrix : "<<(debug_count_cells_nonNull-debug_count_cells_inf)<<" (-"<mfeInteractions.begin()->energy < tmpOutConstraint.maxE)) { + // stop computation since no favorable interaction found + reportOptima(tmpOutConstraint); + return; + } + + // initialize mfe interaction with seed for updates + initOptima( outConstraint ); + // fill final matrix + fillHybridE_seed( ); + + // report mfe interaction + reportOptima( outConstraint ); + +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe4dSeed:: +clear() +{ + // delete 3rd and 4th dimension of the matrix + for (E4dMatrix::iterator1 iRows = hybridE_seed.begin1(); iRows != hybridE_seed.end1(); iRows++) { + for (E4dMatrix::iterator2 ijEntry = iRows.begin(); ijEntry != iRows.end(); ijEntry++) { + // delete 2d matrix for current ij + CLEANUP(*ijEntry); + } + } + // clear matrix, free data + hybridE_seed.clear(); + + // clean up super class data structures + PredictorMfe4d::clear(); +} + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe4dSeed:: +fillHybridE_seed( ) +{ + + // global vars to avoid reallocation + size_t i1,i2,j1,j2,w1,w2,k1,k2; + + ////////// FIRST ROUND : COMPUTE HYBRIDIZATION ENERGIES ONLY //////////// + + // current minimal value + E_type curMinE = E_INF; + // iterate increasingly over all window sizes w1 (seq1) and w2 (seq2) + // minimal size == number of seed base pairs + for (w1=0; w1= hybridE_seed(i1,i2)->size1() || w2 >= hybridE_seed(i1,i2)->size2() ) { + // interaction not possible: nothing to do, since no storage reserved + continue; + } + assert(hybridE(i1,i2)->size1() > w1); + assert(hybridE(i1,i2)->size2() > w2); + // check if no interaction without seed possible -> none with neither + if ( E_isINF((*hybridE(i1,i2))(w1,w2)) + // check if seed base pairs fit not into interaction window + || w1+1 < seedHandler.getConstraint().getBasePairs() + || w2+1 < seedHandler.getConstraint().getBasePairs() ) + { + // ignore this entry + (*hybridE_seed(i1,i2))(w1,w2) = E_INF; + continue; + } + + // get window ends j1 (seq1) and j2 (seq2) + j1=i1+w1; + j2=i2+w2; + + // compute entry /////////////////////////// + curMinE = E_INF; + + // base case = incorporate mfe seed starting at (i1,i2) + // + interaction on right side up to (j1,j2) + // -> check if widths are wide enough to contain a seed + if ( E_isNotINF( seedHandler.getSeedE(i1,i2) ) ) { + // decode right mfe boundary + k1 = i1+seedHandler.getSeedLength1(i1,i2)-1; + k2 = i2+seedHandler.getSeedLength2(i1,i2)-1; + // compute overall energy of seed+upToPQ + if ( k1 <= j1 && k2 <= j2 + && hybridE(k1,k2) != NULL + && j1-k1 < hybridE(k1,k2)->size1() + && j2-k2 < hybridE(k1,k2)->size2() + && E_isNotINF((*hybridE(k1,k2))(j1-k1,j2-k2))) + { + curMinE = seedHandler.getSeedE(i1,i2) + (*hybridE(k1,k2))(j1-k1,j2-k2); + } + } + + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + // where k1..j1 contains a seed + for (k1=std::min(j1-seedHandler.getConstraint().getBasePairs()+1,i1+energy.getMaxInternalLoopSize1()+1); k1>i1; k1--) { + for (k2=std::min(j2-seedHandler.getConstraint().getBasePairs()+1,i2+energy.getMaxInternalLoopSize2()+1); k2>i2; k2--) { + // check if (k1,k2) are valid left boundaries including a seed + if ( hybridE_seed(k1,k2) != NULL + && j1-k1 < hybridE_seed(k1,k2)->size1() + && j2-k2 < hybridE_seed(k1,k2)->size2() + && E_isNotINF( (*hybridE_seed(k1,k2))(j1-k1,j2-k2) ) ) + { + curMinE = std::min( curMinE, + (energy.getE_interLeft(i1,k1,i2,k2) + + (*hybridE_seed(k1,k2))(j1-k1,j2-k2) ) + ); + } + } + } + + // store computed value + (*hybridE_seed(i1,i2))(w1,w2) = curMinE; + + // update mfe if needed (call super class) + if (E_isNotINF(curMinE)) { + updateOptima( i1,j1,i2,j2, curMinE, true ); + } + + } + } + } + } + +} + + +//////////////////////////////////////////////////////////////////////////// + +void +PredictorMfe4dSeed:: +traceBack( Interaction & interaction ) +{ + // check if something to trace + if (interaction.basePairs.size() < 2) { + return; + } + +#if IN_DEBUG_MODE + // sanity checks + if ( ! interaction.isValid() ) { + throw std::runtime_error("PredictorMfe4dSeed::traceBack() : given interaction not valid"); + } + if ( interaction.basePairs.size() != 2 ) { + throw std::runtime_error("PredictorMfe4dSeed::traceBack() : given interaction does not contain boundaries only"); + } +#endif + + + // check for single interaction (start==end) + if (interaction.basePairs.begin()->first == interaction.basePairs.rbegin()->first) { + // delete second boundary (identical to first) + interaction.basePairs.resize(1); + // update done + return; + } + + // ensure sorting + interaction.sort(); + // get indices in hybridE_seed for boundary base pairs + size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), + j1 = energy.getIndex1(interaction.basePairs.at(1)), + i2 = energy.getIndex2(interaction.basePairs.at(0)), + j2 = energy.getIndex2(interaction.basePairs.at(1)), + k1, k2; + + // the currently traced value for i1-j1, i2-j2 + E_type curE = (*hybridE_seed(i1,i2))(j1-i1,j2-i2); + + // trace back + // do until only right boundary is left over + bool seedNotTraced = true; + while( i1 != j1 ) { + + // check if we still have to find the seed + if (seedNotTraced) { + + // check base case == seed only + if ( E_isNotINF( seedHandler.getSeedE(i1,i2) ) ) { + + // right boundary of seed + k1 = i1 + seedHandler.getSeedLength1(i1,i2) -1; + k2 = i2 + seedHandler.getSeedLength2(i1,i2) -1; + + // check if correct trace + if ( hybridE_seed(k1,k2) != NULL + && E_equal( curE, seedHandler.getSeedE(i1,i2) + (*hybridE(k1,k2))(j1-k1,j2-k2) ) ) + { + // store seed information + interaction.setSeedRange( + energy.getBasePair(i1,i2), + energy.getBasePair(k1,k2), + energy.getE(i1,k1,i2,k2,seedHandler.getSeedE(i1,i2))+energy.getE_init()); + // trace back seed base pairs + seedHandler.traceBackSeed( interaction, i1, i2 ); + // continue after seed + i1 = k1; + i2 = k2; + curE = (*hybridE(k1,k2))(j1-k1,j2-k2); + seedNotTraced = false; + continue; + } + } + // check all interval splits if no trace already found + if ( seedNotTraced ) + { + // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) + // where k1..j1 contains a seed + bool traceNotFound = true; + for (k1=std::min(j1-seedHandler.getConstraint().getBasePairs()+1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { + for (k2=std::min(j2-seedHandler.getConstraint().getBasePairs()+1,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { + // check if (k1,k2) are valid left boundaries including a seed + if ( hybridE_seed(k1,k2) != NULL + && j1-k1 < hybridE_seed(k1,k2)->size1() + && j2-k2 < hybridE_seed(k1,k2)->size2() + && E_isNotINF( (*hybridE_seed(k1,k2))(j1-k1,j2-k2) ) ) + { + // check if correct split + if (E_equal ( curE, + (energy.getE_interLeft(i1,k1,i2,k2) + + (*hybridE_seed(k1,k2))(j1-k1,j2-k2) ) + ) ) + { + // update trace back boundary + i1=k1; + i2=k2; + curE= (*hybridE_seed(k1,k2))(j1-k1,j2-k2); + // stop search splits + traceNotFound = false; + // store splitting base pair + interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); + } + } + } // k2 + } // k1 + assert(!traceNotFound); + } + } + // seed was already traced, do "normal" interaction trace + else { + // create temporary data structure to be filed + Interaction rightSide( *interaction.s1, *interaction.s2 ); + rightSide.basePairs.push_back( energy.getBasePair(i1,i2) ); + rightSide.basePairs.push_back( energy.getBasePair(j1,j2) ); + // call traceback of super class + PredictorMfe4d::traceBack( rightSide ); + // copy base pairs (excluding last) + for (size_t i=0; i+1 2) { + Interaction::PairingVec & bps = interaction.basePairs; + // shift all added base pairs to the front + for (size_t i=2; i 0;) { + + // ensure interaction site start is not covered + if (reportedInteractions.first.covers(r1.from)) { + continue; + } + + for (r2.from=hybridE_seed.size2(); r2.from-- > 0;) { + + // ensure interaction site start is not covered + if (reportedInteractions.second.covers(r2.from)) { + continue; + } + // check if left boundary is complementary + if (hybridE_seed(r1.from,r2.from) == NULL) { + // interaction not possible: nothing to do, since no storage reserved + continue; + } + + curTable = hybridE_seed(r1.from,r2.from); + + for (r1.to=r1.from; r1.tosize1(); r1.to++) { + + // check of overlapping + if (reportedInteractions.first.overlaps(r1)) { + // stop since all larger sites will overlap as well + break;; + } + + for (r2.to=r2.from; r2.tosize2(); r2.to++) { + + // check of overlapping + if (reportedInteractions.second.overlaps(r2)) { + // stop since all larger sites will overlap as well + break;; + } + + // get overall energy of entry + curE = energy.getE( r1.from, r1.to, r2.from, r2.to, (*curTable)(r1.to,r2.to)); + + // skip sites with energy too low + // or higher than current best found so far + if ( curE< curBestE || curE >= curBest.energy ) { + continue; + } + + //// FOUND THE NEXT BETTER SOLUTION + // overwrite current best found so far + curBest.energy = curE; + curBest.basePairs[0] = energy.getBasePair( r1.from, r2.from ); + curBest.basePairs[1] = energy.getBasePair( r1.to, r2.to ); + + } // j2 + } // j1 + + + } // i2 + } // i1 + +} + + +//////////////////////////////////////////////////////////////////////////// + diff --git a/src/PredictorMfe4dSeed.h b/src/PredictorMfe4dSeed.h new file mode 100644 index 00000000..d8390b4c --- /dev/null +++ b/src/PredictorMfe4dSeed.h @@ -0,0 +1,123 @@ + +#ifndef PREDICTORMFE4DSEED_H_ +#define PREDICTORMFE4DSEED_H_ + +#include "PredictorMfe4d.h" +#include "SeedConstraint.h" +#include "SeedHandlerIdxOffset.h" + +/** + * Predictor for RNAup-like computation, i.e. full DP-implementation with + * seed-heuristic using a 4D matrix. + * + * This enables non-overlapping suboptimal enumeration. + * + * @author Martin Mann + * + */ +class PredictorMfe4dSeed: public PredictorMfe4d { + + +public: + + /** + * Constructs a predictor and stores the energy and output handler + * + * @param energy the interaction energy handler + * @param output the output handler to report mfe interactions to + * @param seedConstraint the seed constraint to be used for seed identification + */ + PredictorMfe4dSeed( const InteractionEnergy & energy + , OutputHandler & output + , const SeedConstraint & seedConstraint ); + + virtual ~PredictorMfe4dSeed(); + + /** + * Computes the mfe for the given sequence ranges (i1-j1) in the first + * sequence and (i2-j2) in the second sequence and reports it to the output + * handler. + * + * @param r1 the index range of the first sequence interacting with r2 + * @param r2 the index range of the second sequence interacting with r1 + * @param outConstraint constrains the interactions reported to the output handler + * + */ + virtual + void + predict( const IndexRange & r1 = IndexRange(0,RnaSequence::lastPos) + , const IndexRange & r2 = IndexRange(0,RnaSequence::lastPos) + , const OutputConstraint & outConstraint = OutputConstraint() ); + +protected: + + //! access to the interaction energy handler of the super class + using PredictorMfe4d::energy; + + //! access to the output handler of the super class + using PredictorMfe4d::output; + + //! access to the list of reported interaction ranges of the super class + using PredictorMfe4d::reportedInteractions; + + // TODO provide all data structures as arguments to make predict() call threadsafe + + //! energy of all interaction hybrids computed by the recursion with indices + //! hybridE(i1,i2)->(w1,w2), with interaction start i1 (seq1) and i2 (seq2) and + //! interaction end j1=i1+w1 and j2=j2+w2. Interactions do not necessarily + //! contain a seed interaction. + //! NOTE: hybridE(i1,i2)==NULL if not complementary(seq1[i1],seq2[i2]) + using PredictorMfe4d::hybridE; + + + //! the seed handler (with idx offset) + SeedHandlerIdxOffset seedHandler; + + //! energy of all interaction hybrids that contain a seed interaction. + //! they are computed by the recursion with indices + //! hybridE_seed(i1,i2)->(w1,w2), with interaction start i1 (seq1) and i2 (seq2) and + //! interaction end j1=i1+w1 and j2=j2+w2. + //! NOTE: hybridE_seed(i1,i2)==NULL if not complementary(seq1[i1],seq2[i2]) + E4dMatrix hybridE_seed; + + +protected: + + /** + * Removes all temporary data structures and resets the predictor + */ + void + clear(); + + /** + * computes all entries of the hybridE matrix + */ + void + fillHybridE_seed( ); + + /** + * Fills a given interaction (boundaries given) with the according + * hybridizing base pairs. + * @param interaction IN/OUT the interaction to fill + */ + void + traceBack( Interaction & interaction ); + + + /** + * Identifies the next best interaction with an energy equal to or higher + * than the given interaction. The new interaction will not overlap any + * index range stored in reportedInteractions. + * + * @param curBest IN/OUT the current best interaction to be replaced with one + * of equal or higher energy not overlapping with any reported + * interaction so far; an interaction with energy E_INF is set, if + * there is no better interaction left + */ + virtual + void + getNextBest( Interaction & curBest ); + +}; + +#endif /* PREDICTORMFE4DSEED_H_ */ diff --git a/src/ReverseAccessibility.cpp b/src/ReverseAccessibility.cpp new file mode 100644 index 00000000..8b4c5f9e --- /dev/null +++ b/src/ReverseAccessibility.cpp @@ -0,0 +1,50 @@ +/* + * ReverseAccessibility.cpp + * + * Created on: 30.06.2014 + * Author: Mmann + */ + +#include "ReverseAccessibility.h" + + +//////////////////////////////////////////////////////////////////////////// + +std::string +ReverseAccessibility:: +getReversedString( const RnaSequence & seq ) +{ + const RnaSequence::String_type& seqAsString = seq.asString(); + // create string container + std::string revStr(seqAsString.size(),'_'); + // copy in reversed order + std::string::reverse_iterator revStrIt = revStr.rbegin(); + for (RnaSequence::String_type::const_iterator nuc = seqAsString.begin(); + nuc != seqAsString.end(); ++nuc,++revStrIt) + { + *revStrIt = *nuc; + } + // return reversed string + return revStr; +} + +//////////////////////////////////////////////////////////////////////////// + +std::string +ReverseAccessibility:: +getReversedString( const std::string & seqAsString ) +{ + // create string container + std::string revStr(seqAsString.size(),'_'); + // copy in reversed order + std::string::reverse_iterator revStrIt = revStr.rbegin(); + for (RnaSequence::String_type::const_iterator nuc = seqAsString.begin(); + nuc != seqAsString.end(); ++nuc,++revStrIt) + { + *revStrIt = *nuc; + } + // return reversed string + return revStr; +} + +//////////////////////////////////////////////////////////////////////////// diff --git a/src/ReverseAccessibility.h b/src/ReverseAccessibility.h new file mode 100644 index 00000000..d9051a2c --- /dev/null +++ b/src/ReverseAccessibility.h @@ -0,0 +1,216 @@ + +#ifndef REVERSEACCESSIBILITY_H_ +#define REVERSEACCESSIBILITY_H_ + +#include "Accessibility.h" + +/** + * Defines an accessibility meta object with reversed index access to sequence + * and accessibility. + */ +class ReverseAccessibility: public Accessibility { +public: + + /** + * Construction based on a given accessibility object to represent reversed + * + * @param origAcc Access to the accessibility object to reverse + */ + ReverseAccessibility( Accessibility & origAcc ); + + /** + * destruction + */ + virtual ~ReverseAccessibility(); + + /** + * Access to the accessibility energy value (according to reversed indices). + * + * @param from the start index of the regions (from <= to) + * @param to the end index of the regions (to <= seq.length()) + * + * @return 0 if (j-1+1) <= maxLength or ED_UPPER_BOUND otherwise + */ + virtual + E_type + getED( const size_t from, const size_t to ) const; + + + /** + * Access to the RnaSequence this accessibility values are accounting for. + * @return the underlying sequence for this accessibility object. + */ + virtual + const RnaSequence & + getSequence() const; + + + /** + * Access to the globally enforced accessibility constraint. Here '.' + * denotes unconstrained positions and 'x' positions that have to be + * unstructured. Regions covering constrained positions will result in + * ED_UPPER_BOUND accessibility values. + * @return the global accessibility constraint applied + */ + virtual + const AccessibilityConstraint& + getAccConstraint() const; + + /** + * Access to the original not-reversed accessibility object. + * @return the original (index reversed) accessibility object. + */ + virtual + const Accessibility & + getAccessibilityOrigin() const; + + + /** + * Provides the reverse index of a given sequence position. + * @param i the index of interest + * @return the reverse index, i.e. (seq.size()-i-1) + */ + size_t + getReversedIndex( const size_t i ) const; + + /** + * Provides the reverse index range of a given sequence position. + * @param i the index range of interest + * @return the reversed index range, i.e. for index i : (seq.size()-i-1) + */ + IndexRange + getReversedIndexRange( const IndexRange & r ) const; + + +protected: + + + //! Access to the accessibility object to reverse + Accessibility & origAcc; + + //! reversed sequence object + RnaSequence seqReversed; + + //! reversed accessibility constraint object + AccessibilityConstraint accConstrReversed; + + + /** + * Computes a reversed string representation of a sequence + * @param seq the sequence to reverse + * @return the reversed string representation + */ + static + std::string + getReversedString( const RnaSequence& seq ); + + /** + * Computes a reversed string representation of a given string + * @param str the string to reverse + * @return the reversed string + */ + static + std::string + getReversedString( const std::string& str ); + + +}; + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +inline +ReverseAccessibility::ReverseAccessibility( Accessibility & origAcc ) + : + Accessibility( origAcc.getSequence(), origAcc.getMaxLength(), &origAcc.getAccConstraint() ) + , origAcc(origAcc) + , seqReversed( seq.getId(), getReversedString(seq) ) + , accConstrReversed( origAcc.getAccConstraint(), true ) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +ReverseAccessibility::~ReverseAccessibility() { +} + +//////////////////////////////////////////////////////////////////////////// + +inline +const RnaSequence & +ReverseAccessibility:: +getSequence() const +{ + // access reversed sequence + return seqReversed; +} + + +//////////////////////////////////////////////////////////////////////////// + +inline +const AccessibilityConstraint& +ReverseAccessibility:: +getAccConstraint() const +{ + // access reversed accessibility constraint + return accConstrReversed; +} + + +//////////////////////////////////////////////////////////////////////////// + + +inline +E_type +ReverseAccessibility:: +getED( const size_t from, const size_t to ) const +{ + // check indices + checkIndices(from,to); + // reversed ED access + return origAcc.getED( seq.size()-to-1, seq.size()-from-1 ); +} + +//////////////////////////////////////////////////////////////////////////// + +inline +const Accessibility & +ReverseAccessibility:: +getAccessibilityOrigin() const +{ + return origAcc; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +size_t +ReverseAccessibility:: +getReversedIndex( const size_t i ) const +{ + // check indices + checkIndices(i,i); + // compute reverse index + return this->seq.size() -i -1; +} + +//////////////////////////////////////////////////////////////////////////// + +inline +IndexRange +ReverseAccessibility:: +getReversedIndexRange( const IndexRange & r ) const +{ + // reverse indices and their order to keep them ascending/descending + return IndexRange( getReversedIndex(r.to), getReversedIndex(r.from) ); +} + +//////////////////////////////////////////////////////////////////////////// + + + +#endif /* REVERSEACCESSIBILITY_H_ */ diff --git a/src/RnaSequence.cpp b/src/RnaSequence.cpp new file mode 100644 index 00000000..cd2c12bd --- /dev/null +++ b/src/RnaSequence.cpp @@ -0,0 +1,27 @@ +/* + * Sequence.cpp + * + * Created on: 24.06.2014 + * Author: Mmann + */ + +#include "RnaSequence.h" +#include + + + + +// setup static members +std::locale RnaSequence::codeLocale = std::locale(); + +// setup allowed alphabet in lower and upper case +const std::string RnaSequence::SequenceAlphabet = "ACGUN"; +const std::string RnaSequence::SequenceAlphabetIUPAC = "aAuUcCgGtTrRyYsSwWkKmMbBdDhHvVnN"; + + +//////////////////////////////////////////////////////////////////////////// + +const size_t RnaSequence::lastPos = std::string::npos; + +///////////////////////////////////////////////////////////////////////////// + diff --git a/src/RnaSequence.h b/src/RnaSequence.h new file mode 100644 index 00000000..f0d23dfc --- /dev/null +++ b/src/RnaSequence.h @@ -0,0 +1,463 @@ + +#ifndef RNASEQUENCE_H_ +#define RNASEQUENCE_H_ + +#include +#include +#include + +#include "general.h" + + +#ifndef VIENNA_RNA_PAIR_MAT_H +#define VIENNA_RNA_PAIR_MAT_H +extern "C" { + #include "ViennaRNA/pair_mat.h" +} +#endif + + + +/** + * Represents an RNA sequence within IntaRNA and holds all necessary utility + * functions. + * + * The integer sequence encoding uses the Vienna RNA package encoding functions. + * + * @author Martin Mann 2014 + */ +class RnaSequence { + +public: + + //! type for sequence string representation + typedef std::string String_type; + + //! type for integer encoding of a single sequence letter + //! (currently same as in Vienna package) + typedef short Code_type; + + //! type for sequence integer encoded representation + typedef std::vector CodeSeq_type; + + + /** + * Allowed nucleotide single letter character alphabet according to IUPAC + * codes and their lower case variants. + */ + const static std::string SequenceAlphabetIUPAC; + + /** + * Allowed nucleotide single letter character alphabet (uppercase only) + */ + const static std::string SequenceAlphabet; + + //! constant that serves as a placeholder for the last position within a + //! sequence independent of its real size + static const size_t lastPos; + +public: + + /** + * Creates a sequence. + * @param id the name of the sequence + * @param seqString the nucleotide string encoding the sequence + * + */ + RnaSequence(const std::string& id + , const std::string & seqString ); + + /** + * Destruction and garbage collection + */ + virtual ~RnaSequence(); + + + ///////////////////// DATA ACCESS ////////////////////////////// + + /** + * Access to the sequence's ID. + * @return the ID of the sequence. + */ + const std::string& + getId() const; + + /** + * Access to the length of the sequence. + * @return the length of the sequence. + */ + size_t + size() const; + + /** + * Access to the sequence in character encoding. + * @return the character encoding of the sequence + */ + const String_type& + asString() const; + + /** + * Access to the sequence in integer coding using the Vienna RNA package + * encoding. + * @return the integer encoding of the sequence + */ + const CodeSeq_type& + asCodes() const; + + /** + * Whether or not the sequence contains ambiguous nucleotide encodings. + * @return true if the sequence contains ambiguous nucleotide encodings; + * false otherwise + */ + bool + isAmbiguous() const; + + /** + * Whether or not a specific sequence position shows an ambiguous nucleotide + * encoding. + * @param i the sequence position of interest + * @return true if the sequence contains an ambiguous nucleotide encoding + * at position i; + * false otherwise + */ + bool + isAmbiguous( const size_t i ) const; + + /** + * prints the sequence id and the sequence to stream + * @out the ostream to write to + * @rna the RnaSequence object to add + * @return the altered stream out + */ + friend std::ostream& operator<<(std::ostream& out, const RnaSequence& rna); + +public: + + ///////////////////// STATIC UTILITY ////////////////////////////// + + /** + * Utility function that converts a string into the internal sequence's + * string representation. This covers an upper case conversion. + * @param seqString sequence string + * @return the internally used sequence string representation + */ + static + String_type + getUpperCase( const std::string & seqString ); + + + /** + * Utility function that converts a sequence's string representation into + * its integer encoding + * + * NOTE: encoding covers only upper case characters! Otherwise an exception + * is raised. + * + * @param seqString the string to encode + * @param return the integer encoding + * @throw std::runtime_error if an unsupported nucleotide character is given + */ + static + CodeSeq_type + getCodeForString( const String_type& seqString ); + + /** + * Utility function that converts a nucleotide's char representation into + * its integer encoding. + * + * NOTE: encoding covers only upper case characters! Otherwise an exception + * is raised. + * + * @param nucleotide the char to encode + * @param return the integer encoding + * @throw std::runtime_error if an unsupported nucleotide character is given + */ + static + Code_type + getCodeForChar( const char nucleotide ); + + + /** + * Utility function that tests whether or not a given sequence is a valid + * RNA sequence + */ + static + bool + isValidSequence( const std::string& sequence ); + + + /** + * Utility function that tests whether or not a given sequence is a valid + * RNA sequence according to IUPAC encoding + */ + static + bool + isValidSequenceIUPAC( const std::string& sequence ); + + + /** + * Whether or not two positions of two RNAs are complementary, ie. can + * form a base pair + * @param s1 first RNA + * @param s2 second RNA + * @param p1 position within s1 + * @param p2 position within s2 + * @return true if s1[p1] can form a base pair with s2[p2]; false otherwise + */ + static + bool + areComplementary( const RnaSequence & s1, const RnaSequence & s2, + const size_t p1, const size_t p2 ); + +protected: + + ///////////////////// DATA MEMBERS ////////////////////////////// + + + //! the locale to use for integer encoding + static std::locale codeLocale; + + //! ID of this sequence + std::string id; + + //! The sequence's string representation. + String_type seqString; + + //! Integer encoding of the sequence. + CodeSeq_type seqCode; + + //! Whether or not the sequence contains ambiguous nucleotide encodings + bool ambiguous; + +}; + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +inline +RnaSequence::RnaSequence( + const std::string & id + , const std::string & seqString ) + : + id(id) + , seqString(getUpperCase(seqString)) + , seqCode(getCodeForString(this->seqString)) + , ambiguous(this->seqString.find('N')!=std::string::npos) +{ +#if IN_DEBUG_MODE + if (id.size() == 0) { + throw std::runtime_error("RnaSequence::RnaSequence : id empty"); + } + if (seqString.size() == 0) { + throw std::runtime_error("RnaSequence::RnaSequence : seqString empty"); + } +#endif + +} + +///////////////////////////////////////////////////////////////////////////// + +inline +RnaSequence::~RnaSequence() +{ +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const std::string& +RnaSequence:: +getId() const +{ + return id; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +RnaSequence:: +size() const +{ + return seqString.size(); +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const +RnaSequence:: +String_type& +RnaSequence:: +asString() const +{ + return seqString; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const +RnaSequence:: +CodeSeq_type& +RnaSequence:: +asCodes() const +{ + return seqCode; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +bool +RnaSequence:: +isAmbiguous() const +{ + return ambiguous; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +bool +RnaSequence:: +isAmbiguous( const size_t i ) const +{ + // check for ambiguous nucleotide encoding + return this->seqString.at(i) == 'N'; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +RnaSequence:: +String_type +RnaSequence:: +getUpperCase( const std::string & seqString ) +{ +#if IN_DEBUG_MODE + if (!isValidSequenceIUPAC(seqString)) throw std::runtime_error("RnaSequence::getUpperCase() : the given sequence contains non-IUPAC codes : '"+seqString+"'"); +#endif + + // create container to fill + String_type seqRet(seqString.size(),'_'); + + for (size_t i=0; i=s1.size() || p2>=s2.size()) + throw std::runtime_error("RnaSequence::areComplementary : index positions p1/p2 (" + + toString(p1)+"/"+toString(p2) + + ") are out of bounds s1/s2 (" + + toString(s1.size())+"/"+toString(s2.size()) + +")" + ); +#endif + + // check via VRNA util + return BP_pair[s1.seqCode.at(p1)][s2.seqCode.at(p2)] > 0; +} + +///////////////////////////////////////////////////////////////////////////// + + + + +#endif /* RNASEQUENCE_H_ */ diff --git a/src/SeedConstraint.cpp b/src/SeedConstraint.cpp new file mode 100644 index 00000000..608ebdb3 --- /dev/null +++ b/src/SeedConstraint.cpp @@ -0,0 +1,7 @@ + +#include "SeedConstraint.h" +#include "general.h" + +#include + + diff --git a/src/SeedConstraint.h b/src/SeedConstraint.h new file mode 100644 index 00000000..c52746bb --- /dev/null +++ b/src/SeedConstraint.h @@ -0,0 +1,347 @@ + +#ifndef SEEDCONSTRAINT_H_ +#define SEEDCONSTRAINT_H_ + + +#include "general.h" +#include "IndexRangeList.h" + +#include +#include + +/** + * Encodes seed constraints to be used for interaction prediction. + * + * @author Martin Mann + * + */ +class SeedConstraint { + +public: + + /** + * Construction + * + * @param number of base pairs a seed has to have (>= 2) + * @param maxUnpairedOverall_ the maximal (summed) number of unpaired bases + * within both seq1 and seq2 allowed within a seed + * @param maxUnpaired1 the maximal number of unpaired bases within seq1 + * allowed within a seed + * @param maxUnpaired2 the maximal number of unpaired bases within seq2 + * allowed within a seed + * @param maxE maximal energy a seed is allowed to have + * @param maxED maximal ED value a seed is allowed to have for each subsequence + * @param ranges1 the index ranges of seq1 to be searched for seeds + * @param ranges2reversed the index reversed ranges of seq2 to be searched for seeds + */ + SeedConstraint( const size_t bp + , const size_t maxUnpairedOverall + , const size_t maxUnpaired1 + , const size_t maxUnpaired2 + , const E_type maxE + , const E_type maxED + , const IndexRangeList & ranges1 + , const IndexRangeList & ranges2reversed + ); + + virtual ~SeedConstraint(); + + + /** + * Provides the number of base pairs to be present within a seed + * + * @return the number of base pairs a seed has to have + */ + size_t + getBasePairs() const; + + /** + * Provides the overall maximal number of unpaired bases within a seed + * + * @return the overall maximal number of unpaired bases within + * a seed is allowed to have + */ + size_t + getMaxUnpairedOverall() const; + + /** + * Provides the maximal number of unpaired bases within the first sequence + * within a seed + * + * @return the maximal number of unpaired bases within the first sequence + * a seed is allowed to have + */ + size_t + getMaxUnpaired1() const; + + /** + * Provides the maximal number of unpaired bases within the second sequence + * within a seed + * + * @return the maximal number of unpaired bases within the second sequence + * a seed is allowed to have + */ + size_t + getMaxUnpaired2() const; + + /** + * Provides the maximally allowed energy for seeds to be considered + * + * @return the maximally allowed energy for a seed + */ + E_type + getMaxE() const; + + /** + * Provides the maximally allowed ED value for each seed subsequence to be + * considered + * + * @return the maximally allowed ED value (per sequence) for a seed + */ + E_type + getMaxED() const; + + /** + * Provides the maximal length of the seed in seq1 + * @return the maximal length of the seed in seq1 + */ + size_t + getMaxLength1() const; + + /** + * Provides the maximal length of the seed in seq2 + * @return the maximal length of the seed in seq2 + */ + size_t + getMaxLength2() const; + + /** + * Index ranges in seq1 to be searched for seeds or empty if all indices + * are to be considered. + * @return index ranges to be searched or empty list if all indices relevant + */ + const IndexRangeList & + getRanges1() const; + + /** + * Index ranges in seq2 to be searched for seeds or empty if all indices + * are to be considered. + * @return index ranges to be searched or empty list if all indices relevant + */ + const IndexRangeList & + getRanges2() const; + + /** + * Index ranges in seq1 to be searched for seeds or empty if all indices + * are to be considered. + * @return index ranges to be searched or empty list if all indices relevant + */ + IndexRangeList & + getRanges1(); + + /** + * Index ranges in seq2 to be searched for seeds or empty if all indices + * are to be considered. + * @return index ranges to be searched or empty list if all indices relevant + */ + IndexRangeList & + getRanges2(); + + /** + * Prints the seed constraint details to stream + * @param out the ostream to write to + * @param c the object to add + * @return the altered stream out + */ + friend std::ostream& operator<<(std::ostream& out, const SeedConstraint& c); + +protected: + + //! the number of base pairs to be present in a seed + size_t bp; + + //! the overall summed maximally allowed number of unpaired bases in a seed + size_t maxUnpairedOverall; + + //! the maximally allowed number of unpaired bases in seed seq1 + size_t maxUnpaired1; + + //! the maximally allowed number of unpaired bases in seed seq2 + size_t maxUnpaired2; + + //! the maximal energy allowed for a seed + E_type maxE; + + //! the maximal ED value (per sequence) allowed for a seed + E_type maxED; + + //! the index ranges of seq1 to be searched for seeds + IndexRangeList ranges1; + + //! the index ranges of seq2 to be searched for seeds + IndexRangeList ranges2; + +}; + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +inline +SeedConstraint::SeedConstraint( + const size_t bp_ + , const size_t maxUnpairedOverall_ + , const size_t maxUnpaired1_ + , const size_t maxUnpaired2_ + , const E_type maxE_ + , const E_type maxED_ + , const IndexRangeList & ranges1 + , const IndexRangeList & ranges2reversed + ) + : + bp(bp_) + , maxUnpairedOverall(maxUnpairedOverall_) + , maxUnpaired1(std::min(maxUnpaired1_,maxUnpairedOverall_)) // exclude too large boundaries + , maxUnpaired2(std::min(maxUnpaired2_,maxUnpairedOverall_)) // exclude too large boundaries + , maxE(maxE_) + , maxED(maxED_) + , ranges1(ranges1) + , ranges2(ranges2reversed) +{ + if (bp < 2) throw std::runtime_error("SeedConstraint() : base pair number ("+toString(bp)+") < 2"); +} + +///////////////////////////////////////////////////////////////////////////// + +inline +SeedConstraint::~SeedConstraint() { +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedConstraint:: +getBasePairs() const { + return bp; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +E_type +SeedConstraint:: +getMaxE() const { + return maxE; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +E_type +SeedConstraint:: +getMaxED() const { + return maxED; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedConstraint:: +getMaxUnpaired1() const { + return maxUnpaired1; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedConstraint:: +getMaxUnpaired2() const { + return maxUnpaired2; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedConstraint:: +getMaxUnpairedOverall() const { + return maxUnpairedOverall; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedConstraint:: +getMaxLength1() const { + return getBasePairs() + getMaxUnpaired1(); +} + +///////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedConstraint:: +getMaxLength2() const { + return getBasePairs() + getMaxUnpaired2(); +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const IndexRangeList & +SeedConstraint:: +getRanges1() const { + return ranges1; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +const IndexRangeList & +SeedConstraint:: +getRanges2() const { + return ranges2; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList & +SeedConstraint:: +getRanges1() { + return ranges1; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +IndexRangeList & +SeedConstraint:: +getRanges2() { + return ranges2; +} + +///////////////////////////////////////////////////////////////////////////// + +inline +std::ostream& +operator<<(std::ostream& out, const SeedConstraint& c) +{ + out <<"SeedConstraint( bp="< i1max ) throw std::runtime_error("SeedHandler::fillSeed: i1min("+toString(i1min)+") > i1max("+toString(i1max)+")"); + if ( i2min > i2max ) throw std::runtime_error("SeedHandler::fillSeed: i2min("+toString(i2min)+") > i2max("+toString(i2max)+")"); + if ( i1max > energy.size1() ) throw std::runtime_error("SeedHandler::fillSeed: i1max("+toString(i1max)+") > energy.size1("+toString(energy.size1())+")"); + if ( i2max > energy.size2() ) throw std::runtime_error("SeedHandler::fillSeed: i2max("+toString(i2max)+") > energy.size2("+toString(energy.size2())+")"); +#endif + + // TODO : if (umax==0) apply local alignment/exact match search based on sequence only + + // resize matrizes + seed.resize( i1max-i1min+1, i2max-i2min+1 ); + seedE_rec.resize( SeedIndex({{ // setup ring-list data for seed computation + (SeedRecMatrix::index)(seed.size1()) + , (SeedRecMatrix::index)(seed.size2()) + , (SeedRecMatrix::index)(seedConstraint.getBasePairs()+1-2) // +1 for size and -2 to encode at least 2 bps or more + , (SeedRecMatrix::index)(seedConstraint.getMaxUnpaired1()+1) // +1 for size + , (SeedRecMatrix::index)(seedConstraint.getMaxUnpaired2()+1) // +1 for size + }})); + + // store index offset due to restricted matrix size generation + offset1 = i1min; + offset2 = i2min; + + // temporary variables + size_t i1, i2, bpIn, u1, u2, j1, j2, u1p, u2p, k1,k2, u1best, u2best; + E_type curE, bestE; + + size_t seedCountNotInf = 0, seedCount = 0; + + // fill for all start indices + // in decreasing index order + for (i1=i1max+1; i1-- > i1min;) { + for (i2=i2max+1; i2-- > i2min;) { + + // count seed possibility + seedCount++; + + // init according to no seed interaction + seed(i1-offset1,i2-offset2) = SeedMatrix::value_type( E_INF, 0 ); + + // skip non-complementary left seed boundaries + if (!energy.areComplementary(i1,i2)) { + continue; // go to next seedE index + } + // skip left seed boundaries excluded from search + if (!(seedConstraint.getRanges1().empty() || seedConstraint.getRanges1().covers(i1))) { + continue; // go to next seedE index + } + if (!(seedConstraint.getRanges2().empty() || seedConstraint.getRanges2().covers(i2))) { + continue; // go to next seedE index + } + + // for feasible number of base pairs (bp+1) in increasing order + // bp=0 encodes 2 base pairs + for (bpIn=0; bpIn 0;) { + for (u2p=1+std::min(u2,energy.getMaxInternalLoopSize2()); u2p-- > 0;) { + + k1 = i1+u1p+1; + k2 = i2+u2p+1; + // check if split pair is complementary + // and recursed entry is < E_INF + if (! (energy.areComplementary(k1,k2) && E_isNotINF( getSeedE( k1-offset1, k2-offset2, bpIn-1, u1-u1p, u2-u2p ) ) ) ) { + continue; // not complementary -> skip + } + + // update mfe for split at k1,k2 + curE = std::min( curE, + energy.getE_interLeft(i1,k1,i2,k2) + + getSeedE( k1-offset1, k2-offset2, bpIn-1, u1-u1p, u2-u2p ) + ); + } // u2p + } // u1p + } // more than two base pairs + + } // (j1,j2) complementary + + // store seed energy + setSeedE( i1-offset1, i2-offset2, bpIn, u1, u2, curE ); + + } // u2 + } // u1 + + // check if full base pair number reached + if (bpIn+1==seedE_rec.shape()[2]) { + + // find best unpaired combination in seed seed for i1,i2,bp + u1best = 0; + u2best = 0; + bestE = E_INF; + + // for feasible unpaired in seq1 in increasing order + for (u1=0; u1 seedConstraint.getMaxED() + || energy.getED2(i2,j2) > seedConstraint.getMaxED() ) + { + continue; + } + + // get overall interaction energy + curE = energy.getE( i1, j1, i2, j2, getSeedE( i1-offset1, i2-offset2, bpIn, u1, u2 ) ) + energy.getE_init(); + + // check if better than what is known so far + if ( curE < bestE ) { + bestE = curE; + u1best = u1; + u2best = u2; + } + } // u2 + } // u1 + + // reduce bestE to hybridization energy only (init+loops) + if (E_isNotINF( bestE )) { + // overwrite all seeds with too high energy -> infeasible start interactions + if (bestE > seedConstraint.getMaxE()) { + bestE = E_INF; + } else { + // get seed's hybridization loop energies only + bestE = getSeedE( i1-offset1, i2-offset2, bpIn, u1best, u2best ); + // count true seed + seedCountNotInf++; + } + } + + // store best (mfe) seed for all u1/u2 + seed(i1-offset1,i2-offset2) = SeedMatrix::value_type( bestE + , E_isINF(bestE)?0:encodeSeedLength(bpIn+2+u1best,bpIn+2+u2best) ); + + } // store best seed + + } // bp + } // i2 + } // i1 + +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(2) <<"valid seeds = "< 0; ) { + + // base case: only left and right base pair present + if (bpIn==0) { + // add left base pair if not left seed boundary + if (i1 != i1_) { + interaction.basePairs.push_back( energy.getBasePair(i1,i2) ); + } + + } else { + // split seed recursively into all possible leading interior loops + // i1 .. i1+u1p+1 .. j1 + // i2 .. i2+u2p+1 .. j2 + bool traceNotFound = true; + for (u1=1+u1max; traceNotFound && u1-- > 0;) { + for (u2=1+u2max; traceNotFound && u2-- > 0;) { + // check if overall number of unpaired is not exceeded + if (u1+u2 > uMax) { + continue; + } + + k1 = i1+u1+1; + k2 = i2+u2+1; + + // check if valid trace + if ( E_isNotINF( getSeedE( k1, k2, bpIn-1, u1max-u1, u2max-u2 ) ) ) { + + // check if correct trace + if ( E_equal( curE, energy.getE_interLeft(i1,k1,i2,k2) + + getSeedE( k1, k2, bpIn-1, u1max-u1, u2max-u2 )) ) + { + // store left base pair if not left seed boundary + if (i1 != i1_) { + interaction.basePairs.push_back( energy.getBasePair(i1,i2) ); + } + // store next energy value to trace + curE = getSeedE( k1, k2, bpIn-1, u1max-u1, u2max-u2 ); + // reset for next trace step + i1 = k1; + i2 = k2; + // update boundaries for unpaired positions to reduce trace effort + u1max -= u1; + u2max -= u2; + uMax -= (u1 + u2); + // mark trace step done + traceNotFound = false; + } + } + + } // u2 + } // u1 + assert( !traceNotFound ); // sanity check + } // more than two base pairs + + } // bpIn + +} + +//////////////////////////////////////////////////////////////////////////// diff --git a/src/SeedHandler.h b/src/SeedHandler.h new file mode 100644 index 00000000..40238cd4 --- /dev/null +++ b/src/SeedHandler.h @@ -0,0 +1,411 @@ + +#ifndef SEEDHANDLER_H_ +#define SEEDHANDLER_H_ + +#include "InteractionEnergy.h" +#include "SeedConstraint.h" + +#include + +#include + + +/** + * Handler to provide seed interaction information + */ +class SeedHandler +{ +public: + + // TODO replace with 2D array on sparse matrices since most entries not used + + //! 5D matrix type to hold the mfe energies for seed interactions + //! of the ranges i1..(i1+bp+u1-1) with i2..(i2+bp+u2-1), with + //! i1,i2 = the start index of the seed in seq1/2 + //! bp = the number of base pairs within the seed + //! bpInbetween = the number of base pairs enclosed by left and right base pair, ie. == (bp-2) + //! u1/u2 = the number of unpaired positions within the seed, + //! using the index [i1][i2][bpInbetween][u1][u2] or a SeedIndex object + typedef boost::multi_array SeedRecMatrix; + + //! defines the seed data {{ i1, i2, bpInbetween, u1, u2 }} to access elements of + //! the SeedRecMatrix + typedef boost::array SeedIndex; + + //! matrix to store the seed information for each seed left side (i1,i2); + //! it holds both the energy (first) as well as the length of the seed using + //! the length combination using encodeSeedLength() + typedef boost::numeric::ublas::matrix< std::pair > SeedMatrix; + + +public: + + /** + * Construction + * @param energy the energy function to be used for seed prediction + * @param seedConstraint the seed constraint to be applied + */ + SeedHandler( + const InteractionEnergy & energy + , const SeedConstraint & seedConstraint + ); + + /** + * destruction + */ + virtual ~SeedHandler(); + + /** + * Access to the underlying seed constraint + * @return the used seed constraint + */ + virtual + const SeedConstraint& + getConstraint() const; + + /** + * Access to the underlying interaction energy function + * @return the used energy function + */ + virtual + const InteractionEnergy& + getInteractionEnergy() const; + + + /** + * Computes the seed matrix for the given interval boundaries + * @param i1 the first index of seq1 that might interact + * @param j1 the last index of seq1 that might interact + * @param i2 the first index of seq2 that might interact + * @param j2 the last index of seq2 that might interact + * @return the number of potential seed interactions + */ + virtual + size_t + fillSeed(const size_t i1, const size_t j1, const size_t i2, const size_t j2); + + /** + * Identifies the base pairs of the mfe seed interaction starting at i1,i2 + * and writes them to the provided container + * + * NOTE: the right most base pair is excluded! + * + * @param interaction the container to add the base pairs too + * @param i1 the start of the seed in seq1 + * @param i2 the start of the seed in seq2 + */ + virtual + void + traceBackSeed( Interaction & interaction, const size_t i1, const size_t i2); + + + /** + * Access to the mfe of any seed with left-most base pair (i1,i2) + * @param i1 the left most interacting base of seq1 + * @param i2 the left most interacting base of seq2 + * @return the mfe of any seed starting at (i1,i2) or E_INF if none possible + */ + virtual + E_type + getSeedE( const size_t i1, const size_t i2 ) const; + + /** + * Access to the length in seq1 of the mfe seed with left-most base pair (i1,i2) + * @param i1 the left most interacting base of seq1 + * @param i2 the left most interacting base of seq2 + * @return the length in seq1 of the mfe seed starting at (i1,i2) or 0 if none possible + */ + virtual + size_t + getSeedLength1( const size_t i1, const size_t i2 ) const; + + /** + * Access to the length in seq2 of the mfe seed with left-most base pair (i1,i2) + * @param i1 the left most interacting base of seq1 + * @param i2 the left most interacting base of seq2 + * @return the length in seq2 of the mfe seed starting at (i1,i2) or 0 if none possible + */ + virtual + size_t + getSeedLength2( const size_t i1, const size_t i2 ) const; + + + +protected: + + //! the used energy function + const InteractionEnergy& energy; + + //! the seed constraint to be applied + const SeedConstraint & seedConstraint; + + //! the recursion data for the computation of a seed interaction + //! i1..(i1+bpInbetween+u1-1) with i2..(i2+bpInbetween+u2-1) + //! using the indexing [i1][i2][bpInbetween][u1][u2] + SeedRecMatrix seedE_rec; + + //! the seed mfe information for seeds starting at (i1,i2) + //! TODO replace with sparse data structure + SeedMatrix seed; + + //! offset for seq1 indices for the current (restricted) matrices + size_t offset1; + + //! offset for seq2 indices for the current (restricted) matrices + size_t offset2; + + /** + * Provides the seed energy during recursion. + * + * @param i1 the seed left end in seq 1 (index including offset) + * @param i2 the seed left end in seq 2 (index including offset) + * @param bpInbetween the number of seed base pairs enclosed by the left- + * and right-most base pair, ie. bpSeed-2 + * @param u1 the number of unpaired bases within seq 1 + * @param u2 the number of unpaired bases within seq 2 + * + * @return the energy of the according (sub)seed + */ + E_type + getSeedE( const size_t i1, const size_t i2, const size_t bpInbetween, const size_t u1, const size_t u2 ); + + /** + * Fills the seed energy during recursion. + * + * NOTE: internally a ring-list data structure is used which reuses memory + * instead of allocating mem for all possible parameter combinations. Thus, + * you have to call the method in appropriate order depending on your seed + * recursion. + * + * @param i1 the seed left end in seq 1 (index including offset) + * @param i2 the seed left end in seq 2 (index including offset) + * @param bpInbetween the number of seed base pairs enclosed by the left- + * and right-most base pair, ie. bpSeed-2 + * @param u1 the number of unpaired bases within seq 1 + * @param u2 the number of unpaired bases within seq 2 + * @param E the energy value to be set + */ + void + setSeedE( const size_t i1, const size_t i2, const size_t bpInbetween, const size_t u1, const size_t u2, const E_type E ); + + /** + * Encodes the seed lengths into one number + * @param l1 the length of the seed in seq1 + * @param l2 the length of the seed in seq2 + * @return the combined encoding = (l1 + l2*(max_l1+1)) + */ + size_t + encodeSeedLength( const size_t l1, const size_t l2 ) const; + + /** + * Decodes the length of the seed within sequence 1 from an encoding + * generated with encodeSeedLength() + * @param code the lengths encoding + * @return the length of the seed in seq1 + */ + size_t + decodeSeedLength1( const size_t code ) const; + + /** + * Decodes the length of the seed within sequence 2 from an encoding + * generated with encodeSeedLength() + * @param code the lengths encoding + * @return the length of the seed in seq2 + */ + size_t + decodeSeedLength2( const size_t code ) const; + + /** + * Fills a given interaction with the according + * hybridizing base pairs of the provided seed interaction (excluding + * the right-most seed base pair) + * + * @param interaction IN/OUT the interaction to fill + * @param i1 the seed left end in seq 1 (index including offset) + * @param i2 the seed left end in seq 2 (index including offset) + * @param bp the number of base pairs (bp+2) within the seed so far + * @param u1 the number of unpaired bases within seq 1 + * @param u2 the number of unpaired bases within seq 2 + */ + void + traceBackSeed( Interaction & interaction + , const size_t i1, const size_t i2, const size_t bp + , const size_t u1, const size_t u2 ); + +}; + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + + +inline +SeedHandler::SeedHandler( + const InteractionEnergy & energy + , const SeedConstraint & seedConstraint + ) + : + energy(energy) + , seedConstraint(seedConstraint) + , seedE_rec( SeedIndex({{ 0,0,0,0,0 }})) + , seed() + , offset1(0) + , offset2(0) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +SeedHandler::~SeedHandler() +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +const SeedConstraint& +SeedHandler:: +getConstraint() const +{ + return seedConstraint; +} + +////////////////////////////////////////////////////////////////////////// + +inline +const InteractionEnergy& +SeedHandler:: +getInteractionEnergy() const +{ + return energy; +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +SeedHandler:: +traceBackSeed( Interaction & interaction + , const size_t i1 + , const size_t i2 + ) +{ +#if IN_DEBUG_MODE + if ( i1 < offset1 ) throw std::runtime_error("SeedHandler::traceBackSeed(i1="+toString(i1)+") is out of range (>"+toString(offset1)+")"); + if ( i1-offset1 >= seed.size1() ) throw std::runtime_error("SeedHandler::traceBackSeed(i1="+toString(i1)+") is out of range (<"+toString(seed.size1()+offset1)+")"); + if ( i2 < offset2 ) throw std::runtime_error("SeedHandler::traceBackSeed(i2="+toString(i2)+") is out of range (>"+toString(offset2)+")"); + if ( i2-offset2 >= seed.size2() ) throw std::runtime_error("SeedHandler::traceBackSeed(i2="+toString(i2)+") is out of range (<"+toString(seed.size2()+offset2)+")"); + if ( E_isINF( getSeedE(i1,i2) ) ) throw std::runtime_error("SeedHandler::traceBackSeed(i1="+toString(i1)+",i2="+toString(i2)+") no seed known (E_INF)"); + if ( i1+getSeedLength1(i1,i2)-1-offset1 >= seed.size1() ) throw std::runtime_error("SeedHandler::traceBackSeed(i1="+toString(i1)+") seed length ("+toString(getSeedLength1(i1,i2))+") exceeds of range (<"+toString(seed.size1()+offset1)+")"); + if ( i2+getSeedLength2(i1,i2)-1-offset2 >= seed.size2() ) throw std::runtime_error("SeedHandler::traceBackSeed(i2="+toString(i2)+") seed length ("+toString(getSeedLength2(i1,i2))+") exceeds of range (<"+toString(seed.size2()+offset2)+")"); +#endif + + // get number of base pairs within the seed + const size_t seedBps = getConstraint().getBasePairs(); + + // trace back the according seed + traceBackSeed( interaction, i1-offset1, i2-offset2 + , seedBps-2 + , getSeedLength1(i1,i2)-seedBps + , getSeedLength2(i1,i2)-seedBps ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +SeedHandler:: +getSeedE( const size_t i1, const size_t i2 ) const +{ + return seed(i1-offset1,i2-offset2).first; +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandler:: +getSeedLength1( const size_t i1, const size_t i2 ) const +{ + return decodeSeedLength1(seed(i1-offset1,i2-offset2).second); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandler:: +getSeedLength2( const size_t i1, const size_t i2 ) const +{ + return decodeSeedLength2(seed(i1-offset1,i2-offset2).second); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +SeedHandler:: +getSeedE( const size_t i1, const size_t i2, const size_t bpInbetween, const size_t u1, const size_t u2 ) +{ +// return seedE_rec[i1][i2][bpInbetween][u1][u2]; + return seedE_rec( SeedIndex({{ + (SeedRecMatrix::index) i1 + , (SeedRecMatrix::index) i2 + , (SeedRecMatrix::index) bpInbetween + , (SeedRecMatrix::index) u1 + , (SeedRecMatrix::index) u2 }}) ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +SeedHandler:: +setSeedE( const size_t i1, const size_t i2, const size_t bpInbetween, const size_t u1, const size_t u2, const E_type E ) +{ +// seedE_rec[i1][i2][bpInbetween][u1][u2] = E; + seedE_rec( SeedIndex({{ + (SeedRecMatrix::index) i1 + , (SeedRecMatrix::index) i2 + , (SeedRecMatrix::index) bpInbetween + , (SeedRecMatrix::index) u1 + , (SeedRecMatrix::index) u2 }}) ) = E; +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandler:: +encodeSeedLength( const size_t l1, const size_t l2 ) const +{ + return l1 + l2*(seedConstraint.getMaxLength1()+1); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandler:: +decodeSeedLength1( const size_t code ) const +{ + return code % (seedConstraint.getMaxLength1()+1); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandler:: +decodeSeedLength2( const size_t code ) const +{ + return code / (seedConstraint.getMaxLength1()+1); +} + +////////////////////////////////////////////////////////////////////////// + + + +#endif /* SEEDHANDLER_H_ */ diff --git a/src/SeedHandlerIdxOffset.cpp b/src/SeedHandlerIdxOffset.cpp new file mode 100644 index 00000000..f8a347e7 --- /dev/null +++ b/src/SeedHandlerIdxOffset.cpp @@ -0,0 +1,3 @@ + +#include "SeedHandlerIdxOffset.h" + diff --git a/src/SeedHandlerIdxOffset.h b/src/SeedHandlerIdxOffset.h new file mode 100644 index 00000000..e330fe94 --- /dev/null +++ b/src/SeedHandlerIdxOffset.h @@ -0,0 +1,319 @@ + +#ifndef SEEDHANDLERIDXOFFSET_H_ +#define SEEDHANDLERIDXOFFSET_H_ + +#include "SeedHandler.h" + +#include + +#include + + +/** + * Wrapper around a SeedHandler object where indices are shifted by + * a given positive offset (shifted towards infinity). + * This is useful for local interaction computations. + * + * @author Martin Mann + * + */ +class SeedHandlerIdxOffset +{ + +public: + + /** + * Construction + * @param energy the energy function to be used for seed prediction (already offset) + * @param seedConstraint the seed constraint to be applied + */ + SeedHandlerIdxOffset( + const InteractionEnergy & energy + , const SeedConstraint & seedConstraint + ); + + /** + * destruction + */ + virtual ~SeedHandlerIdxOffset(); + + /** + * Access to the currently used index offset for sequence 1 + * @return the index offset for sequence 1 used + */ + size_t getOffset1() const; + + /** + * Sets the index offset to be used for sequence 1 + * @param offset1 the index offset for sequence 1 to be used + */ + void setOffset1(size_t offset1); + + /** + * Access to the currently used index offset for sequence 2 + * @return the index offset for sequence 2 used + */ + size_t getOffset2() const; + + /** + * Sets the index offset to be used for sequence 2 + * @param offset1 the index offset for sequence 2 to be used + */ + void setOffset2(size_t offset2); + + + /////////////// OVERWRITTEN MEMBERS USING OFFSET ///////////////// + + + /** + * Access to the underlying seed constraint + * @return the used seed constraint + */ + virtual + const SeedConstraint& + getConstraint() const; + + + /** + * Computes the seed matrix for the given interval boundaries + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the first index of seq1 that might interact + * @param j1 the last index of seq1 that might interact + * @param i2 the first index of seq2 that might interact + * @param j2 the last index of seq2 that might interact + * + * @return number of possible seed interactions + */ + virtual + size_t + fillSeed(const size_t i1, const size_t j1, const size_t i2, const size_t j2); + + /** + * Identifies the base pairs of the mfe seed interaction starting at i1,i2 + * and writes them to the provided container + * + * NOTE: the right most base pair is excluded! + * + * Note, the indices are shifted by an offset for computation. + * + * @param interaction the container to add the base pairs too + * @param i1 the start of the seed in seq1 + * @param i2 the start of the seed in seq2 + */ + virtual + void + traceBackSeed( Interaction & interaction, const size_t i1, const size_t i2); + + + /** + * Access to the mfe of any seed with left-most base pair (i1,i2) + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the left most interacting base of seq1 + * @param i2 the left most interacting base of seq2 + * @return the mfe of any seed starting at (i1,i2) or E_INF if none possible + */ + virtual + E_type + getSeedE( const size_t i1, const size_t i2 ) const; + + /** + * Access to the length in seq1 of the mfe seed with left-most base pair (i1,i2) + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the left most interacting base of seq1 + * @param i2 the left most interacting base of seq2 + * @return the length in seq1 of the mfe seed starting at (i1,i2) or 0 if none possible + */ + virtual + size_t + getSeedLength1( const size_t i1, const size_t i2 ) const; + + /** + * Access to the length in seq2 of the mfe seed with left-most base pair (i1,i2) + * + * Note, the indices are shifted by an offset for computation. + * + * @param i1 the left most interacting base of seq1 + * @param i2 the left most interacting base of seq2 + * @return the length in seq2 of the mfe seed starting at (i1,i2) or 0 if none possible + */ + virtual + size_t + getSeedLength2( const size_t i1, const size_t i2 ) const; + + + +protected: + + //! the index shifted seed constraint + SeedHandler seedHandlerOriginal; + + //! the index shifted seed constraint + SeedConstraint seedConstraintOffset; + + //! offset for indices in seq1 + size_t idxOffset1; + + //! offset for indices in seq2 + size_t idxOffset2; + +}; + + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + + +inline +SeedHandlerIdxOffset::SeedHandlerIdxOffset( + const InteractionEnergy & energy + , const SeedConstraint & seedConstraint + ) + : + seedHandlerOriginal( energy, seedConstraint ) + , seedConstraintOffset(seedConstraint) + , idxOffset1(0) + , idxOffset2(0) +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +SeedHandlerIdxOffset::~SeedHandlerIdxOffset() +{ +} + +//////////////////////////////////////////////////////////////////////////// + +inline +const SeedConstraint& +SeedHandlerIdxOffset:: +getConstraint() const +{ + return seedConstraintOffset; +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandlerIdxOffset:: +fillSeed( const size_t i1min, const size_t i1max, const size_t i2min, const size_t i2max) +{ + return seedHandlerOriginal.fillSeed( i1min+idxOffset1, i1max+idxOffset1, i2min+idxOffset2, i2max+idxOffset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +SeedHandlerIdxOffset:: +traceBackSeed( Interaction & interaction + , const size_t i1 + , const size_t i2 + ) +{ + seedHandlerOriginal.traceBackSeed( interaction, i1+idxOffset1, i2+idxOffset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +E_type +SeedHandlerIdxOffset:: +getSeedE( const size_t i1, const size_t i2 ) const +{ + return seedHandlerOriginal.getSeedE( i1+idxOffset1, i2+idxOffset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandlerIdxOffset:: +getSeedLength1( const size_t i1, const size_t i2 ) const +{ + return seedHandlerOriginal.getSeedLength1( i1+idxOffset1, i2+idxOffset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandlerIdxOffset:: +getSeedLength2( const size_t i1, const size_t i2 ) const +{ + return seedHandlerOriginal.getSeedLength2( i1+idxOffset1, i2+idxOffset2 ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandlerIdxOffset:: +getOffset1() const +{ + return idxOffset1; +} + +////////////////////////////////////////////////////////////////////////// + +inline +size_t +SeedHandlerIdxOffset:: +getOffset2() const +{ + return idxOffset2; +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +SeedHandlerIdxOffset:: +setOffset1( const size_t offset ) +{ +#if IN_DEBUG_MODE + if (offset >= seedHandlerOriginal.getInteractionEnergy().size1()) { + throw std::runtime_error("SeedHandlerIdxOffset.setOffset1("+toString(offset) + +") offset > seq1.length "+toString(seedHandlerOriginal.getInteractionEnergy().size1())); + } +#endif + // set idx offset + this->idxOffset1 = offset; + // update ranges of seed constraint + seedConstraintOffset.getRanges1() = seedHandlerOriginal.getConstraint().getRanges1().shift( -(int)offset, seedHandlerOriginal.getInteractionEnergy().size1()-1-offset ); +} + +////////////////////////////////////////////////////////////////////////// + +inline +void +SeedHandlerIdxOffset:: +setOffset2( const size_t offset ) +{ +#if IN_DEBUG_MODE + if (offset >= seedHandlerOriginal.getInteractionEnergy().size2()) { + throw std::runtime_error("SeedHandlerIdxOffset.setOffset2("+toString(offset) + +") offset > seq2.length "+toString(seedHandlerOriginal.getInteractionEnergy().size2())); + } +#endif + // set idx offset + this->idxOffset2 = offset; + // update ranges of seed constraint + seedConstraintOffset.getRanges2() = seedHandlerOriginal.getConstraint().getRanges2().shift( -(int)offset, seedHandlerOriginal.getInteractionEnergy().size2()-1-offset ); +} + +//////////////////////////////////////////////////////////////////////////// + + +#endif /* SEEDHANDLERIDXOFFSET_H_ */ diff --git a/src/VrnaHandler.cpp b/src/VrnaHandler.cpp new file mode 100644 index 00000000..1ad432b7 --- /dev/null +++ b/src/VrnaHandler.cpp @@ -0,0 +1,126 @@ +/* + * ViennaSetup.cpp + * + * Created on: 22.09.2016 + * Author: Mmann + */ + +#include "VrnaHandler.h" +#include "general.h" + +#include + +extern "C" { + #include + #include +} + + + +//////////////////////////////////////////////////////////////////////////// + +VrnaHandler:: +VrnaHandler( double temperature, const std::string * const vrnaParamFile ) + : + model() + , RT(getRT(temperature)) +{ + + // init parameters from file if needed + if (vrnaParamFile != NULL) { + // read parameters from file + read_parameter_file( vrnaParamFile->c_str() ); + } + + + // get default model data + vrna_md_set_default( &model ); + + // set model details according to command line arguments + + model.temperature = temperature; +// model.temperature = this->temperature; +// double temperature; /**< @brief The temperature used to scale the thermodynamic parameters */ +// double betaScale; /**< @brief A scaling factor for the thermodynamic temperature of the Boltzmann factors */ + model.dangles = 2; +// int dangles; /**< @brief Specifies the dangle model used in any energy evaluation (0,1,2 or 3) */ +// int special_hp; /**< @brief Include special hairpin contributions for tri, tetra and hexaloops */ + model.noLP = 0; +// int noLP; /**< @brief Only consider canonical structures, i.e. no 'lonely' base pairs */ + model.noGU = 0; +// int noGU; /**< @brief Do not allow GU pairs */ + model.noGUclosure = 0; +// int noGUclosure; /**< @brief Do not allow loops to be closed by GU pair */ +// int logML; /**< @brief Use logarithmic scaling for multi loops */ + model.circ = 0; +// int circ; /**< @brief Assume RNA to be circular instead of linear */ + model.gquad = 0; +// int gquad; /**< @brief Include G-quadruplexes in structure prediction */ +// int canonicalBPonly; /**< @brief remove non-canonical bp's from constraint structures */ +// int uniq_ML; /**< @brief Flag to ensure unique multibranch loop decomposition during folding */ +// int energy_set; /**< @brief Specifies the energy set that defines set of compatible base pairs */ +// int backtrack; /**< @brief Specifies whether or not secondary structures should be backtraced */ +// char backtrack_type; /**< @brief Specifies in which matrix to backtrack */ +// int compute_bpp; /**< @brief Specifies whether or not backward recursions for base pair probability (bpp) computation will be performed */ +// char nonstandards[64]; /**< @brief contains allowed non standard bases */ + model.max_bp_span = -1; +// int max_bp_span; /**< @brief maximum allowed base pair span */ +// int min_loop_size; /**< @brief Minimum size of hairpin loops */ + model.window_size = -1; +// int window_size; /**< @brief Size of the sliding window for locally optimal structure predition */ +// int oldAliEn; /**< @brief Use old alifold energy model */ +// int ribo; /**< @brief Use ribosum scoring table in alifold energy model */ +// double cv_fact; /**< @brief Covariance scaling factor for consensus structure prediction */ +// double nc_fact; /**< @brief Scaling factor to weight covariance contributions of non-canonical pairs */ +// double sfact; /**< @brief Scaling factor for partition function scaling */ +// int rtype[8]; /**< @brief Reverse base pair type array */ +// short alias[MAXALPHA+1]; /**< @brief alias of an integer nucleotide representation */ +// int pair[MAXALPHA+1][MAXALPHA+1]; /**< @brief Integer representation of a base pair */ + + + // might need to be called to broadcast model changes globally + //vrna_md_defaults_reset(model); + +} + +//////////////////////////////////////////////////////////////////////////// + +VrnaHandler:: +~VrnaHandler() { +} + +//////////////////////////////////////////////////////////////////////////// + + + + +vrna_md_t +VrnaHandler:: +getModel( int max_bp_span, int window_size ) const +{ + // the sub model to be returned + vrna_md_t subModel; + + // copy default model + vrna_md_copy(&subModel, &model); + + // set specific parameters + subModel.max_bp_span = max_bp_span; + subModel.window_size = window_size; + + // return new model + return subModel; +} + +//////////////////////////////////////////////////////////////////////////// + +double +VrnaHandler:: +getRT( const double temperature ) +{ + return ((temperature+K0)*GASCONST/1000.0); +} + +//////////////////////////////////////////////////////////////////////////// + + diff --git a/src/VrnaHandler.h b/src/VrnaHandler.h new file mode 100644 index 00000000..dc62573e --- /dev/null +++ b/src/VrnaHandler.h @@ -0,0 +1,103 @@ +/* + * ViennaSetup.h + * + * Created on: 22.09.2016 + * Author: Mmann + */ + +#ifndef VIENNASETUP_H_ +#define VIENNASETUP_H_ + +#include "general.h" +#include + +extern "C" { + #include + #include +} + + +/** + * Central hub for Vienna RNA package related stuff + * + * @author Martin Mann + * + */ +class VrnaHandler { + +protected: + + //! VRNA parameter model + vrna_md_t model; + + //! the RT constant used for the current setup + E_type RT; + +public: + + /** + * Construction with global VRNA folding parameter setup + * + * @param temperature Folding temperature in Celsius + * @param vrnaParamFile name of a VRNA parameter file to be used for + * parameter setup or NULL if defaults are to be used + */ + VrnaHandler( + double temperature = 37.0, + const std::string * const vrnaParamFile = NULL ); + + /** + * destruction + */ + virtual ~VrnaHandler(); + + /** + * Generates a new VRNA parameter model according to the global and local settings + * + * NOTE: you have to call vrna_md_defaults_reset() to broadcast + * the model details before using non-VRNA-API-3 functions. + * + * @param max_bp_span Maximal distance between base pair partners within one RNA + * or -1 if no constraint needed + * @param window_size Size of the sliding window for locally folding within one RNA + * or -1 if no constraint needed + * @return the model to be used for VRNA computations + */ + vrna_md_t + getModel( int max_bp_span = -1, int window_size = -1 ) const; + + /** + * Provides RT for the current setup + * @return R*temperature + */ + double + getRT() const; + + /** + * Provides RT for the given temperature + * @return R*temperature + */ + static + double + getRT( const double temperature ); + + + +}; + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +inline +double +VrnaHandler:: +getRT() const +{ + return RT; +} + +//////////////////////////////////////////////////////////////////////////// + + +#endif /* VIENNASETUP_H_ */ diff --git a/src/basics.cpp b/src/basics.cpp deleted file mode 100644 index 06656efa..00000000 --- a/src/basics.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#include "basics.h" - -/********************************************************** - translates an integerBase to a characterBase (nucleotide) -**********************************************************/ - -char int2char(int base) -{ - if (base == 0) return 'A'; - else if (base == 1) return 'C'; - else if (base == 2) return 'G'; - else if (base == 3) return 'U'; - else if (base == 4) return 'N'; - else - { - cerr << "There's something wrong in your int-base!"; - exit(1); - } -} - -/********************************************************** - translates an integerSeq. to a characterSeq. (nucleotide) -**********************************************************/ - -char* int2char(int* num_seq, int size) -{ - char* seq = (char*) malloc(sizeof(char)*size); - for (int i=0; i 3'-5') -*********************************************************/ -void change_direction(char* sequence) -{ - int len = (int)strlen(sequence); - char reverse_sequence[len+1]; - - for (int i=0; i=0) - x_int = (int)((x*1000)+0.5); - else - x_int = (int)((x*1000)-0.5); - - return (double) x_int/1000; -} - - - -/************************************************************ - finds the minimum of two integers -************************************************************/ - -int Minimum(int a, int b) -{ - if (ab) - return a; - else - return b; -} - - - -/************************************************************ - returns the sum of a and b, if either a or b is MAX_DOUBLE, - it returns MAX_DOUBLE -************************************************************/ - -double Sum_or_MAX_DOUBLE(double a, double b) -{ - if ((a==MAX_DOUBLE) || (b==MAX_DOUBLE)) - return MAX_DOUBLE; - else - return a+b; -} - - - -/************************************************************ - sums up all values of a vector -************************************************************/ - -int SumVec(int* vec, int size) -{ - int sum = 0; - for (int i=0; i max[1]) - { - max[1] = vec[i]; - max[0] = i; - } - return max; -} - - - diff --git a/src/basics.h b/src/basics.h deleted file mode 100644 index 69f815e5..00000000 --- a/src/basics.h +++ /dev/null @@ -1,207 +0,0 @@ -/*************************************************************************** - basics.h - global variables - ------------------- - begin : 30-08-2004 - copyright : (C) 2004 by Anke Busch - email : anke.busch@informatik.uni-freiburg.de - ***************************************************************************/ - -#ifndef _BASICS__ -#define _BASICS__ - -#include -#include -#include -#include -#include -#include -#include -#include "energy.h" -#include "interior_energy.h" -#include "stacking_energy.h" -#include "bulge_energy.h" -#include "dangling_energy.h" -#include "hybrid.h" -#include "single_run.h" - -extern "C"{ - #include - #include - #include - #include - #include - #include - #include - } - -using namespace std; -/********************************************************************************** -* Structure- and Type definitions * -**********************************************************************************/ -typedef unsigned int unt; - - -/********************************************************************************** -* Makros * -**********************************************************************************/ -#define NUM_ACIDS 20 -#define NUM_PAM 21 - - -/********************************************************************************** -* Constants * -**********************************************************************************/ - -extern const int MAX_BULGE_SIZE; -extern const int MAX_INTERIOR_ONE_SIDE_SIZE; - -extern const double K_0; -extern const double T_MEASURE; -extern const double R; - -extern const double MIN_DOUBLE; -extern const double MAX_DOUBLE; -extern const double DOUBLE_DIFF; - -extern const int MIN_INT; -extern const int MAX_INT; - - -/********************************************************************************** -* global variabels (extern) * -**********************************************************************************/ - -extern double stacking_energies[]; -extern double stacking_enthalpies[]; -extern double interior_loop_1_1_energy[]; -extern double interior_loop_1_1_enthalpy[]; -extern double interior_loop_1_2_energy[]; -extern double interior_loop_1_2_enthalpy[]; -extern double interior_loop_2_2_energy[]; -extern double interior_loop_2_2_enthalpy[]; -extern double loop_destabilizing_energies[]; -extern double single_base_stacking_energy[]; -extern double single_base_stacking_enthalpies[]; -extern double mismatch_energies_hairpin[]; -extern double mismatch_energies_interior[]; -extern double mismatch_enthalpies[]; - -extern double RT ; -extern double duplex_init ; -extern double terminal_AU ; -extern double loop_extrapolation ; -extern double max_ninio_correction; -extern double ninio_correction ; - -extern char* sequence_target ; -extern char* sequence_miRNA ; -extern int* int_sequence_target ; -extern int* int_sequence_miRNA ; -extern vector< string > targets ; -extern vector< string > miRNAs ; - -extern int** che1 ; -extern int** che2 ; -extern int** ches1 ; -extern int** ches2 ; -extern double** C ; -extern double** Cseed ; -extern double** U ; -extern double** ED_target ; -extern bool ED_target_computed ; -extern double ED_target_scaling ; -extern double** ED_miRNA ; -extern bool ED_miRNA_computed ; -extern double ED_miRNA_scaling ; -extern double** seed ; -extern int** seed_unpaired_target; -extern int** seed_unpaired_miRNA ; -extern int num_bp_seed ; -extern int max_unpaired_target ; -extern int max_unpaired_miRNA ; -extern int max_unpaired ; -// next line is quick hack, please remove if not needed anymore -extern double pu_comb_threshold ; -extern int seed_region_start_ncRNA_5; -extern int seed_region_end_ncRNA_5; -extern int seed_region_start_ncRNA_3; -extern int seed_region_end_ncRNA_3; -extern bool seed_region_ncRNA ; -extern bool window ; -extern int window_size ; -extern double threshold ; -extern bool max_length ; -extern int max_unpaired_length ; -extern bool max_dist ; -extern int max_pair_dist ; -extern int max_subopt ; -extern int best_che1 ; -extern int best_che2 ; -extern bool detailed_output ; -extern bool use_RNAplfold ; -extern bool use_RNAup ; -extern bool target_file ; -extern bool miRNA_file ; -extern bool heuristic ; - - -extern double***** hybrid_matrix ; - -extern string target_name ; -extern string miRNA_name ; -extern string hybrid_sequence_target; -extern string hybrid_sequence_miRNA; -extern string bulges_sequence_target; -extern string bulges_sequence_miRNA; -extern string hybrid_pos_target ; - -extern int target_counter ; -extern int miRNA_counter ; - -extern int pos_target_1 ; -extern int pos_target_2 ; -extern int pos_target_3 ; -extern int pos_target_4 ; -extern int pos_target_1_dangle ; -extern int pos_target_4_dangle ; -extern int pos_miRNA_1 ; -extern int pos_miRNA_2 ; -extern int pos_miRNA_3 ; -extern int pos_miRNA_4 ; -extern int pos_miRNA_1_dangle ; -extern int pos_miRNA_4_dangle ; - -/********************************************************************************** -* Funktionen * -**********************************************************************************/ - -char int2char(int base); -char* int2char(int* num_seq, int size); -int char2int_base(char base); -int* char2int(char* seq); -void change_direction(char* sequence); - -int BP2int(int b1, int b2); -void BP2_2(int bp, int &base_i, int &base_j); - -bool PairTest(int b1, int b2); -bool PairTest(char b1, char b2); - -bool check_sequence_and_set2upper(char* seq); -bool check_sequence_and_set2upper(string& seq); - -bool is_ambiguous_sequence(char* seq); - -double Double_Round(double x); -int Minimum(int a, int b); -double Minimum(double a, double b); -int Maximum(int a, int b); - -double Sum_or_MAX_DOUBLE(double a, double b); -int SumVec(int* vec, int size); - -double* MiniVec(double* vec, int size); -double* MaxiVec(double* vec, int size); - - -#endif // _BASICS_ diff --git a/src/bulge_energy.cpp b/src/bulge_energy.cpp deleted file mode 100644 index 2717636f..00000000 --- a/src/bulge_energy.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "bulge_energy.h" - -double BulgeEnergy(int size, int bp_i, int bp_j, int bp_before_i, int bp_before_j) -{ - double energy = 0.0; - - // valid base pair test: - //**************************** - if ((PairTest(bp_before_i, bp_before_j) == false) || (PairTest(bp_i, bp_j) == false)) - return MAX_DOUBLE; - else - { - int bp_before = BP2int(bp_before_i, bp_before_j); - - // no bulges of size 0: - //****************************************** - if (size == 0) - { - cerr << "No Bulge!" << endl; - exit(1); - } - - // loop_destabilizing_energies: - //****************************** - if (size <= 30) - energy += loop_destabilizing_energies[3*size-2]; - else - { - energy += loop_destabilizing_energies[3*30-2]; - // energy += 1.75*RT*log((double)(size/30.0)); replaced by - energy += loop_extrapolation*log((double)(size/30.0)); - } - - // additional bulge-energy (size 1: stacking, >1: nothing, but term. A-U-penalty: - //********************************************************************************** - if (size == 1) - energy += stacking_energies[64*bp_i+16*bp_before_i+4*bp_j+bp_before_j]; - else - { - if ((bp_before == 0) || (bp_before == 3) || (bp_before == 4) || (bp_before == 5)) - energy += terminal_AU; - if ((BP2int(bp_i, bp_j) == 0) || (BP2int(bp_i,bp_j) == 3) || (BP2int(bp_i,bp_j) == 4) || (BP2int(bp_i,bp_j) == 5)) - energy += terminal_AU; - } - return energy; - } -} diff --git a/src/bulge_energy.h b/src/bulge_energy.h deleted file mode 100644 index 169ac078..00000000 --- a/src/bulge_energy.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _BULGE_ENERGY__ -#define _BULGE_ENERGY__ - -#include -#include "basics.h" - -using namespace std; - -double BulgeEnergy(int size, int bp_i, int bp_j, int bp_before_i, int bp_before_j); - -#endif // _BULGE_ENERGY_ diff --git a/src/calc_hybrid_energy.cpp b/src/calc_hybrid_energy.cpp deleted file mode 100644 index 7b3ab16a..00000000 --- a/src/calc_hybrid_energy.cpp +++ /dev/null @@ -1,724 +0,0 @@ -/*************************************************************************** - calc_hybrid_energy.cpp - main - ------------------- - begin : April-2007 - copyright : (C) 2007 by Anke Busch & Sven Siebert - email : anke.busch@informatik.uni-freiburg.de - ***************************************************************************/ - -#include -#include -#include -#include -#include "basics.h" - -using namespace std; - - -/********************************************************************************** -* Constants * -* defined in "basics.h" -**********************************************************************************/ - -const int MAX_BULGE_SIZE = 16; -const int MAX_INTERIOR_ONE_SIDE_SIZE = 16; - -const double K_0 = 273.15; // temperature of 0°C in [K] -const double T_MEASURE = 310.15; // temperature in [K] used to measure free energies -const double R = 1.98717; // gas constant in [cal/K/mol], value used by Vienna Package 1.7 - -// const double T = 310.15 ; // temperature in Kelvin(37C);K=C+273.15 -// const double RT = 0.616 ; // Boltzmann gas constant in kcal/mol -// RT=kT=1.380622*10^(-23)Joule/K *310.15K (37C=273.15K+37K=310.15K) - - -const double MIN_DOUBLE = -1000000.0; -const double MAX_DOUBLE = 1000000.0; -const double DOUBLE_DIFF = 0.00001; - -const int MIN_INT = -1000000; -const int MAX_INT = 1000000; - -/********************************************************************************** -* global variabels * -**********************************************************************************/ -double RT ; // product of gas constant and temperature -double duplex_init ; // intermolecular initiation free energy -double terminal_AU ; // terminal AU penalty (actually non-GC penalty) -double loop_extrapolation ; // extrapolation term for large loops (internal, bulge or hairpin) > 30 nt: - // dS(T)=dS(30)+loop_extrapolation*ln(n/30) -double max_ninio_correction; // asymmetric internal loops maximum correction term -double ninio_correction ; // asymmetric internal loops Ninio correction term - -char* sequence_target ; //input sequence 1 -char* sequence_miRNA ; //input sequence 2 -int* int_sequence_target ; //input sequence 1 as integers (A=0,C=1,G=2,U=3) -int* int_sequence_miRNA ; //input sequence 2 as integers (A=0,C=1,G=2,U=3) - -vector< string > targets ; //used if sequences are put in via a .fasta file -vector< string > miRNAs ; //used if sequences are put in via a .fasta file -int** che1 ; //C-hybridization-end in the mRNA -int** che2 ; //C-hybridization-end in the sRNA -int** ches1 ; //Cseed-hybridization-end in the mRNA -int** ches2 ; //Cseed-hybridization-end in the sRNA -double** C ; //C-matrix (~RNAhybrid, includes mfe if the last bases pair) -double** Cseed ; //C^seed-matrix (RNAhyrid+seed, includes mfe if the last bases pair) -double** U ; //U-matrix (includes mfe if last bases in one or both sequences are unpaired) -double** ED_target ; //matrix of the energy differences of the mRNA (ED = E^unpaired-E^all) -bool ED_target_computed ; //is true if ED_target is computed, which is done after the first valid seed is found -double ED_target_scaling ; //scaling factor for target ED -double** ED_miRNA ; //matrix of the energy differences of the sRNA (ED = E^unpaired-E^all) -bool ED_miRNA_computed ; //is true if ED_miRNA is computed, which is done after the first valid seed is found -double ED_miRNA_scaling ; //scaling factor for miRNA ED -double** seed ; //matrix, that stores the best seed-hybridizing energy, (seed(i,j) gives the mfe of hybridization starting at (i,j)) -int** seed_unpaired_target; //matrix, that stores the number of unbound bases in the target that give the mfe in seed -int** seed_unpaired_miRNA ; //matrix, that stores the number of unbound bases in the miRNA that give the mfe in seed -int num_bp_seed ; //number of base pairs that the user wants to be in the seed region -int max_unpaired_target ; //max. number of unpaired bases in the seed of the target -int max_unpaired_miRNA ; //max. number of unpaired bases in the seed of the target -int max_unpaired ; //max. number of unpaired bases in the seed (sum of unpaired bases in both sequences) -// next line is quick hack, please remove if not needed anymore -double pu_comb_threshold ; // lower end of boxplot for L100, W200 and u=5: 0.0068; u=6: 0.0018; u=7: 0.00045 -int seed_region_start_ncRNA_5; //start of seed region in ncRNA as passed from 5' end counting from 1 -int seed_region_end_ncRNA_5; //end of seed region in ncRNA as passed from 5' end counting from 1 -int seed_region_start_ncRNA_3; //internal start of seed region in ncRNA from 3' end counting from 0 -int seed_region_end_ncRNA_3; //internal end of seed region in ncRNA given from 3' end counting from 0 -bool seed_region_ncRNA ; //is true if seed region in ncRNA is given -bool window ; //is true if sliding window approach is used -int window_size ; //size of the sliding window -double threshold ; //threshold for output of results below value 'threshold' -bool max_length ; //is true if max. size of unpaired region is specified -int max_unpaired_length ; //max. size of the unpaired region during the calculation of ED_... -bool max_dist ; //is true if max. base pair span is specified -int max_pair_dist ; //maximal base pair span used for ED-calculation with RNAplfold -int max_subopt ; //max. number of calculated suboptimal hybridizations -int best_che1 ; //best C-hybridization-end in the mRNA -int best_che2 ; //best C-hybridization-end in the sRNA - -bool detailed_output ; //is true, if a detailed output is wanted -bool use_RNAplfold ; //is true, if RNAplfold-procedures are used to compute ED-values in the target -bool use_RNAup ; //is true, if RNAup-procedures are used to compute ED-values in the sRNA -bool target_file ; //true if target file is given -bool miRNA_file ; //true if miRNA file is given -bool heuristic ; //true if heuristic for hybridization end is used - -double***** hybrid_matrix ; //stores the hybridizing energies - -string target_name ; //name of current target -string miRNA_name ; //name of current miRNA -string hybrid_sequence_target; //target sequence after hybridization -string hybrid_sequence_miRNA ; //miRNA sequence after hybridization -string bulges_sequence_target; //bulges in target sequence after hybridization -string bulges_sequence_miRNA ; //bulges in miRNA sequence after hybridization -string hybrid_pos_target ; //positions in target not considered yet for suboptimal hybridizations - -int target_counter ; //counts the analyzed targets -int miRNA_counter ; //counts the analyzed miRNAs - - -/********************************************************************************** -* stable regions very stable region(seed) stable region -* -* pos2 pos3 -* pos1 | | pos4 -* | ***************************** | -* ****************************************************************** -* ACUAUCGUGCUAGUGCAUGCUGACUGAUGCUGAUCUGAUGCUGAUGCAUCUAUCUAUCUACUAUCUGAUCGAUCGAUCCUAGCUGAGCUAC -* ******************************************************************** -* | | -* pos1_dangle pos4_dangle -* -**********************************************************************************/ - -int pos_target_1 ; -int pos_target_2 ; -int pos_target_3 ; -int pos_target_4 ; -int pos_target_1_dangle ; -int pos_target_4_dangle ; -int pos_miRNA_1 ; -int pos_miRNA_2 ; -int pos_miRNA_3 ; -int pos_miRNA_4 ; -int pos_miRNA_1_dangle ; -int pos_miRNA_4_dangle ; - - - -/********************************************************************************** -* help for calling the program * -**********************************************************************************/ - -void usage() -{ - cout << endl; - cout << "Synopsis : IntaRNA [-t fasta_file] [-m fasta_file] [-v energy] [-o]" << endl; - cout << " [-s number] [-n] [-h] [-u[1|2] number] [-u number]" << endl; - cout << " [-p number] [-f pos,pos] [-T temp] [-U] [-P][-w size]" << endl; - cout << " [-L distance] [-l length] [-a weight] [-b weight]" << endl; - cout << " [-c threshold] target-RNA-seq binding-RNA-seq" << endl << endl; - cout << "Description : finds optimal hybridization location between RNA sequences" << endl; - cout << " target-RNA-seq and binding-RNA-seq according to the sum of 3 energy" << endl; - cout << " contributions:" << endl; - cout << " 1) energy to open the binding site in the target RNA" << endl; - cout << " 2) energy to open the binding site in the binding RNA" << endl; - cout << " 3) hybridization energy between both RNAs" << endl << endl;; - cout << "Options : " << endl; - cout << " === General parameters === " << endl; - cout << " -t fasta_file : use fasta file of target sequences" << endl; - cout << " -m fasta_file : use fasta file of binding sequences" << endl; - cout << " -v energy : outputs all results below energy in kcal/mol" << endl; - cout << " -o : detailed output" << endl; - cout << " -s number : max. number of calculated suboptimal results" << endl; - cout << " (default:0)" << endl; - cout << " -n : use no heuristic for hybridization end" << endl; - cout << " (complete approach, more time-consuming)" << endl; - cout << " Does not support -s option" << endl; - cout << " -h : this help" << endl << endl; - cout << " === Seed parameters === " << endl; - cout << " -p number : exact number of paired bases in the seed region" << endl; - cout << " (default:6)" << endl; - cout << " -u[1|2] number : max. number of unpaired bases in the seed" << endl; - cout << " region in" << endl; - cout << " 1: the first sequence (default:0)" << endl; - cout << " 2: the second sequence (default:0)" << endl; - cout << " -u number : max. number of unpaired bases in the seed" << endl; - cout << " region in both sequences (default:0)" << endl; - cout << " -f number,number : search for seed in binding RNA (e.g. ncRNA)" << endl; - cout << " in region between positions start,end" << endl; - cout << " (given in 5' to 3' direction counting from 1)" << endl << endl; - cout << " === RNA folding parameters === " << endl; - cout << " -T temp : temperature in Celsius (default: 37°C)" << endl; - cout << " -U : use RNAup to compute ED values of binding RNA" << endl; - cout << " (default)" << endl; - cout << " -P : use RNAplfold to compute ED values of target RNA" << endl; - cout << " (default)" << endl; - cout << " -w size : window size for computation of ED values" << endl; - cout << " with RNAplfold (default: length of target RNA)" << endl; - cout << " -L distance : max. distance of two paired bases for" << endl; - cout << " computation of ED values with RNAplfold" << endl; - cout << " (default: window size)" << endl; - cout << " -l length : max. length of hybridized region, mainly used " << endl; - cout << " for efficient computation (default: window size)" << endl; - cout << " -a weight : weight for ED values of target RNA in energy "<< endl; - cout << " (default: 1.0)" << endl; - cout << " -b weight : weight for ED values of binding RNA in energy "<< endl; - cout << " (default: 1.0)" << endl; - cout << " -c threshold : threshold for seed accessibility, requires u=0 "<< endl; - cout << " EXPERIMENTAL FEATURE, (default: -1.0)" << endl << endl; - cout << "Example :-find optimal hybridization location between two RNAs:" << endl; - cout << " IntaRNA CCCCCCCCCCCCGGG GGGGGGCCC" << endl; - cout << " Output: " << endl; - cout << " 5'-CCCCCC GGG-3'" << endl; - cout << " CCCCCC" << endl; - cout << " GGGGGG" << endl; - cout << " 3'-CCC -5'" << endl; - cout << " energy: -11.4152 kcal/mol" << endl << endl; - cout << "Contact : intarna@informatik.uni-freiburg.de" << endl; - cout << endl; -} - -/* -void usage_help(char* name) -{ - cout << "\ncall: " << name << " \"sequence1\" \"sequence2\"\n"; - cout << " [-p number of base paired in the seed region, default: 4]\n"; - cout << " [-B max. number of unpaired bases in the seed region of seq. 1, default: 0]\n"; - cout << " [-b max. number of unpaired bases in the seed region of seq. 2, default: 0]\n"; - cout << " [-U max. number of unpaired bases in the seed region of both seq's, default: 0] \n"; - cout << " [-w window size for sliding window approach, default: sliding window appr. not used]\n"; - cout << " [-l max. length of an unpaired region (that is considered)]\n"; - cout << " [-T temperature in Celsius, default: 37 Celsius]\n"; - cout << " [-o] if a detailed output is wanted\n"; - cout << "\n"; - cout << endl; - exit(1); -} -*/ - - - -/********************************************************************************** -* Main-Function * -**********************************************************************************/ - -int main(int argc, char *argv[]) -{ - do_backtrack = 1; // must be set for RNAup - fold_constrained = 1; - - /*default values*/ - -// energy parameter from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999)- do not change! - RT = R*T_MEASURE/1000.0; // in [kcal/mol] - duplex_init = 4.10; - terminal_AU = 0.50; - loop_extrapolation = 1.079; - max_ninio_correction = 3.00; - ninio_correction = 0.50; -// ************************************************************************************************ - - ED_target_computed = false; - ED_miRNA_computed = false; - - ED_target_scaling = 1.0; - ED_miRNA_scaling = 1.0; - - num_bp_seed = 6; - max_unpaired_target = 0; - max_unpaired_miRNA = 0; - max_unpaired = 0; - pu_comb_threshold = -1.0; - seed_region_start_ncRNA_5 = -1; - seed_region_start_ncRNA_3 = -1; - seed_region_end_ncRNA_5 = -1; - seed_region_end_ncRNA_3 = -1; - seed_region_ncRNA = false; - window = false; - window_size = -1; - max_length = false; - max_unpaired_length = -1; - max_dist = false; - max_pair_dist = -1; - detailed_output = false; - threshold = MAX_DOUBLE; - max_subopt = 0; - best_che1 = -1; - best_che2 = -1; - target_name = ""; - miRNA_name = ""; - use_RNAplfold = true; - use_RNAup = true; - heuristic = true; - - target_file = false; - char* target_file_name = NULL; - - miRNA_file = false; - char* miRNA_file_name = NULL; - - target_counter = 0; - miRNA_counter = 0; - - /********************************************** - * reading the options * - **********************************************/ - - int opt; - int option_index = 0; - - static struct option long_options[] = - { - /* These options are distinguished by their indices. */ - {"u1", required_argument, 0, 'x'}, - {"u2", required_argument, 0, 'y'}, - {0,0,0,0} - }; - - while ((opt = getopt_long_only(argc, argv, "x:y:u:p:f:T:w:l:L:a:b:c:v:s:t:m:oPnhU",long_options, &option_index)) != -1) - { - switch (opt) - { - - case 'x': max_unpaired_target = atoi(optarg); - //cout << "max_unpaired_target: " << max_unpaired_target << endl; - break; - - case 'y': max_unpaired_miRNA = atoi(optarg); - //cout << "max_unpaired_miRNA : " << max_unpaired_miRNA << endl; - break; - - case 'u': max_unpaired = atoi(optarg); - //cout << "max_unpaired : " << max_unpaired << endl; - break; - - /*case 'u': int seqnum =atoi(argv[optind]); - int num_unpaired=atoi(argv[optind+1]); - optind+=2; - if (seqnum==1) - max_unpaired_target = num_unpaired; - else if (seqnum==2) - max_unpaired_miRNA = num_unpaired; - else if (seqnum==3) - max_unpaired = num_unpaired; - else - { - cerr << "no valid sequence identifier" << endl; - exit(1); - } - break;*/ - - case 'p': num_bp_seed = atoi(optarg); - break; - case 'f': // passed positions count from 5' with 1, but internal indices count from 3' with 0 - sscanf(optarg,"%d,%d",&seed_region_start_ncRNA_5,&seed_region_end_ncRNA_5); - seed_region_ncRNA = true; - break; - case 'T': temperature = atof(optarg); // in [°C] - RT = R*(temperature+K_0)/1000.0; // in [kcal/mol] - scale_parameters(); - break; - case 'w': window_size = atoi(optarg); - window = true; - break; - case 'l': max_unpaired_length = atoi(optarg); - max_length = true; - break; - case 'L': max_pair_dist = atoi(optarg); - max_dist = true; - break; - case 'a': ED_target_scaling = atof(optarg); - break; - case 'b': ED_miRNA_scaling = atof(optarg); - break; - case 'c': pu_comb_threshold = atof(optarg); - break; - case 'v': threshold = atoi(optarg); - break; - case 's': max_subopt= (heuristic?atoi(optarg):0); - break; - case 't': target_file_name = optarg; - target_file = true; - break; - case 'm': miRNA_file_name = optarg; - miRNA_file = true; - break; - case 'o': detailed_output = true; - break; - case 'P': use_RNAplfold = true; - break; - case 'U': use_RNAup = true; - // must be set to calculate the base pair probability matrix - do_backtrack = 1; - break; - case 'n': heuristic = false; - max_subopt = 0; - break; - case 'h': usage(); - exit(0); - case '?': if (isprint (optopt) ) - cerr << "Unknown option `-" << optopt << "`" << endl; - else - cerr << "Unknown option character `" << optopt << "`" << endl; - return 1; - default : abort (); - } - } - - /***************************************************************** - * if RNAplfold is used, max_length and window must also be given * - *****************************************************************/ - - /*if ((use_RNAplfold == true) && ((max_length == false) || (window == false))) - { - cerr << "Window size (-w) and the max. length of the hybridized region (-l) must be given when using RNAplfold (-P)!" << endl; - exit(1); - }*/ - - /********************************************** - * reading the sequences * - **********************************************/ - - if ((target_file == false) && (miRNA_file == false)) - { - if (optind < argc) - { - sequence_target = argv[optind++]; - if (optind < argc) - { - sequence_miRNA = argv[optind++]; - if (optind < argc) - { - for (int i=optind;i -#include "basics.h" - -using namespace std; - -double ed3(int bp_j, int bp_i, int dangle3); -double ed5(int bp_j, int bp_i, int dangle5); - -#endif // _DANGLING_ENERGY__ diff --git a/src/data/interior_loop_1_1_energies.dat b/src/data/interior_loop_1_1_energies.dat deleted file mode 100644 index 2b36c23a..00000000 --- a/src/data/interior_loop_1_1_energies.dat +++ /dev/null @@ -1,117 +0,0 @@ -// Single mismatch energies (1 x 1 interior loops) from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// Data table for symetric interior loops of size 2 -// Free energies at 37 degrees for RNA -// Data Arrangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' --> 3' -// (*24) -// X -// (*96)A A(*4) -// U U -// Y -// (*1) -// 3' <-- 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) . . . . - -// -// A-U=0 , C-G=1 , G-C=2 , U-A=3 , G-U=4 , U-G=5 -// matrix coordinates = 96*(1)+24*(2)+4*(3)+(4) - -double interior_loop_1_1_energy[]= -{ -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70,-0.40, 1.70, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, - 1.70, 1.70, 1.70, 1.50, 1.10, 1.10, 1.10, 1.00, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.20, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.10, 1.10, 1.10, 1.10, 0.40,-0.40, 0.40, 0.40, 1.10, 0.40, 0.40, 0.40, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, - 1.10, 1.10, 1.10, 1.10, 0.30, 0.50, 0.40, 0.50, 0.40, 0.40, 0.40, 0.40, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, - 1.10, 1.10,-1.00, 1.10,-0.10, 0.40,-1.70, 0.40, 0.40, 0.40,-1.40, 0.40, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, - 1.10, 1.10, 1.10, 1.10, 0.40, 0.00, 0.40,-0.30, 0.40, 0.40, 0.40, 0.40, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.10, 1.10, 1.10, 1.10, 0.80, 0.40, 0.40, 0.40, 0.40, 0.30,-0.10, 0.40, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, - 1.10, 1.10, 1.10, 1.10, 0.40, 0.40, 0.40, 0.40,-0.40, 0.50, 0.40, 0.00, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, - 1.10, 1.10,-1.00, 1.10, 0.40, 0.40,-2.10, 0.40, 0.40, 0.40,-1.70, 0.40, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, - 1.10, 1.10, 1.10, 1.10, 0.40, 0.40, 0.40,-0.70, 0.40, 0.50, 0.40,-0.30, 1.10, 1.10, 1.10, 1.00, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70,-0.40, 1.70, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, - 1.70, 1.70, 1.70, 1.80, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.50, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70,-0.40, 1.70, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, - 1.70, 1.70,-0.40, 1.70, 1.10, 1.10,-1.00, 1.10, 1.10, 1.10,-1.00, 1.10, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, 1.70, 1.70,-0.40, 1.70, - 1.70, 1.70, 1.70, 1.70, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.10, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70, 1.70 -}; diff --git a/src/data/interior_loop_1_1_enthalpies.dat b/src/data/interior_loop_1_1_enthalpies.dat deleted file mode 100644 index 908363e9..00000000 --- a/src/data/interior_loop_1_1_enthalpies.dat +++ /dev/null @@ -1,117 +0,0 @@ -// Single mismatch enthalpies (1 x 1 interior loops) from mfold Version 2.3 (Walter et al.:PNAS1994) -// Data table for symetric interior loops of size 2 -// Enthalpies for RNA -// Data Arrangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' --> 3' -// (*24) -// X -// (*96)A A(*4) -// U U -// Y -// (*1) -// 3' <-- 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) . . . . - -// -// A-U=0 , C-G=1 , G-C=2 , U-A=3 , G-U=4 , U-G=5 -// matrix coordinates = 96*(1)+24*(2)+4*(3)+(4) - -double interior_loop_1_1_enthalpy[]= -{ -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// Y Y Y Y Y Y -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, - 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, -}; diff --git a/src/data/interior_loop_1_2_energies.dat b/src/data/interior_loop_1_2_energies.dat deleted file mode 100644 index 140be9bf..00000000 --- a/src/data/interior_loop_1_2_energies.dat +++ /dev/null @@ -1,385 +0,0 @@ -// (1 x 2 interior loop energies) from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// Data tables for asymmetric interior loops of size 3 -// Free energies at 37 degrees for RNA -// Data arrangement: -// -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' --> 3' -// (*24) -// X -// (*384)A A(*4) -// U U -// YA -// (*1)(*96) -// 3' <-- 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) . . . . - - -double interior_loop_1_2_energy[]= -{ -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.90, 3.70, 3.10, 5.50, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, - 3.80, 3.70, 5.50, 3.70, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, - 3.20, 5.50, 2.30, 5.50, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.60, 3.20, 3.10, 5.50, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, - 3.70, 4.00, 5.50, 3.70, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.70, 5.50, 2.80, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 2.50, 2.10, 1.90, 5.50, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 2.30, 5.50, 3.70, 5.50, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 4.00, 3.40, 5.50, 3.70, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.20, 5.50, 2.70, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.20, 3.00, 2.40, 4.80, 2.30, 2.20, 1.10, 4.00, 2.40, 2.20, 1.60, 4.00, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, - 3.10, 3.00, 4.80, 3.00, 2.30, 2.20, 4.00, 2.20, 2.30, 2.20, 4.00, 2.20, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, - 2.50, 4.80, 1.60, 4.80, 1.70, 4.00, 0.80, 4.00, 1.70, 4.00, 0.80, 4.00, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 2.90, 2.50, 2.40, 4.80, 2.10, 1.70, 1.60, 4.00, 2.10, 1.70, 1.60, 4.00, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, - 3.00, 3.30, 4.80, 3.00, 2.20, 2.50, 4.00, 2.20, 2.20, 2.50, 4.00, 2.20, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 4.80, 3.00, 4.80, 2.10, 4.00, 2.20, 4.00, 1.50, 4.00, 2.20, 4.00, 1.30, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.80, 1.40, 1.20, 4.80, 0.80, 0.60, 0.40, 4.00, 1.00, 0.60, 0.40, 4.00, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 1.60, 4.80, 3.00, 4.80, 0.80, 4.00, 2.20, 4.00, 0.80, 4.00, 2.20, 4.00, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 3.30, 2.70, 4.80, 3.00, 2.50, 1.90, 4.00, 2.20, 2.50, 1.90, 4.00, 2.20, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 4.80, 2.50, 4.80, 2.00, 4.00, 1.70, 4.00, 1.20, 4.00, 1.70, 4.00, 1.20, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.20, 3.00, 2.40, 4.80, 2.40, 2.20, 1.60, 4.00, 2.50, 2.20, 2.10, 4.00, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, - 3.10, 3.00, 4.80, 3.00, 2.30, 2.20, 4.00, 2.20, 2.30, 2.20, 4.00, 2.20, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, - 2.50, 4.80, 1.60, 4.80, 1.70, 4.00, 0.80, 4.00, 1.70, 4.00, 0.80, 4.00, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 2.90, 2.50, 2.40, 4.80, 2.10, 1.70, 1.60, 4.00, 2.10, 1.70, 1.60, 4.00, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, - 3.00, 3.30, 4.80, 3.00, 2.20, 2.50, 4.00, 2.20, 2.20, 2.50, 4.00, 2.20, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 4.80, 3.00, 4.80, 2.10, 4.00, 2.20, 4.00, 1.30, 4.00, 2.20, 4.00, 1.20, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.80, 1.40, 1.20, 4.80, 1.00, 0.60, 0.40, 4.00, 1.20, 0.60, 0.40, 4.00, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 1.60, 4.80, 3.00, 4.80, 0.80, 4.00, 2.20, 4.00, 0.80, 4.00, 2.20, 4.00, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 3.30, 2.70, 4.80, 3.00, 2.50, 1.90, 4.00, 2.20, 2.50, 1.90, 4.00, 2.20, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, - 4.80, 4.80, 4.80, 4.80, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.00, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, - 4.80, 2.50, 4.80, 2.00, 4.00, 1.70, 4.00, 1.20, 4.00, 1.70, 4.00, 1.20, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.90, 3.70, 3.10, 5.50, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, - 3.80, 3.70, 5.50, 3.70, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, - 3.20, 5.50, 2.30, 5.50, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.60, 3.20, 3.10, 5.50, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, - 3.70, 4.00, 5.50, 3.70, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.70, 5.50, 2.80, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 2.50, 2.10, 1.90, 5.50, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 2.30, 5.50, 3.70, 5.50, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 4.00, 3.40, 5.50, 3.70, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.20, 5.50, 2.70, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.90, 3.70, 3.10, 5.50, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, - 3.80, 3.70, 5.50, 3.70, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, - 3.20, 5.50, 2.30, 5.50, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.60, 3.20, 3.10, 5.50, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, - 3.70, 4.00, 5.50, 3.70, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.70, 5.50, 2.80, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 2.50, 2.10, 1.90, 5.50, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 2.30, 5.50, 3.70, 5.50, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 4.00, 3.40, 5.50, 3.70, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.20, 5.50, 2.70, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.90, 3.70, 3.10, 5.50, 3.20, 3.00, 2.40, 4.80, 3.20, 3.00, 2.40, 4.80, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, 3.90, 3.70, 3.10, 5.50, - 3.80, 3.70, 5.50, 3.70, 3.10, 3.00, 4.80, 3.00, 3.10, 3.00, 4.80, 3.00, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, 3.80, 3.70, 5.50, 3.70, - 3.20, 5.50, 2.30, 5.50, 2.50, 4.80, 1.60, 4.80, 2.50, 4.80, 1.60, 4.80, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, 3.20, 5.50, 2.30, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 3.60, 3.20, 3.10, 5.50, 2.90, 2.50, 2.40, 4.80, 2.90, 2.50, 2.40, 4.80, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, 3.60, 3.20, 3.10, 5.50, - 3.70, 4.00, 5.50, 3.70, 3.00, 3.30, 4.80, 3.00, 3.00, 3.30, 4.80, 3.00, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, 3.70, 4.00, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.70, 5.50, 2.80, 4.80, 3.00, 4.80, 2.10, 4.80, 3.00, 4.80, 2.10, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, 5.50, 3.70, 5.50, 2.80, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 2.50, 2.10, 1.90, 5.50, 1.80, 1.40, 1.20, 4.80, 1.80, 1.40, 1.20, 4.80, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, 2.50, 2.10, 1.90, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 2.30, 5.50, 3.70, 5.50, 1.60, 4.80, 3.00, 4.80, 1.60, 4.80, 3.00, 4.80, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, 2.30, 5.50, 3.70, 5.50, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 4.00, 3.40, 5.50, 3.70, 3.30, 2.70, 4.80, 3.00, 3.30, 2.70, 4.80, 3.00, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, 4.00, 3.40, 5.50, 3.70, - 5.50, 5.50, 5.50, 5.50, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 4.80, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, 5.50, - 5.50, 3.20, 5.50, 2.70, 4.80, 2.50, 4.80, 2.00, 4.80, 2.50, 4.80, 2.00, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70, 5.50, 3.20, 5.50, 2.70 -}; diff --git a/src/data/interior_loop_1_2_enthalpies.dat b/src/data/interior_loop_1_2_enthalpies.dat deleted file mode 100644 index aad0f09f..00000000 --- a/src/data/interior_loop_1_2_enthalpies.dat +++ /dev/null @@ -1,385 +0,0 @@ -// (1 x 2 interior loop enthalpies) from mfold Version 2.3 (Walter et al.:PNAS1994) -// Data tables for asymmetric interior loops of size 3 -// Enthalpies for RNA -// Data arrangement: -// -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' --> 3' -// (*24) -// X -// (*384)A A(*4) -// U U -// YA -// (*1)(*96) -// 3' <-- 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) . . . . - - -double interior_loop_1_2_enthalpy[]= -{ -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.3,-10.0,-10.0,-10.00,-9.5,-11.2,-11.2,-11.20,-4.00,-5.70,-5.70,-5.70,-8.6,-10.3,-10.3,-10.3,-11.5,-13.2,-13.2,-13.20,-8.60,-10.3,-10.3,-10.30, - -8.9, -8.70,-8.70,-8.7,-11.4,-11.2,-11.2,-11.20, 6.90, 7.10, 7.10, 7.10,-8.60,-8.40,-8.40,-8.4,-10.5,-10.3,-10.3,-10.30,-8.60, -8.40,-8.40,-8.40, --12.3,-15.8,-15.8,-15.80,-9.0,-12.5,-12.5,-12.50, 6.90, 3.40, 3.40, 3.40,-9.4,-12.9,-12.9,-12.9,-13.0,-16.5,-16.5,-16.50,-9.40,-12.9,-12.9,-12.90, - -9.20,-9.20,-9.20,-9.2,-12.1,-12.1,-12.1,-12.1,-13.6,-13.6,-13.6,-13.60,-9.30,-9.30,-9.30,-9.3,-11.4,-11.4,-11.4,-11.40,-9.30, -9.30,-9.30,-9.30, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.6,-10.3,-10.3,-10.3,-11.5,-13.2,-13.2,-13.2, -9.5,-11.2,-11.2,-11.20,-6.90,-8.60,-8.60,-8.60,-9.1,-10.8,-10.8,-10.80,-6.90,-8.60,-8.60,-8.60, - -7.7, -7.50,-7.50,-7.50,-5.70,-5.50,-5.50,-5.50,-7.10,-6.90,-6.90,-6.90,-5.00,-4.80,-4.80,-4.80,-7.40,-7.20,-7.20,-7.20,-5.00,-4.80,-4.80,-4.80, - -5.4, -8.90,-8.90,-8.90,-6.5,-10.0,-10.0,-10.00,-8.6,-12.1,-12.1,-12.10,-5.80,-9.30,-9.30,-9.30,-7.0,-10.5,-10.5,-10.50,-5.80,-9.30,-9.30,-9.30, - -5.1, -5.10,-5.10,-5.10,-7.20,-7.20,-7.20,-7.2,-10.0,-10.0,-10.0,-10.00,-5.70,-5.70,-5.70,-5.70,-8.10,-8.10,-8.10,-8.10,-5.70,-5.70,-5.70,-5.70, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.10,-9.80,-9.80,-9.8,-11.4,-13.1,-13.1,-13.1,-13.7,-15.4,-15.4,-15.40,-7.70,-9.40,-9.40,-9.4,-10.9,-12.6,-12.6,-12.60,-7.70,-9.40,-9.40,-9.40, - -9.40,-9.20,-9.20,-9.2,-10.00,-9.80,-9.80,-9.8,-12.0,-11.8,-11.8,-11.80,-9.50,-9.30,-9.30,-9.3,-10.7,-10.5,-10.5,-10.50,-9.50,-9.30,-9.30,-9.30, --12.3,-15.8,-15.8,-15.80,-9.6,-13.1,-13.1,-13.1,-12.8,-16.3,-16.3,-16.3,-10.3,-13.8,-13.8,-13.8,-12.6,-16.1,-16.1,-16.1,-10.3,-13.8,-13.8,-13.80, --10.1,-10.1,-10.1,-10.1,-10.7,-10.7,-10.7,-10.7,-12.7,-12.7,-12.7,-12.7,-10.2,-10.2,-10.2,-10.2,-11.4,-11.4,-11.4,-11.4,-10.2,-10.2,-10.2,-10.20, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// A A A C A G A U A G A U -// U U U G U C U A U U U G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -7.10,-8.80,-8.80,-8.80,-9.3,-11.0,-11.0,-11.0,-12.4,-14.1,-14.1,-14.10,-7.60,-9.30,-9.30,-9.30,-9.8,-11.5,-11.5,-11.50,-7.60,-9.30,-9.30,-9.30, - -4.00,-3.80,-3.80,-3.80,-7.60,-7.40,-7.40,-7.4,-10.00,-9.80,-9.80,-9.80,-5.90,-5.70,-5.70,-5.70,-7.00,-6.80,-6.80,-6.80,-5.90,-5.70,-5.70,-5.70, - -6.20,-9.70,-9.70,-9.70,-8.4,-11.9,-11.9,-11.9,-11.5,-15.0,-15.0,-15.00,-6.7,-10.2,-10.2,-10.20,-8.9,-12.4,-12.4,-12.40,-6.7,-10.2,-10.2,-10.20, - -4.70,-4.70,-4.70,-4.70,-9.00,-9.00,-9.00,-9.0,-11.9,-11.9,-11.9,-11.90,-6.60,-6.60,-6.60,-6.60,-6.90,-6.90,-6.90,-6.90,-6.60,-6.60,-6.60,-6.60, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -3.70, 5.50, 6.3,-14.30,-4.90, 4.30, 5.1,-15.50, 0.60, 9.80,10.6,-10.00,-4.00, 5.20, 6.0,-14.60,-6.90, 2.30, 3.1,-17.50,-4.00, 5.20, 6.0,-14.60, --11.5,-10.8,-11.5,-13.0,-14.0,-13.3,-14.0,-15.50, 4.30, 5.00, 4.30, 2.8,-11.2,-10.5,-11.2,-12.7,-13.1,-12.4,-13.1,-14.6,-11.2,-10.5,-11.2,-12.70, --18.3,-18.3,-18.3,-18.3,-15.0,-15.0,-15.0,-15.00, 0.90, 0.90, 0.90, 0.9,-15.4,-15.4,-15.4,-15.4,-19.0,-19.0,-19.0,-19.0,-15.4,-15.4,-15.4,-15.40, --14.0,-13.3,-14.0,-14.5,-16.9,-16.2,-16.9,-17.4,-18.4,-17.7,-18.4,-18.9,-14.1,-13.4,-14.1,-14.6,-16.2,-15.5,-16.2,-16.7,-14.1,-13.4,-14.1,-14.60, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -4.00, 5.20, 6.0,-14.60,-6.90, 2.30, 3.1,-17.50,-4.90, 4.30, 5.1,-15.50,-2.30, 6.90, 7.7,-12.90,-4.50, 4.70, 5.5,-15.10,-2.30, 6.90, 7.7,-12.90, --10.30,-9.6,-10.3,-11.80,-8.30,-7.60,-8.30,-9.80,-9.70,-9.00,-9.7,-11.20,-7.60,-6.90,-7.60,-9.1,-10.00,-9.3,-10.0,-11.50,-7.60,-6.90,-7.60,-9.10, --11.4,-11.4,-11.4,-11.4,-12.5,-12.5,-12.5,-12.5,-14.6,-14.6,-14.6,-14.6,-11.8,-11.8,-11.8,-11.8,-13.0,-13.0,-13.0,-13.0,-11.8,-11.8,-11.8,-11.80, - -9.90,-9.20,-9.9,-10.4,-12.0,-11.3,-12.0,-12.5,-14.8,-14.1,-14.8,-15.3,-10.50,-9.8,-10.5,-11.0,-12.9,-12.2,-12.9,-13.4,-10.50,-9.8,-10.5,-11.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -3.50, 5.70, 6.5,-14.10,-6.80, 2.40, 3.2,-17.40,-9.10, 0.10, 0.9,-19.70,-3.10, 6.10, 6.9,-13.70,-6.30, 2.90, 3.7,-16.90,-3.10, 6.10, 6.9,-13.70, --12.0,-11.3,-12.0,-13.5,-12.6,-11.9,-12.6,-14.1,-14.6,-13.9,-14.6,-16.1,-12.1,-11.4,-12.1,-13.6,-13.3,-12.6,-13.3,-14.8,-12.1,-11.4,-12.1,-13.60, --18.3,-18.3,-18.3,-18.3,-15.6,-15.6,-15.6,-15.6,-18.8,-18.8,-18.8,-18.8,-16.3,-16.3,-16.3,-16.3,-18.6,-18.6,-18.6,-18.6,-16.3,-16.3,-16.3,-16.30, --14.9,-14.2,-14.9,-15.4,-15.5,-14.8,-15.5,-16.0,-17.5,-16.8,-17.5,-18.0,-15.0,-14.3,-15.0,-15.5,-16.2,-15.5,-16.2,-16.7,-15.0,-14.3,-15.0,-15.50, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// C A C C C G C U C G C U -// G U G G G C G A G U G G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -2.50, 6.70, 7.5,-13.10,-4.70, 4.50, 5.3,-15.30,-7.80, 1.40, 2.2,-18.40,-3.00, 6.20, 7.0,-13.60,-5.20, 4.00, 4.8,-15.80,-3.00, 6.20, 7.0,-13.60, - -6.60,-5.90,-6.60,-8.1,-10.20,-9.5,-10.2,-11.7,-12.6,-11.9,-12.6,-14.10,-8.50,-7.80,-8.5,-10.00,-9.60,-8.90,-9.6,-11.10,-8.50,-7.80,-8.5,-10.00, --12.2,-12.2,-12.2,-12.2,-14.4,-14.4,-14.4,-14.4,-17.5,-17.5,-17.5,-17.5,-12.7,-12.7,-12.7,-12.7,-14.9,-14.9,-14.9,-14.9,-12.7,-12.7,-12.7,-12.70, - -9.50,-8.80,-9.5,-10.0,-13.8,-13.1,-13.8,-14.3,-16.7,-16.0,-16.7,-17.2,-11.4,-10.7,-11.4,-11.9,-11.7,-11.0,-11.7,-12.2,-11.4,-10.7,-11.4,-11.90, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -9.2,-12.80,-9.6,-12.8,-10.4,-14.0,-10.8,-14.00,-4.90,-8.50,-5.30,-8.50,-9.5,-13.10,-9.9,-13.1,-12.4,-16.0,-12.8,-16.00,-9.5,-13.10,-9.9,-13.10, --13.50,-9.40,-9.4,-10.2,-16.0,-11.9,-11.9,-12.70, 2.30, 6.40, 6.40, 5.6,-13.20,-9.10,-9.10,-9.9,-15.1,-11.0,-11.0,-11.8,-13.20,-9.10,-9.10,-9.90, --16.0,-16.3,-15.1,-16.3,-12.7,-13.0,-11.8,-13.00, 3.20, 2.90, 4.10, 2.9,-13.1,-13.4,-12.2,-13.4,-16.7,-17.0,-15.8,-17.0,-13.1,-13.4,-12.2,-13.40, --10.9,-10.9,-10.9,-11.6,-13.8,-13.8,-13.8,-14.5,-15.3,-15.3,-15.3,-16.0,-11.0,-11.0,-11.0,-11.7,-13.1,-13.1,-13.1,-13.8,-11.0,-11.0,-11.0,-11.70, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -9.5,-13.10,-9.9,-13.1,-12.4,-16.0,-12.8,-16.0,-10.4,-14.0,-10.8,-14.00,-7.8,-11.40,-8.2,-11.4,-10.0,-13.6,-10.4,-13.60,-7.8,-11.40,-8.2,-11.40, --12.30,-8.20,-8.20,-9.0,-10.30,-6.20,-6.20,-7.0,-11.70,-7.60,-7.60,-8.40,-9.60,-5.50,-5.50,-6.3,-12.00,-7.90,-7.90,-8.70,-9.60,-5.50,-5.50,-6.30, - -9.10,-9.40,-8.20,-9.4,-10.2,-10.50,-9.3,-10.5,-12.3,-12.6,-11.4,-12.60,-9.50,-9.80,-8.60,-9.8,-10.7,-11.00,-9.8,-11.00,-9.50,-9.80,-8.60,-9.80, - -6.80,-6.80,-6.80,-7.50,-8.90,-8.90,-8.90,-9.6,-11.7,-11.7,-11.7,-12.40,-7.40,-7.40,-7.40,-8.10,-9.80,-9.80,-9.8,-10.50,-7.40,-7.40,-7.40,-8.10, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -9.0,-12.60,-9.4,-12.6,-12.3,-15.9,-12.7,-15.9,-14.6,-18.2,-15.0,-18.20,-8.6,-12.20,-9.0,-12.2,-11.8,-15.4,-12.2,-15.40,-8.6,-12.20,-9.0,-12.20, --14.00,-9.90,-9.9,-10.7,-14.6,-10.5,-10.5,-11.3,-16.6,-12.5,-12.5,-13.3,-14.1,-10.0,-10.0,-10.8,-15.3,-11.2,-11.2,-12.0,-14.1,-10.0,-10.0,-10.80, --16.0,-16.3,-15.1,-16.3,-13.3,-13.6,-12.4,-13.6,-16.5,-16.8,-15.6,-16.8,-14.0,-14.3,-13.1,-14.3,-16.3,-16.6,-15.4,-16.6,-14.0,-14.3,-13.1,-14.30, --11.8,-11.8,-11.8,-12.5,-12.4,-12.4,-12.4,-13.1,-14.4,-14.4,-14.4,-15.1,-11.9,-11.9,-11.9,-12.6,-13.1,-13.1,-13.1,-13.8,-11.9,-11.9,-11.9,-12.60, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// C U C G C C C A C U C G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.0,-11.60,-8.4,-11.6,-10.2,-13.8,-10.6,-13.8,-13.3,-16.9,-13.7,-16.90,-8.5,-12.10,-8.9,-12.1,-10.7,-14.3,-11.1,-14.30,-8.5,-12.10,-8.9,-12.10, - -8.60,-4.50,-4.50,-5.3,-12.20,-8.10,-8.10,-8.9,-14.6,-10.5,-10.5,-11.3,-10.50,-6.40,-6.40,-7.2,-11.60,-7.50,-7.50,-8.3,-10.50,-6.40,-6.40,-7.20, - -9.9,-10.20,-9.0,-10.2,-12.1,-12.4,-11.2,-12.4,-15.2,-15.5,-14.3,-15.5,-10.4,-10.70,-9.5,-10.7,-12.6,-12.9,-11.7,-12.9,-10.4,-10.70,-9.5,-10.70, - -6.40,-6.40,-6.40,-7.1,-10.7,-10.7,-10.7,-11.4,-13.6,-13.6,-13.6,-14.30,-8.30,-8.30,-8.30,-9.00,-8.60,-8.60,-8.60,-9.30,-8.30,-8.30,-8.30,-9.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.0,-10.3,-12.90,-9.90,-9.2,-11.5,-14.1,-11.10,-3.70,-6.00,-8.60,-5.60,-8.3,-10.6,-13.2,-10.2,-11.2,-13.5,-16.1,-13.10,-8.3,-10.6,-13.2,-10.20, --10.6,-11.40,-8.30,-8.1,-13.1,-13.9,-10.8,-10.60, 5.20, 4.40, 7.50, 7.7,-10.3,-11.10,-8.00,-7.8,-12.2,-13.00,-9.90,-9.7,-10.3,-11.10,-8.00,-7.80, --12.7,-15.7,-17.8,-15.70,-9.4,-12.4,-14.5,-12.40, 6.50, 3.50, 1.40, 3.50,-9.8,-12.8,-14.9,-12.8,-13.4,-16.4,-18.5,-16.40,-9.8,-12.8,-14.9,-12.80, - -8.70,-7.30,-8.70,-7.3,-11.6,-10.2,-11.6,-10.2,-13.1,-11.7,-13.1,-11.70,-8.80,-7.40,-8.80,-7.4,-10.90,-9.5,-10.90,-9.50,-8.80,-7.40,-8.80,-7.40, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.3,-10.6,-13.2,-10.2,-11.2,-13.5,-16.1,-13.10,-9.2,-11.5,-14.1,-11.10,-6.60,-8.9,-11.50,-8.50,-8.8,-11.1,-13.7,-10.70,-6.60,-8.9,-11.50,-8.50, - -9.4,-10.20,-7.10,-6.90,-7.40,-8.20,-5.10,-4.90,-8.80,-9.60,-6.50,-6.30,-6.70,-7.50,-4.40,-4.20,-9.10,-9.90,-6.80,-6.60,-6.70,-7.50,-4.40,-4.20, - -5.80,-8.8,-10.90,-8.80,-6.90,-9.9,-12.00,-9.90,-9.0,-12.0,-14.1,-12.00,-6.20,-9.2,-11.30,-9.20,-7.4,-10.4,-12.5,-10.40,-6.20,-9.2,-11.30,-9.20, - -4.60,-3.20,-4.60,-3.20,-6.70,-5.30,-6.70,-5.30,-9.50,-8.10,-9.50,-8.10,-5.20,-3.80,-5.20,-3.80,-7.60,-6.20,-7.60,-6.20,-5.20,-3.80,-5.20,-3.80, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -7.8,-10.1,-12.70,-9.7,-11.1,-13.4,-16.0,-13.0,-13.4,-15.7,-18.3,-15.30,-7.40,-9.7,-12.30,-9.3,-10.6,-12.9,-15.5,-12.50,-7.40,-9.7,-12.30,-9.30, --11.1,-11.90,-8.80,-8.6,-11.7,-12.50,-9.40,-9.2,-13.7,-14.5,-11.4,-11.2,-11.2,-12.00,-8.90,-8.7,-12.4,-13.2,-10.10,-9.9,-11.2,-12.00,-8.90,-8.70, --12.7,-15.7,-17.8,-15.7,-10.0,-13.0,-15.1,-13.0,-13.2,-16.2,-18.3,-16.2,-10.7,-13.7,-15.8,-13.7,-13.0,-16.0,-18.1,-16.0,-10.7,-13.7,-15.8,-13.70, - -9.60,-8.20,-9.60,-8.2,-10.20,-8.8,-10.20,-8.8,-12.2,-10.8,-12.2,-10.80,-9.70,-8.30,-9.70,-8.3,-10.90,-9.5,-10.90,-9.50,-9.70,-8.30,-9.70,-8.30, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// A U A G A C A A A U A G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -6.80,-9.1,-11.70,-8.70,-9.0,-11.3,-13.9,-10.9,-12.1,-14.4,-17.0,-14.00,-7.30,-9.6,-12.20,-9.20,-9.5,-11.8,-14.4,-11.40,-7.30,-9.6,-12.20,-9.20, - -5.70,-6.50,-3.40,-3.20,-9.3,-10.10,-7.00,-6.8,-11.7,-12.50,-9.40,-9.20,-7.60,-8.40,-5.30,-5.10,-8.70,-9.50,-6.40,-6.20,-7.60,-8.40,-5.30,-5.10, - -6.60,-9.6,-11.70,-9.60,-8.8,-11.8,-13.9,-11.8,-11.9,-14.9,-17.0,-14.90,-7.1,-10.1,-12.2,-10.10,-9.3,-12.3,-14.4,-12.30,-7.1,-10.1,-12.2,-10.10, - -4.20,-2.80,-4.20,-2.80,-8.50,-7.10,-8.50,-7.1,-11.4,-10.0,-11.4,-10.00,-6.10,-4.70,-6.10,-4.70,-6.40,-5.00,-6.40,-5.00,-6.10,-4.70,-6.10,-4.70, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.3,-10.0,-10.0,-10.00,-9.5,-11.2,-11.2,-11.20,-4.00,-5.70,-5.70,-5.70,-8.6,-10.3,-10.3,-10.3,-11.5,-13.2,-13.2,-13.20,-8.6,-10.3,-10.3,-10.30, - -8.90,-8.70,-8.70,-8.7,-11.4,-11.2,-11.2,-11.20, 6.90, 7.10, 7.10, 7.10,-8.60,-8.40,-8.40,-8.4,-10.5,-10.3,-10.3,-10.30,-8.60,-8.40,-8.40,-8.40, --12.3,-15.8,-15.8,-15.80,-9.0,-12.5,-12.5,-12.50, 6.90, 3.40, 3.40, 3.40,-9.4,-12.9,-12.9,-12.9,-13.0,-16.5,-16.5,-16.50,-9.4,-12.9,-12.9,-12.90, - -9.20,-9.20,-9.20,-9.2,-12.1,-12.1,-12.1,-12.1,-13.6,-13.6,-13.6,-13.60,-9.30,-9.30,-9.30,-9.3,-11.4,-11.4,-11.4,-11.40,-9.30,-9.30,-9.30,-9.30, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.6,-10.3,-10.3,-10.3,-11.5,-13.2,-13.2,-13.20,-9.5,-11.2,-11.2,-11.20,-6.90,-8.60,-8.60,-8.60,-9.1,-10.8,-10.8,-10.80,-6.90,-8.60,-8.60,-8.60, - -7.70,-7.50,-7.50,-7.50,-5.70,-5.50,-5.50,-5.50,-7.10,-6.90,-6.90,-6.90,-5.00,-4.80,-4.80,-4.80,-7.40,-7.20,-7.20,-7.20,-5.00,-4.80,-4.80,-4.80, - -5.40,-8.90,-8.90,-8.90,-6.5,-10.0,-10.0,-10.00,-8.6,-12.1,-12.1,-12.10,-5.80,-9.30,-9.30,-9.30,-7.0,-10.5,-10.5,-10.50,-5.80,-9.30,-9.30,-9.30, - -5.10,-5.10,-5.10,-5.10,-7.20,-7.20,-7.20,-7.2,-10.0,-10.0,-10.0,-10.00,-5.70,-5.70,-5.70,-5.70,-8.10,-8.10,-8.10,-8.10,-5.70,-5.70,-5.70,-5.70, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -8.10,-9.80,-9.80,-9.8,-11.4,-13.1,-13.1,-13.1,-13.7,-15.4,-15.4,-15.40,-7.70,-9.40,-9.40,-9.4,-10.9,-12.6,-12.6,-12.60,-7.70,-9.40,-9.40,-9.40, - -9.40,-9.20,-9.20,-9.2,-10.00,-9.80,-9.80,-9.8,-12.0,-11.8,-11.8,-11.80,-9.50,-9.30,-9.30,-9.3,-10.7,-10.5,-10.5,-10.50,-9.50,-9.30,-9.30,-9.30, --12.3,-15.8,-15.8,-15.80,-9.6,-13.1,-13.1,-13.1,-12.8,-16.3,-16.3,-16.3,-10.3,-13.8,-13.8,-13.8,-12.6,-16.1,-16.1,-16.1,-10.3,-13.8,-13.8,-13.80, --10.1,-10.1,-10.1,-10.1,-10.7,-10.7,-10.7,-10.7,-12.7,-12.7,-12.7,-12.7,-10.2,-10.2,-10.2,-10.2,-11.4,-11.4,-11.4,-11.4,-10.2,-10.2,-10.2,-10.20, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// G A G C G G G U G G G U -// U U U G U C U A U U U G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -7.10,-8.80,-8.80,-8.80,-9.3,-11.0,-11.0,-11.0,-12.4,-14.1,-14.1,-14.10,-7.60,-9.30,-9.30,-9.30,-9.8,-11.5,-11.5,-11.50,-7.60,-9.30,-9.30,-9.30, - -4.00,-3.80,-3.80,-3.80,-7.60,-7.40,-7.40,-7.4,-10.00,-9.80,-9.80,-9.80,-5.90,-5.70,-5.70,-5.70,-7.00,-6.80,-6.80,-6.80,-5.90,-5.70,-5.70,-5.70, - -6.20,-9.70,-9.70,-9.70,-8.4,-11.9,-11.9,-11.9,-11.5,-15.0,-15.0,-15.00,-6.7,-10.2,-10.2,-10.20,-8.9,-12.4,-12.4,-12.40,-6.7,-10.2,-10.2,-10.20, - -4.70,-4.70,-4.70,-4.70,-9.00,-9.00,-9.00,-9.0,-11.9,-11.9,-11.9,-11.90,-6.60,-6.60,-6.60,-6.60,-6.90,-6.90,-6.90,-6.90,-6.60,-6.60,-6.60,-6.60, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YA YA YA YA YA YA -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' --11.2,-11.9,-13.6,-12.1,-12.4,-13.1,-14.8,-13.30,-6.90,-7.60,-9.30,-7.8,-11.5,-12.2,-13.9,-12.4,-14.4,-15.1,-16.8,-15.3,-11.5,-12.2,-13.9,-12.40, --11.1,-11.10,-9.9,-11.1,-13.6,-13.6,-12.4,-13.60, 4.70, 4.70, 5.90, 4.7,-10.8,-10.80,-9.6,-10.8,-12.7,-12.7,-11.5,-12.7,-10.8,-10.80,-9.6,-10.80, --15.5,-17.0,-18.1,-17.0,-12.2,-13.7,-14.8,-13.70, 3.70, 2.20, 1.10, 2.2,-12.6,-14.1,-15.2,-14.1,-16.2,-17.7,-18.8,-17.7,-12.6,-14.1,-15.2,-14.10, --11.4,-10.3,-11.40,-9.5,-14.3,-13.2,-14.3,-12.4,-15.8,-14.7,-15.8,-13.9,-11.5,-10.4,-11.50,-9.6,-13.6,-12.5,-13.6,-11.7,-11.5,-10.4,-11.50,-9.60, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YC YC YC YC YC YC -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' --11.5,-12.2,-13.9,-12.4,-14.4,-15.1,-16.8,-15.3,-12.4,-13.1,-14.8,-13.30,-9.8,-10.5,-12.2,-10.7,-12.0,-12.7,-14.4,-12.90,-9.8,-10.5,-12.2,-10.70, - -9.90,-9.90,-8.70,-9.90,-7.90,-7.90,-6.70,-7.90,-9.30,-9.30,-8.10,-9.30,-7.20,-7.20,-6.00,-7.20,-9.60,-9.60,-8.40,-9.60,-7.20,-7.20,-6.00,-7.20, - -8.6,-10.1,-11.2,-10.10,-9.7,-11.2,-12.3,-11.2,-11.8,-13.3,-14.4,-13.30,-9.0,-10.5,-11.6,-10.5,-10.2,-11.7,-12.8,-11.70,-9.0,-10.5,-11.6,-10.50, - -7.30,-6.20,-7.30,-5.40,-9.40,-8.30,-9.40,-7.5,-12.2,-11.1,-12.2,-10.30,-7.90,-6.80,-7.90,-6.0,-10.30,-9.2,-10.30,-8.40,-7.90,-6.80,-7.90,-6.00, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YG YG YG YG YG YG -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' --11.0,-11.7,-13.4,-11.9,-14.3,-15.0,-16.7,-15.2,-16.6,-17.3,-19.0,-17.5,-10.6,-11.3,-13.0,-11.5,-13.8,-14.5,-16.2,-14.7,-10.6,-11.3,-13.0,-11.50, --11.6,-11.6,-10.4,-11.6,-12.2,-12.2,-11.0,-12.2,-14.2,-14.2,-13.0,-14.2,-11.7,-11.7,-10.5,-11.7,-12.9,-12.9,-11.7,-12.9,-11.7,-11.7,-10.5,-11.70, --15.5,-17.0,-18.1,-17.0,-12.8,-14.3,-15.4,-14.3,-16.0,-17.5,-18.6,-17.5,-13.5,-15.0,-16.1,-15.0,-15.8,-17.3,-18.4,-17.3,-13.5,-15.0,-16.1,-15.00, --12.3,-11.2,-12.3,-10.4,-12.9,-11.8,-12.9,-11.0,-14.9,-13.8,-14.9,-13.0,-12.4,-11.3,-12.4,-10.5,-13.6,-12.5,-13.6,-11.7,-12.4,-11.3,-12.4,-10.50, -// -// Y Y Y Y Y Y -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// X X X X X X -// U A U C U G U U U G U U -// G U G G G C G A G U G G -// YU YU YU YU YU YU -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' --10.0,-10.7,-12.4,-10.9,-12.2,-12.9,-14.6,-13.1,-15.3,-16.0,-17.7,-16.2,-10.5,-11.2,-12.9,-11.4,-12.7,-13.4,-15.1,-13.6,-10.5,-11.2,-12.9,-11.40, - -6.20,-6.20,-5.00,-6.20,-9.80,-9.80,-8.60,-9.8,-12.2,-12.2,-11.0,-12.20,-8.10,-8.10,-6.90,-8.10,-9.20,-9.20,-8.00,-9.20,-8.10,-8.10,-6.90,-8.10, - -9.4,-10.9,-12.0,-10.9,-11.6,-13.1,-14.2,-13.1,-14.7,-16.2,-17.3,-16.20,-9.9,-11.4,-12.5,-11.4,-12.1,-13.6,-14.7,-13.60,-9.9,-11.4,-12.5,-11.40, - -6.90,-5.80,-6.90,-5.0,-11.2,-10.1,-11.20,-9.3,-14.1,-13.0,-14.1,-12.20,-8.80,-7.70,-8.80,-6.90,-9.10,-8.00,-9.10,-7.20,-8.80,-7.70,-8.80,-6.90 -}; diff --git a/src/data/interior_loop_2_2_energies.dat b/src/data/interior_loop_2_2_energies.dat deleted file mode 100644 index f94b3cfc..00000000 --- a/src/data/interior_loop_2_2_energies.dat +++ /dev/null @@ -1,973 +0,0 @@ -// Tandem mismatch energies (2 x 2 interior loops) from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// Data tables for symetric interior loops of size 4 -// Free energies at 37 degrees for RNA -// Data arrangement: -// -// Y -// ---------------------------------------------------------------- -// (X) A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// ---------------------------------------------------------------- -// 5' ------> 3' -// (*64)(*4) -// (*1536)A \/ \_/ A(*256) -// U /\ | U -// (*16)(*1) -// 3' <------ 5' -// -// (AA) . . . . . . . . . . . . . . . . -// (AC) . . . . . . . . . . . . . . . . -// (AG) . . . . . . . . . . . . . . . . -// (AU) . . . . . . . . . . . . . . . . -// (CA) . . . . . . . . . . . . . . . . -// (CC) . . . . . . . . . . . . . . . . -// (CG) . . . . . . . . . . . . . . . . -// (CU) . . . . . . . . . . . . . . . . -// (GA) . . . . . . . . . . . . . . . . -// (GC) . . . . . . . . . . . . . . . . -// (GG) . . . . . . . . . . . . . . . . -// (GU) . . . . . . . . . . . . . . . . -// (UA) . . . . . . . . . . . . . . . . -// (UC) . . . . . . . . . . . . . . . . -// (UG) . . . . . . . . . . . . . . . . -// (UU) . . . . . . . . . . . . . . . . - -double interior_loop_2_2_energy[]= -{ - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ A -// U /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.60, 2.20, 1.60, 2.00, 2.60, 2.60, 2.00, 2.60, 1.60, 2.00, 2.00,-0.20, 2.00, 2.30, 1.10, 1.80, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.10, 1.50, 2.00, 2.50, 2.50, 2.00, 2.50, 1.50, 2.00, 1.90,-0.30, 2.00, 2.20, 1.00, 1.70, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.60, 1.00, 2.00, 2.10, 2.70, 2.00, 2.70, 1.00, 2.00, 1.40, 0.30, 2.00, 2.40, 1.50, 2.20, - 2.30, 0.90, 2.10, 2.00, 1.30, 2.30, 2.00, 2.30, 2.10, 2.00, 1.70,-1.50, 2.00, 2.00,-0.20, 2.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.30,-0.10, 1.10, 2.00, 0.30, 1.30, 2.00, 1.30, 1.10, 2.00, 0.70,-2.50, 2.00, 1.00,-1.20, 1.30, - 2.70, 1.20, 2.40, 2.00, 1.70, 1.70, 2.00, 1.70, 2.40, 2.00, 2.00, 0.70, 2.00, 1.40, 1.90, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ C -// U /\ | G -// 3' <------ 5' - 2.10, 1.90, 0.10, 2.00, 1.80, 2.50, 2.00, 1.50, 0.70, 2.00, 1.80, 0.00, 2.00, 2.50, 0.40, 2.10, - 2.00, 1.70, 0.00, 2.00, 1.70, 1.70, 2.00, 0.70, 0.60, 2.00, 1.60,-1.20, 2.00, 1.80,-0.80, 1.00, - 0.90, 0.60,-1.10, 2.00, 0.60, 1.60, 2.00, 0.70,-0.50, 2.00, 0.50,-0.50, 2.00, 1.70,-0.10, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.60,-0.10, 2.00, 1.60, 1.60, 2.00, 0.60, 0.50, 2.00, 1.50,-1.30, 2.00, 1.70,-0.90, 0.90, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 0.90, 0.60,-1.10, 2.00, 0.60, 1.60, 2.00, 0.70,-0.50, 2.00, 0.50,-0.50, 2.00, 1.70,-0.10, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.40, 1.20,-0.60, 2.00, 1.10, 1.80, 2.00, 0.80, 0.00, 2.00, 1.10,-0.70, 2.00, 1.80,-0.30, 1.40, - 1.70, 0.40, 0.50, 2.00, 0.40, 1.40, 2.00, 0.50, 1.10, 2.00, 1.30,-2.50, 2.00, 1.50,-2.10, 1.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 0.70,-0.50,-0.50, 2.00,-0.60, 0.50, 2.00,-0.50, 0.10, 2.00, 0.40,-3.50, 2.00, 0.50,-3.10, 0.50, - 2.00, 0.80, 0.80, 2.00, 0.70, 0.80, 2.00,-0.20, 1.50, 2.00, 1.70,-0.30, 2.00, 0.80, 0.10, 0.00, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ G -// U /\ | C -// 3' <------ 5' - 2.00, 1.90, 1.00, 2.00, 2.40, 2.80, 2.00, 2.70, 1.00, 2.00, 1.80, 0.30, 2.00, 2.70, 1.80, 2.20, - 1.90, 1.80, 0.90, 2.00, 2.20, 2.10, 2.00, 1.90, 0.90, 2.00, 1.60,-0.80, 2.00, 1.90, 0.70, 1.00, - 0.80, 0.70,-0.20, 2.00, 1.10, 2.00, 2.00, 1.80,-0.20, 2.00, 0.50,-0.10, 2.00, 1.80, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.70, 0.80, 2.00, 2.10, 2.00, 2.00, 1.80, 0.80, 2.00, 1.50,-0.90, 2.00, 1.80, 0.60, 0.90, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 0.80, 0.70,-0.20, 2.00, 1.10, 2.00, 2.00, 1.80,-0.20, 2.00, 0.50,-0.10, 2.00, 1.80, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.30, 1.20, 0.30, 2.00, 1.70, 2.10, 2.00, 2.00, 0.30, 2.00, 1.10,-0.40, 2.00, 2.00, 1.10, 1.50, - 1.60, 0.50, 1.40, 2.00, 0.90, 1.80, 2.00, 1.60, 1.40, 2.00, 1.30,-2.10, 2.00, 1.60,-0.60, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 0.60,-0.50, 0.40, 2.00, 0.00, 0.80, 2.00, 0.70, 0.40, 2.00, 0.40,-3.10, 2.00, 0.70,-1.60, 0.60, - 1.90, 0.80, 1.80, 2.00, 1.30, 1.10, 2.00, 1.00, 1.80, 2.00, 1.70, 0.00, 2.00, 1.00, 1.60, 0.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ U -// U /\ | A -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.60, 2.40, 1.40, 2.00, 2.50, 2.30, 2.00, 2.30, 1.40, 2.00, 1.90, 0.20, 2.00, 2.30, 1.20, 1.50, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.30, 1.30, 2.00, 2.40, 2.20, 2.00, 2.20, 1.30, 2.00, 1.80, 0.10, 2.00, 2.20, 1.10, 1.40, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.80, 0.80, 2.00, 1.90, 2.40, 2.00, 2.40, 0.80, 2.00, 1.40, 0.70, 2.00, 2.40, 1.60, 2.00, - 2.30, 1.10, 1.90, 2.00, 1.20, 2.00, 2.00, 2.00, 1.90, 2.00, 1.60,-1.10, 2.00, 2.00,-0.10, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.30, 0.10, 0.90, 2.00, 0.20, 1.00, 2.00, 1.00, 0.90, 2.00, 0.70,-2.10, 2.00, 1.00,-1.10, 1.10, - 2.70, 1.40, 2.20, 2.00, 1.50, 1.40, 2.00, 1.40, 2.20, 2.00, 2.00, 1.10, 2.00, 1.40, 2.00, 0.60, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ G -// U /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.60, 2.20, 1.60, 2.00, 2.60, 2.60, 2.00, 2.60, 1.60, 2.00, 2.00,-0.20, 2.00, 2.30, 1.10, 1.80, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.10, 1.50, 2.00, 2.50, 2.50, 2.00, 2.50, 1.50, 2.00, 1.90,-0.30, 2.00, 2.20, 1.00, 1.70, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.60, 1.00, 2.00, 2.10, 2.70, 2.00, 2.70, 1.00, 2.00, 1.40, 0.30, 2.00, 2.40, 1.50, 2.20, - 2.30, 0.90, 2.10, 2.00, 1.30, 2.30, 2.00, 2.30, 2.10, 2.00, 1.70,-1.50, 2.00, 2.00,-0.20, 2.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.30,-0.10, 1.10, 2.00, 0.30, 1.30, 2.00, 1.30, 1.10, 2.00, 0.70,-2.50, 2.00, 1.00,-1.20, 1.30, - 2.70, 1.20, 2.40, 2.00, 1.70, 1.70, 2.00, 1.70, 2.40, 2.00, 2.00, 0.70, 2.00, 1.40, 1.90, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ U -// U /\ | G -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.60, 2.40, 1.40, 2.00, 2.50, 2.30, 2.00, 2.30, 1.40, 2.00, 1.90, 0.20, 2.00, 2.30, 1.20, 1.50, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.30, 1.30, 2.00, 2.40, 2.20, 2.00, 2.20, 1.30, 2.00, 1.80, 0.10, 2.00, 2.20, 1.10, 1.40, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.80, 0.80, 2.00, 1.90, 2.40, 2.00, 2.40, 0.80, 2.00, 1.40, 0.70, 2.00, 2.40, 1.60, 2.00, - 2.30, 1.10, 1.90, 2.00, 1.20, 2.00, 2.00, 2.00, 1.90, 2.00, 1.60,-1.10, 2.00, 2.00,-0.10, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.30, 0.10, 0.90, 2.00, 0.20, 1.00, 2.00, 1.00, 0.90, 2.00, 0.70,-2.10, 2.00, 1.00,-1.10, 1.10, - 2.70, 1.40, 2.20, 2.00, 1.50, 1.40, 2.00, 1.40, 2.20, 2.00, 2.00, 1.10, 2.00, 1.40, 2.00, 0.60, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ A -// G /\ | U -// 3' <------ 5' - 2.00, 1.60, 1.00, 2.00, 2.00, 2.60, 2.00, 2.60, 1.00, 2.00, 1.40, 0.20, 2.00, 2.30, 1.50, 2.20, - 2.40, 1.90, 1.30, 2.00, 2.40, 2.40, 2.00, 2.40, 1.30, 2.00, 1.70,-0.40, 2.00, 2.10, 0.80, 1.50, - 1.00, 0.60, 0.00, 2.00, 1.00, 2.00, 2.00, 2.00, 0.00, 2.00, 0.40, 0.00, 2.00, 1.70, 1.30, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.50, 0.90, 2.00, 1.90, 1.90, 2.00, 1.90, 0.90, 2.00, 1.30,-0.90, 2.00, 1.60, 0.40, 1.10, - 2.80, 1.80, 2.20, 2.00, 2.20, 2.20, 2.00, 2.20, 2.20, 2.00, 2.20, 0.40, 2.00, 1.90, 1.70, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.60, 2.00, 2.00, 2.10, 2.10, 2.00, 2.10, 2.00, 2.00, 2.00, 0.30, 2.00, 1.80, 1.50, 1.20, - 1.00, 0.60, 0.00, 2.00, 1.00, 2.00, 2.00, 2.00, 0.00, 2.00, 0.40, 0.00, 2.00, 1.70, 1.30, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.30, 0.70, 2.00, 1.80, 2.40, 2.00, 2.40, 0.70, 2.00, 1.10, 0.00, 2.00, 2.10, 1.20, 1.90, - 1.80, 0.40, 1.60, 2.00, 0.80, 1.80, 2.00, 1.80, 1.60, 2.00, 1.20,-2.00, 2.00, 1.50,-0.70, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.60, 2.00, 2.00, 2.10, 2.10, 2.00, 2.10, 2.00, 2.00, 2.00, 0.30, 2.00, 1.80, 1.50, 1.20, - 0.30,-1.10, 0.10, 2.00,-0.70, 0.30, 2.00, 0.30, 0.10, 2.00,-0.30,-3.50, 2.00, 0.00,-2.20, 0.30, - 2.20, 0.70, 1.90, 2.00, 1.20, 1.20, 2.00, 1.20, 1.90, 2.00, 1.50, 0.20, 2.00, 0.90, 1.50, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ C -// G /\ | G -// 3' <------ 5' - 0.50, 1.10,-0.30, 2.00, 1.10, 1.70, 2.00, 0.70, 0.40, 2.00, 1.00, 0.10, 2.00, 1.80,-0.50, 1.50, - 0.60, 1.50, 0.10, 2.00, 1.10, 1.50, 2.00, 0.50, 0.50, 2.00, 1.40,-0.70, 2.00, 1.50,-0.60, 0.00, - 0.00,-0.70,-1.60, 2.00,-1.00,-0.60, 2.00, 0.20,-0.70, 2.00, 0.00,-0.80, 2.00, 1.20,-0.60, 0.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.30, 1.00,-0.70, 2.00, 1.00, 1.00, 2.00, 0.00, 0.70, 2.00, 0.90,-1.90, 2.00, 1.10,-1.50,-0.20, - 2.20, 1.30, 0.70, 2.00, 1.90, 1.30, 2.00, 0.30, 0.70, 2.00, 1.80,-0.30, 2.00, 1.40,-0.20,-0.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.00, 1.20, 0.40, 2.00, 1.10, 1.20, 2.00, 1.70, 1.00, 2.00, 1.70,-0.70, 2.00, 1.20,-0.30, 0.20, - -0.20,-0.40,-1.70, 2.00, 0.70, 1.10, 2.00, 0.20,-0.50, 2.00, 0.00,-0.90, 2.00, 1.20,-1.30, 0.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.10, 0.90,-0.90, 2.00, 0.80, 1.50, 2.00, 0.50,-0.20, 2.00, 0.80,-1.00, 2.00, 1.50,-0.60, 1.10, - 0.90, 0.00, 0.30, 2.00,-0.10, 1.00, 2.00, 0.00, 0.60, 2.00, 0.90,-3.00, 2.00, 1.00,-2.40, 0.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.00, 1.20, 0.40, 2.00, 1.10, 1.20, 2.00, 0.20, 0.50, 2.00, 1.70,-0.70, 2.00, 1.20,-0.10, 0.40, - -0.10,-1.60,-1.60, 2.00,-1.60,-0.60, 2.00,-1.60,-0.60, 2.00,-0.70,-4.40, 2.00,-0.50,-4.10,-1.00, - 1.40, 0.30, 0.50, 2.00, 0.30, 0.30, 2.00, 0.10, 1.40, 2.00, 1.20,-1.00, 2.00, 0.30, 0.10, 0.60, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ G -// G /\ | C -// 3' <------ 5' - 1.30, 1.20, 0.30, 2.00, 1.60, 2.10, 2.00, 1.90, 0.30, 2.00, 1.00,-0.40, 2.00, 1.90, 1.10, 1.40, - 1.60, 1.50, 0.60, 2.00, 2.00, 1.80, 2.00, 1.70, 0.60, 2.00, 1.40,-1.10, 2.00, 1.70, 0.40, 0.80, - 0.30, 0.20,-0.70, 2.00, 0.60, 1.50, 2.00, 1.30,-0.70, 2.00, 0.00,-0.60, 2.00, 1.30, 0.90, 1.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.20, 1.10, 0.20, 2.00, 1.50, 1.40, 2.00, 1.20, 0.20, 2.00, 0.90,-1.50, 2.00, 1.20, 0.00, 0.30, - 2.10, 1.40, 1.50, 2.00, 1.80, 1.70, 2.00, 1.50, 1.50, 2.00, 1.80,-0.20, 2.00, 1.50, 1.30, 0.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.20, 1.30, 2.00, 1.70, 1.50, 2.00, 1.40, 1.30, 2.00, 1.70,-0.40, 2.00, 1.40, 1.10, 0.50, - 0.30, 0.20,-0.70, 2.00, 0.60, 1.50, 2.00, 1.30,-0.70, 2.00, 0.00,-0.60, 2.00, 1.30, 0.90, 1.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.00, 0.90, 0.00, 2.00, 1.40, 1.80, 2.00, 1.70, 0.00, 2.00, 0.80,-0.70, 2.00, 1.70, 0.90, 1.20, - 1.10, 0.00, 0.90, 2.00, 0.40, 1.30, 2.00, 1.10, 0.90, 2.00, 0.90,-2.60, 2.00, 1.10,-1.10, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.20, 1.30, 2.00, 1.70, 1.50, 2.00, 1.40, 1.30, 2.00, 1.70,-0.40, 2.00, 1.40, 1.10, 0.50, - -0.40,-1.50,-0.60, 2.00,-1.10,-0.20, 2.00,-0.40,-0.60, 2.00,-0.70,-4.20, 2.00,-0.40,-2.60,-0.50, - 1.40, 0.30, 1.30, 2.00, 0.80, 0.60, 2.00, 0.50, 1.30, 2.00, 1.20,-0.50, 2.00, 0.50, 1.10,-0.40, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ U -// G /\ | A -// 3' <------ 5' - 2.00, 1.80, 0.80, 2.00, 1.90, 2.30, 2.00, 2.30, 0.80, 2.00, 1.30, 0.60, 2.00, 2.30, 1.60, 1.90, - 2.40, 2.10, 1.10, 2.00, 2.20, 2.10, 2.00, 2.10, 1.10, 2.00, 1.70, 0.00, 2.00, 2.10, 0.90, 1.30, - 1.00, 0.80,-0.20, 2.00, 0.90, 1.70, 2.00, 1.70,-0.20, 2.00, 0.30, 0.40, 2.00, 1.70, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.70, 0.70, 2.00, 1.80, 1.60, 2.00, 1.60, 0.70, 2.00, 1.20,-0.50, 2.00, 1.60, 0.50, 0.80, - 2.80, 2.00, 2.00, 2.00, 2.10, 1.90, 2.00, 1.90, 2.00, 2.00, 2.10, 0.80, 2.00, 1.90, 1.80, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.80, 1.80, 2.00, 1.90, 1.80, 2.00, 1.80, 1.80, 2.00, 2.00, 0.70, 2.00, 1.80, 1.60, 1.00, - 1.00, 0.80,-0.20, 2.00, 0.90, 1.70, 2.00, 1.70,-0.20, 2.00, 0.30, 0.40, 2.00, 1.70, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.50, 0.50, 2.00, 1.60, 2.10, 2.00, 2.10, 0.50, 2.00, 1.10, 0.40, 2.00, 2.10, 1.30, 1.70, - 1.80, 0.60, 1.40, 2.00, 0.70, 1.50, 2.00, 1.50, 1.40, 2.00, 1.10,-1.60, 2.00, 1.50,-0.60, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.80, 1.80, 2.00, 1.90, 1.80, 2.00, 1.80, 1.80, 2.00, 2.00, 0.70, 2.00, 1.80, 1.60, 1.00, - 0.30,-0.90,-0.10, 2.00,-0.80, 0.00, 2.00, 0.00,-0.10, 2.00,-0.40,-3.10, 2.00, 0.00,-2.10, 0.00, - 2.20, 0.90, 1.80, 2.00, 1.00, 0.90, 2.00, 0.90, 1.80, 2.00, 1.50, 0.60, 2.00, 0.90, 1.60, 0.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ G -// G /\ | U -// 3' <------ 5' - 2.00, 1.60, 1.00, 2.00, 2.00, 2.60, 2.00, 2.60, 1.00, 2.00, 1.40, 0.20, 2.00, 2.30, 1.50, 2.20, - 2.40, 1.90, 1.30, 2.00, 2.40, 2.40, 2.00, 2.40, 1.30, 2.00, 1.70,-0.40, 2.00, 2.10, 0.80, 1.50, - 1.00, 0.60, 0.00, 2.00, 1.00, 2.00, 2.00, 2.00, 0.00, 2.00, 0.40, 0.00, 2.00, 1.70, 1.30, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.50, 0.90, 2.00, 1.90, 1.90, 2.00, 1.90, 0.90, 2.00, 1.30,-0.90, 2.00, 1.60, 0.40, 1.10, - 2.80, 1.80, 2.20, 2.00, 2.20, 2.20, 2.00, 2.20, 2.20, 2.00, 2.20, 0.40, 2.00, 1.90, 1.70, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.60, 2.00, 2.00, 2.10, 2.10, 2.00, 2.10, 2.00, 2.00, 2.00, 0.30, 2.00, 1.80, 1.50, 1.20, - 1.00, 0.60, 0.00, 2.00, 1.00, 2.00, 2.00, 2.00, 0.00, 2.00, 0.40, 0.00, 2.00, 1.70, 1.30, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.30, 0.70, 2.00, 1.80, 2.40, 2.00, 2.40, 0.70, 2.00, 1.10, 0.00, 2.00, 2.10, 1.20, 1.90, - 1.80, 0.40, 1.60, 2.00, 0.80, 1.80, 2.00, 1.80, 1.60, 2.00, 1.20,-2.00, 2.00, 1.50,-0.70, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.60, 2.00, 2.00, 2.10, 2.10, 2.00, 2.10, 2.00, 2.00, 2.00, 0.30, 2.00, 1.80, 1.50, 1.20, - 0.30,-1.10, 0.10, 2.00,-0.70, 0.30, 2.00, 0.30, 0.10, 2.00,-0.30,-3.50, 2.00, 0.00,-2.20, 0.30, - 2.20, 0.70, 1.90, 2.00, 1.20, 1.20, 2.00, 1.20, 1.90, 2.00, 1.50, 0.20, 2.00, 0.90, 1.50, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ U -// G /\ | G -// 3' <------ 5' - 2.00, 1.80, 0.80, 2.00, 1.90, 2.30, 2.00, 2.30, 0.80, 2.00, 1.30, 0.60, 2.00, 2.30, 1.60, 1.90, - 2.40, 2.10, 1.10, 2.00, 2.20, 2.10, 2.00, 2.10, 1.10, 2.00, 1.70, 0.00, 2.00, 2.10, 0.90, 1.30, - 1.00, 0.80,-0.20, 2.00, 0.90, 1.70, 2.00, 1.70,-0.20, 2.00, 0.30, 0.40, 2.00, 1.70, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.70, 0.70, 2.00, 1.80, 1.60, 2.00, 1.60, 0.70, 2.00, 1.20,-0.50, 2.00, 1.60, 0.50, 0.80, - 2.80, 2.00, 2.00, 2.00, 2.10, 1.90, 2.00, 1.90, 2.00, 2.00, 2.10, 0.80, 2.00, 1.90, 1.80, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.80, 1.80, 2.00, 1.90, 1.80, 2.00, 1.80, 1.80, 2.00, 2.00, 0.70, 2.00, 1.80, 1.60, 1.00, - 1.00, 0.80,-0.20, 2.00, 0.90, 1.70, 2.00, 1.70,-0.20, 2.00, 0.30, 0.40, 2.00, 1.70, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.50, 0.50, 2.00, 1.60, 2.10, 2.00, 2.10, 0.50, 2.00, 1.10, 0.40, 2.00, 2.10, 1.30, 1.70, - 1.80, 0.60, 1.40, 2.00, 0.70, 1.50, 2.00, 1.50, 1.40, 2.00, 1.10,-1.60, 2.00, 1.50,-0.60, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.80, 1.80, 2.00, 1.90, 1.80, 2.00, 1.80, 1.80, 2.00, 2.00, 0.70, 2.00, 1.80, 1.60, 1.00, - 0.30,-0.90,-0.10, 2.00,-0.80, 0.00, 2.00, 0.00,-0.10, 2.00,-0.40,-3.10, 2.00, 0.00,-2.10, 0.00, - 2.20, 0.90, 1.80, 2.00, 1.00, 0.90, 2.00, 0.90, 1.80, 2.00, 1.50, 0.60, 2.00, 0.90, 1.60, 0.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ A -// C /\ | U -// 3' <------ 5' - 2.10, 1.70, 1.10, 2.00, 2.10, 2.70, 2.00, 2.70, 1.10, 2.00, 1.50, 0.30, 2.00, 2.40, 1.60, 2.30, - 1.80, 1.40, 0.80, 2.00, 1.80, 1.80, 2.00, 1.80, 0.80, 2.00, 1.20,-1.00, 2.00, 1.50, 0.30, 1.00, - 0.70, 0.30,-0.30, 2.00, 0.70, 1.70, 2.00, 1.70,-0.30, 2.00, 0.10,-0.30, 2.00, 1.40, 1.00, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.40, 0.80, 2.00, 1.90, 1.90, 2.00, 1.90, 0.80, 2.00, 1.20,-0.90, 2.00, 1.60, 0.30, 1.00, - 2.50, 1.40, 1.80, 2.00, 1.90, 1.90, 2.00, 1.90, 1.80, 2.00, 1.80, 0.10, 2.00, 1.60, 1.30, 1.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 1.50, 1.90, 2.00, 1.90, 1.90, 2.00, 1.90, 1.90, 2.00, 1.90, 0.10, 2.00, 1.60, 1.40, 1.10, - 0.10,-0.30,-0.90, 2.00, 0.10, 1.10, 2.00, 1.10,-0.90, 2.00,-0.50,-0.90, 2.00, 0.80, 0.40, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.30, 0.70, 2.00, 1.80, 2.40, 2.00, 2.40, 0.70, 2.00, 1.10, 0.00, 2.00, 2.10, 1.20, 1.90, - 0.40,-1.10, 0.10, 2.00,-0.60, 0.40, 2.00, 0.40, 0.10, 2.00,-0.30,-3.50, 2.00, 0.10,-2.20, 0.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.50, 0.40, 0.90, 2.00, 0.90, 0.90, 2.00, 0.90, 0.90, 2.00, 0.80,-0.90, 2.00, 0.60, 0.40, 0.00, - 0.00,-1.50,-0.30, 2.00,-1.00, 0.00, 2.00, 0.00,-0.30, 2.00,-0.70,-3.90, 2.00,-0.30,-2.60,-0.10, - 2.10, 0.70, 1.90, 2.00, 1.10, 1.10, 2.00, 1.10, 1.90, 2.00, 1.50, 0.10, 2.00, 0.80, 1.40, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ C -// C /\ | G -// 3' <------ 5' - 1.50, 1.20,-0.50, 2.00, 1.20, 1.80, 2.00, 0.80, 0.10, 2.00, 1.10,-0.70, 2.00, 1.90,-0.30, 1.50, - 1.20, 0.90,-0.80, 2.00, 0.90, 0.90, 2.00, 0.00,-0.20, 2.00, 0.80,-2.00, 2.00, 1.00,-1.60, 0.20, - 0.10,-0.10,-1.90, 2.00,-0.20, 0.90, 2.00,-0.10,-1.30, 2.00,-0.20,-1.30, 2.00, 0.90,-0.90, 0.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.20, 1.00,-0.80, 2.00, 0.90, 1.00, 2.00, 0.00,-0.10, 2.00, 0.90,-1.90, 2.00, 1.00,-1.50, 0.20, - 1.80, 1.00, 0.20, 2.00, 0.90, 1.00, 2.00, 0.00, 0.90, 2.00, 1.50,-0.90, 2.00, 1.00,-0.50, 0.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.00, 0.30, 2.00, 1.00, 1.00, 2.00, 0.00, 0.90, 2.00, 1.50,-0.90, 2.00, 1.10,-0.50, 0.30, - -0.50,-0.80,-2.60, 2.00,-0.80, 0.20, 2.00,-0.80,-1.90, 2.00,-0.90,-1.90, 2.00, 0.30,-1.50, 0.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.10, 0.90,-0.90, 2.00, 0.80, 1.50, 2.00, 0.50,-0.20, 2.00, 0.80,-1.00, 2.00, 1.50,-0.60, 1.10, - -0.30,-1.50,-1.50, 2.00,-1.60,-0.50, 2.00,-1.50,-0.90, 2.00,-0.60,-4.50, 2.00,-0.50,-4.10,-0.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 0.80, 0.00,-0.80, 2.00, 0.00, 0.00, 2.00,-1.00,-0.10, 2.00, 0.50,-1.90, 2.00, 0.00,-1.50,-0.70, - -0.70,-1.90,-1.90, 2.00,-2.00,-0.90, 2.00,-1.90,-1.30, 2.00,-1.00,-4.90, 2.00,-0.90,-4.50,-0.90, - 1.50, 0.20, 0.30, 2.00, 0.20, 0.20, 2.00,-0.70, 0.90, 2.00, 1.10,-0.90, 2.00, 0.30,-0.50,-0.50, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// C /\ | C -// 3' <------ 5' - 0.50, 1.30,-0.20, 2.00, 0.60, 2.20, 2.00, 2.00, 0.00, 2.00, 1.10,-0.10, 2.00, 2.00, 0.90, 1.40, - 1.10, 1.00, 0.70, 2.00, 1.10, 1.90, 2.00, 1.10,-1.00, 2.00, 0.80,-1.60, 2.00, 1.10,-0.10, 0.30, - 0.40, 0.70,-0.50, 2.00, 0.50, 0.70, 2.00, 0.50,-0.70, 2.00,-0.20,-0.60, 2.00, 1.00, 0.60, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.10, 1.00,-0.40, 2.00, 1.50, 1.30, 2.00, 1.20,-0.70, 2.00, 0.90,-1.60, 2.00, 1.20, 0.00, 0.30, - 1.70, 1.00, 1.10, 2.00, 1.50, 1.30, 2.00, 1.20,-0.60, 2.00, 1.50,-0.60, 2.00, 1.20, 1.00, 0.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.10, 1.20, 2.00, 1.50, 1.40, 2.00, 1.20, 1.20, 2.00, 1.50,-0.50, 2.00, 1.20, 1.00, 0.30, - -0.30,-0.70,-1.70, 2.00, 0.10, 0.70, 2.00, 0.40,-1.60, 2.00,-0.90,-1.60, 2.00, 0.40, 0.30, 0.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.00, 0.90, 0.00, 2.00, 1.40, 1.80, 2.00, 1.70, 0.00, 2.00, 0.80,-0.70, 2.00, 1.70, 0.90, 1.20, - -0.50,-1.50,-1.30, 2.00,-0.60,-0.20, 2.00,-0.10,-0.60, 2.00,-0.60,-4.10, 2.00,-0.30,-2.40, 0.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 0.70, 0.00, 0.20, 2.00, 0.50, 0.30, 2.00, 0.20, 0.20, 2.00, 0.50,-1.60, 2.00, 1.70, 0.00, 0.10, - 0.10,-1.90,-0.90, 2.00,-0.70,-0.30, 2.00,-0.70,-0.80, 2.00,-1.00,-4.40, 2.00,-0.70,-3.00,-1.00, - 1.50,-0.20, 0.90, 2.00, 0.00,-0.10, 2.00, 0.40, 0.90, 2.00, 1.10,-1.00, 2.00, 0.20, 0.60, 0.60, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// C /\ | A -// 3' <------ 5' - 2.10, 1.90, 0.90, 2.00, 2.00, 2.40, 2.00, 2.40, 0.90, 2.00, 1.40, 0.70, 2.00, 2.40, 1.70, 2.00, - 1.80, 1.60, 0.60, 2.00, 1.70, 1.50, 2.00, 1.50, 0.60, 2.00, 1.10,-0.60, 2.00, 1.50, 0.40, 0.70, - 0.70, 0.50,-0.50, 2.00, 0.60, 1.40, 2.00, 1.40,-0.50, 2.00, 0.00, 0.10, 2.00, 1.40, 1.10, 1.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.60, 0.60, 2.00, 1.70, 1.60, 2.00, 1.60, 0.60, 2.00, 1.20,-0.50, 2.00, 1.60, 0.40, 0.80, - 2.50, 1.60, 1.60, 2.00, 1.70, 1.60, 2.00, 1.60, 1.60, 2.00, 1.80, 0.50, 2.00, 1.60, 1.40, 0.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 1.70, 1.70, 2.00, 1.80, 1.60, 2.00, 1.60, 1.70, 2.00, 1.80, 0.50, 2.00, 1.60, 1.50, 0.80, - 0.10,-0.10,-1.10, 2.00, 0.00, 0.80, 2.00, 0.80,-1.10, 2.00,-0.60,-0.50, 2.00, 0.80, 0.50, 0.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.50, 0.50, 2.00, 1.60, 2.10, 2.00, 2.10, 0.50, 2.00, 1.10, 0.40, 2.00, 2.10, 1.30, 1.70, - 0.40,-0.90,-0.10, 2.00,-0.80, 0.10, 2.00, 0.10,-0.10, 2.00,-0.30,-3.10, 2.00, 0.10,-2.10, 0.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.50, 0.60, 0.70, 2.00, 0.70, 0.60, 2.00, 0.60, 0.70, 2.00, 0.80,-0.50, 2.00, 0.60, 0.50,-0.20, - 0.00,-1.30,-0.50, 2.00,-1.20,-0.30, 2.00,-0.30,-0.50, 2.00,-0.70,-3.50, 2.00,-0.30,-2.50,-0.30, - 2.10, 0.90, 1.70, 2.00, 1.00, 0.80, 2.00, 0.80, 1.70, 2.00, 1.40, 0.50, 2.00, 0.80, 1.50, 0.00, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// C /\ | U -// 3' <------ 5' - 2.10, 1.70, 1.10, 2.00, 2.10, 2.70, 2.00, 2.70, 1.10, 2.00, 1.50, 0.30, 2.00, 2.40, 1.60, 2.30, - 1.80, 1.40, 0.80, 2.00, 1.80, 1.80, 2.00, 1.80, 0.80, 2.00, 1.20,-1.00, 2.00, 1.50, 0.30, 1.00, - 0.70, 0.30,-0.30, 2.00, 0.70, 1.70, 2.00, 1.70,-0.30, 2.00, 0.10,-0.30, 2.00, 1.40, 1.00, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.40, 0.80, 2.00, 1.90, 1.90, 2.00, 1.90, 0.80, 2.00, 1.20,-0.90, 2.00, 1.60, 0.30, 1.00, - 2.50, 1.40, 1.80, 2.00, 1.90, 1.90, 2.00, 1.90, 1.80, 2.00, 1.80, 0.10, 2.00, 1.60, 1.30, 1.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 1.50, 1.90, 2.00, 1.90, 1.90, 2.00, 1.90, 1.90, 2.00, 1.90, 0.10, 2.00, 1.60, 1.40, 1.10, - 0.10,-0.30,-0.90, 2.00, 0.10, 1.10, 2.00, 1.10,-0.90, 2.00,-0.50,-0.90, 2.00, 0.80, 0.40, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.30, 0.70, 2.00, 1.80, 2.40, 2.00, 2.40, 0.70, 2.00, 1.10, 0.00, 2.00, 2.10, 1.20, 1.90, - 0.40,-1.10, 0.10, 2.00,-0.60, 0.40, 2.00, 0.40, 0.10, 2.00,-0.30,-3.50, 2.00, 0.10,-2.20, 0.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.50, 0.40, 0.90, 2.00, 0.90, 0.90, 2.00, 0.90, 0.90, 2.00, 0.80,-0.90, 2.00, 0.60, 0.40, 0.00, - 0.00,-1.50,-0.30, 2.00,-1.00, 0.00, 2.00, 0.00,-0.30, 2.00,-0.70,-3.90, 2.00,-0.30,-2.60,-0.10, - 2.10, 0.70, 1.90, 2.00, 1.10, 1.10, 2.00, 1.10, 1.90, 2.00, 1.50, 0.10, 2.00, 0.80, 1.40, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// C /\ | G -// 3' <------ 5' - 2.10, 1.90, 0.90, 2.00, 2.00, 2.40, 2.00, 2.40, 0.90, 2.00, 1.40, 0.70, 2.00, 2.40, 1.70, 2.00, - 1.80, 1.60, 0.60, 2.00, 1.70, 1.50, 2.00, 1.50, 0.60, 2.00, 1.10,-0.60, 2.00, 1.50, 0.40, 0.70, - 0.70, 0.50,-0.50, 2.00, 0.60, 1.40, 2.00, 1.40,-0.50, 2.00, 0.00, 0.10, 2.00, 1.40, 1.10, 1.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.60, 0.60, 2.00, 1.70, 1.60, 2.00, 1.60, 0.60, 2.00, 1.20,-0.50, 2.00, 1.60, 0.40, 0.80, - 2.50, 1.60, 1.60, 2.00, 1.70, 1.60, 2.00, 1.60, 1.60, 2.00, 1.80, 0.50, 2.00, 1.60, 1.40, 0.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 1.70, 1.70, 2.00, 1.80, 1.60, 2.00, 1.60, 1.70, 2.00, 1.80, 0.50, 2.00, 1.60, 1.50, 0.80, - 0.10,-0.10,-1.10, 2.00, 0.00, 0.80, 2.00, 0.80,-1.10, 2.00,-0.60,-0.50, 2.00, 0.80, 0.50, 0.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.50, 0.50, 2.00, 1.60, 2.10, 2.00, 2.10, 0.50, 2.00, 1.10, 0.40, 2.00, 2.10, 1.30, 1.70, - 0.40,-0.90,-0.10, 2.00,-0.80, 0.10, 2.00, 0.10,-0.10, 2.00,-0.30,-3.10, 2.00, 0.10,-2.10, 0.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.50, 0.60, 0.70, 2.00, 0.70, 0.60, 2.00, 0.60, 0.70, 2.00, 0.80,-0.50, 2.00, 0.60, 0.50,-0.20, - 0.00,-1.30,-0.50, 2.00,-1.20,-0.30, 2.00,-0.30,-0.50, 2.00,-0.70,-3.50, 2.00,-0.30,-2.50,-0.30, - 2.10, 0.90, 1.70, 2.00, 1.00, 0.80, 2.00, 0.80, 1.70, 2.00, 1.40, 0.50, 2.00, 0.80, 1.50, 0.00, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ A -// A /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.80, 2.30, 1.70, 2.00, 2.80, 2.80, 2.00, 2.80, 1.70, 2.00, 2.10, 0.00, 2.00, 2.50, 1.20, 1.90, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.90, 1.30, 2.00, 2.30, 2.30, 2.00, 2.30, 1.30, 2.00, 1.70,-0.50, 2.00, 2.00, 0.80, 1.50, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.70, 1.10, 2.00, 2.10, 2.70, 2.00, 2.70, 1.10, 2.00, 1.50, 0.30, 2.00, 2.40, 1.60, 2.30, - 2.20, 0.80, 2.00, 2.00, 1.20, 2.20, 2.00, 2.20, 2.00, 2.00, 1.60,-1.60, 2.00, 1.90,-0.30, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 1.00,-0.50, 0.70, 2.00, 0.00, 1.00, 2.00, 1.00, 0.70, 2.00, 0.30,-2.90, 2.00, 0.70,-1.60, 0.90, - 2.90, 1.50, 2.70, 2.00, 1.90, 1.90, 2.00, 1.90, 2.70, 2.00, 2.30, 0.90, 2.00, 1.60, 2.20, 1.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ C -// A /\ | G -// 3' <------ 5' - 2.10, 1.90, 0.10, 2.00, 1.80, 2.50, 2.00, 1.50, 0.70, 2.00, 1.80, 0.00, 2.00, 2.50, 0.40, 2.10, - 2.10, 1.90, 0.10, 2.00, 1.80, 1.90, 2.00, 0.90, 0.70, 2.00, 1.80,-1.00, 2.00, 1.90,-0.60, 1.10, - 1.10, 0.80,-0.90, 2.00, 0.80, 1.80, 2.00, 0.90,-0.30, 2.00, 0.70,-0.30, 2.00, 1.90, 0.10, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.70, 1.40,-0.30, 2.00, 1.40, 1.40, 2.00, 0.40, 0.30, 2.00, 1.30,-1.50, 2.00, 1.50,-1.10, 0.70, - 2.70, 1.90, 1.10, 2.00, 1.80, 1.90, 2.00, 0.90, 1.70, 2.00, 2.40, 0.00, 2.00, 1.90, 0.40, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 1.10, 0.80,-0.90, 2.00, 0.80, 1.80, 2.00, 0.90,-0.30, 2.00, 0.70,-0.30, 2.00, 1.90, 0.10, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.50, 1.20,-0.50, 2.00, 1.20, 1.80, 2.00, 0.80, 0.10, 2.00, 1.10,-0.70, 2.00, 1.90,-0.30, 1.50, - 1.60, 0.30, 0.40, 2.00, 0.30, 1.30, 2.00, 0.40, 1.00, 2.00, 1.20,-2.60, 2.00, 1.40,-2.20, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.90, 1.10, 2.00, 1.80, 1.90, 2.00, 0.90, 1.70, 2.00, 2.40, 0.00, 2.00, 1.90, 0.40, 1.10, - 0.30,-0.90,-0.90, 2.00,-1.00, 0.10, 2.00,-0.90,-0.30, 2.00, 0.00,-3.90, 2.00, 0.10,-3.50, 0.10, - 2.30, 1.00, 1.10, 2.00, 1.00, 1.00, 2.00, 0.00, 1.70, 2.00, 1.90,-0.10, 2.00, 1.10, 0.30, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// A /\ | C -// 3' <------ 5' - 2.00, 1.90, 1.00, 2.00, 2.40, 2.80, 2.00, 2.70, 1.00, 2.00, 1.80, 0.30, 2.00, 2.70, 1.80, 2.20, - 2.00, 1.90, 1.00, 2.00, 2.40, 2.20, 2.00, 2.10, 1.00, 2.00, 1.80,-0.70, 2.00, 2.10, 0.80, 1.20, - 1.00, 0.90, 0.00, 2.00, 1.30, 2.20, 2.00, 2.00, 0.00, 2.00, 0.70, 0.10, 2.00, 2.00, 1.60, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.60, 1.50, 0.60, 2.00, 1.90, 1.80, 2.00, 1.60, 0.60, 2.00, 1.30,-1.10, 2.00, 1.60, 0.40, 0.70, - 2.60, 1.90, 2.00, 2.00, 2.40, 2.20, 2.00, 2.10, 2.00, 2.00, 2.40, 0.30, 2.00, 2.10, 1.80, 1.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 1.00, 0.90, 0.00, 2.00, 1.30, 2.20, 2.00, 2.00, 0.00, 2.00, 0.70, 0.10, 2.00, 2.00, 1.60, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.40, 1.30, 0.40, 2.00, 1.70, 2.20, 2.00, 2.00, 0.40, 2.00, 1.10,-0.30, 2.00, 2.00, 1.20, 1.50, - 1.50, 0.40, 1.30, 2.00, 0.80, 1.70, 2.00, 1.50, 1.30, 2.00, 1.20,-2.20, 2.00, 1.50,-0.70, 1.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.60, 1.90, 2.00, 2.00, 2.40, 2.20, 2.00, 2.10, 2.00, 2.00, 2.40, 0.30, 2.00, 2.10, 1.80, 1.20, - 0.20,-0.90, 0.00, 2.00,-0.40, 0.40, 2.00, 0.30, 0.00, 2.00, 0.00,-3.50, 2.00, 0.30,-2.00, 0.20, - 2.20, 1.10, 2.00, 2.00, 1.50, 1.40, 2.00, 1.20, 2.00, 2.00, 1.90, 0.30, 2.00, 1.20, 1.80, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// A /\ | A -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.80, 2.50, 1.50, 2.00, 2.60, 2.50, 2.00, 2.50, 1.50, 2.00, 2.10, 0.30, 2.00, 2.50, 1.30, 1.70, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 2.10, 1.10, 2.00, 2.20, 2.00, 2.00, 2.00, 1.10, 2.00, 1.60,-0.10, 2.00, 2.00, 0.90, 1.20, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.90, 0.90, 2.00, 2.00, 2.40, 2.00, 2.40, 0.90, 2.00, 1.40, 0.70, 2.00, 2.40, 1.70, 2.00, - 2.20, 1.00, 1.80, 2.00, 1.10, 1.90, 2.00, 1.90, 1.80, 2.00, 1.50,-1.20, 2.00, 1.90,-0.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 1.00,-0.30, 0.50, 2.00,-0.20, 0.70, 2.00, 0.70, 0.50, 2.00, 0.30,-2.50, 2.00, 0.70,-1.50, 0.70, - 2.90, 1.70, 2.50, 2.00, 1.80, 1.60, 2.00, 1.60, 2.50, 2.00, 2.20, 1.30, 2.00, 1.60, 2.30, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// A /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.80, 2.30, 1.70, 2.00, 2.80, 2.80, 2.00, 2.80, 1.70, 2.00, 2.10, 0.00, 2.00, 2.50, 1.20, 1.90, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.90, 1.30, 2.00, 2.30, 2.30, 2.00, 2.30, 1.30, 2.00, 1.70,-0.50, 2.00, 2.00, 0.80, 1.50, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.70, 1.10, 2.00, 2.10, 2.70, 2.00, 2.70, 1.10, 2.00, 1.50, 0.30, 2.00, 2.40, 1.60, 2.30, - 2.20, 0.80, 2.00, 2.00, 1.20, 2.20, 2.00, 2.20, 2.00, 2.00, 1.60,-1.60, 2.00, 1.90,-0.30, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 1.00,-0.50, 0.70, 2.00, 0.00, 1.00, 2.00, 1.00, 0.70, 2.00, 0.30,-2.90, 2.00, 0.70,-1.60, 0.90, - 2.90, 1.50, 2.70, 2.00, 1.90, 1.90, 2.00, 1.90, 2.70, 2.00, 2.30, 0.90, 2.00, 1.60, 2.20, 1.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// A /\ | G -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.80, 2.50, 1.50, 2.00, 2.60, 2.50, 2.00, 2.50, 1.50, 2.00, 2.10, 0.30, 2.00, 2.50, 1.30, 1.70, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 2.10, 1.10, 2.00, 2.20, 2.00, 2.00, 2.00, 1.10, 2.00, 1.60,-0.10, 2.00, 2.00, 0.90, 1.20, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.90, 0.90, 2.00, 2.00, 2.40, 2.00, 2.40, 0.90, 2.00, 1.40, 0.70, 2.00, 2.40, 1.70, 2.00, - 2.20, 1.00, 1.80, 2.00, 1.10, 1.90, 2.00, 1.90, 1.80, 2.00, 1.50,-1.20, 2.00, 1.90,-0.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 1.00,-0.30, 0.50, 2.00,-0.20, 0.70, 2.00, 0.70, 0.50, 2.00, 0.30,-2.50, 2.00, 0.70,-1.50, 0.70, - 2.90, 1.70, 2.50, 2.00, 1.80, 1.60, 2.00, 1.60, 2.50, 2.00, 2.20, 1.30, 2.00, 1.60, 2.30, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ A -// U /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.60, 2.20, 1.60, 2.00, 2.60, 2.60, 2.00, 2.60, 1.60, 2.00, 2.00,-0.20, 2.00, 2.30, 1.10, 1.80, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.10, 1.50, 2.00, 2.50, 2.50, 2.00, 2.50, 1.50, 2.00, 1.90,-0.30, 2.00, 2.20, 1.00, 1.70, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.60, 1.00, 2.00, 2.10, 2.70, 2.00, 2.70, 1.00, 2.00, 1.40, 0.30, 2.00, 2.40, 1.50, 2.20, - 2.30, 0.90, 2.10, 2.00, 1.30, 2.30, 2.00, 2.30, 2.10, 2.00, 1.70,-1.50, 2.00, 2.00,-0.20, 2.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.30,-0.10, 1.10, 2.00, 0.30, 1.30, 2.00, 1.30, 1.10, 2.00, 0.70,-2.50, 2.00, 1.00,-1.20, 1.30, - 2.70, 1.20, 2.40, 2.00, 1.70, 1.70, 2.00, 1.70, 2.40, 2.00, 2.00, 0.70, 2.00, 1.40, 1.90, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ C -// U /\ | G -// 3' <------ 5' - 2.10, 1.90, 0.10, 2.00, 1.80, 2.50, 2.00, 1.50, 0.70, 2.00, 1.80, 0.00, 2.00, 2.50, 0.40, 2.10, - 2.00, 1.70, 0.00, 2.00, 1.70, 1.70, 2.00, 0.70, 0.60, 2.00, 1.60,-1.20, 2.00, 1.80,-0.80, 1.00, - 0.90, 0.60,-1.10, 2.00, 0.60, 1.60, 2.00, 0.70,-0.50, 2.00, 0.50,-0.50, 2.00, 1.70,-0.10, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.90, 1.60,-0.10, 2.00, 1.60, 1.60, 2.00, 0.60, 0.50, 2.00, 1.50,-1.30, 2.00, 1.70,-0.90, 0.90, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 0.90, 0.60,-1.10, 2.00, 0.60, 1.60, 2.00, 0.70,-0.50, 2.00, 0.50,-0.50, 2.00, 1.70,-0.10, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.40, 1.20,-0.60, 2.00, 1.10, 1.80, 2.00, 0.80, 0.00, 2.00, 1.10,-0.70, 2.00, 1.80,-0.30, 1.40, - 1.70, 0.40, 0.50, 2.00, 0.40, 1.40, 2.00, 0.50, 1.10, 2.00, 1.30,-2.50, 2.00, 1.50,-2.10, 1.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 0.70,-0.50,-0.50, 2.00,-0.60, 0.50, 2.00,-0.50, 0.10, 2.00, 0.40,-3.50, 2.00, 0.50,-3.10, 0.50, - 2.00, 0.80, 0.80, 2.00, 0.70, 0.80, 2.00,-0.20, 1.50, 2.00, 1.70,-0.30, 2.00, 0.80, 0.10, 0.00, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// U /\ | C -// 3' <------ 5' - 2.00, 1.90, 1.00, 2.00, 2.40, 2.80, 2.00, 2.70, 1.00, 2.00, 1.80, 0.30, 2.00, 2.70, 1.80, 2.20, - 1.90, 1.80, 0.90, 2.00, 2.20, 2.10, 2.00, 1.90, 0.90, 2.00, 1.60,-0.80, 2.00, 1.90, 0.70, 1.00, - 0.80, 0.70,-0.20, 2.00, 1.10, 2.00, 2.00, 1.80,-0.20, 2.00, 0.50,-0.10, 2.00, 1.80, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.80, 1.70, 0.80, 2.00, 2.10, 2.00, 2.00, 1.80, 0.80, 2.00, 1.50,-0.90, 2.00, 1.80, 0.60, 0.90, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 0.80, 0.70,-0.20, 2.00, 1.10, 2.00, 2.00, 1.80,-0.20, 2.00, 0.50,-0.10, 2.00, 1.80, 1.40, 1.80, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.30, 1.20, 0.30, 2.00, 1.70, 2.10, 2.00, 2.00, 0.30, 2.00, 1.10,-0.40, 2.00, 2.00, 1.10, 1.50, - 1.60, 0.50, 1.40, 2.00, 0.90, 1.80, 2.00, 1.60, 1.40, 2.00, 1.30,-2.10, 2.00, 1.60,-0.60, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 0.60,-0.50, 0.40, 2.00, 0.00, 0.80, 2.00, 0.70, 0.40, 2.00, 0.40,-3.10, 2.00, 0.70,-1.60, 0.60, - 1.90, 0.80, 1.80, 2.00, 1.30, 1.10, 2.00, 1.00, 1.80, 2.00, 1.70, 0.00, 2.00, 1.00, 1.60, 0.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// U /\ | A -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.60, 2.40, 1.40, 2.00, 2.50, 2.30, 2.00, 2.30, 1.40, 2.00, 1.90, 0.20, 2.00, 2.30, 1.20, 1.50, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.30, 1.30, 2.00, 2.40, 2.20, 2.00, 2.20, 1.30, 2.00, 1.80, 0.10, 2.00, 2.20, 1.10, 1.40, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.80, 0.80, 2.00, 1.90, 2.40, 2.00, 2.40, 0.80, 2.00, 1.40, 0.70, 2.00, 2.40, 1.60, 2.00, - 2.30, 1.10, 1.90, 2.00, 1.20, 2.00, 2.00, 2.00, 1.90, 2.00, 1.60,-1.10, 2.00, 2.00,-0.10, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.30, 0.10, 0.90, 2.00, 0.20, 1.00, 2.00, 1.00, 0.90, 2.00, 0.70,-2.10, 2.00, 1.00,-1.10, 1.10, - 2.70, 1.40, 2.20, 2.00, 1.50, 1.40, 2.00, 1.40, 2.20, 2.00, 2.00, 1.10, 2.00, 1.40, 2.00, 0.60, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// U /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.60, 2.20, 1.60, 2.00, 2.60, 2.60, 2.00, 2.60, 1.60, 2.00, 2.00,-0.20, 2.00, 2.30, 1.10, 1.80, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.10, 1.50, 2.00, 2.50, 2.50, 2.00, 2.50, 1.50, 2.00, 1.90,-0.30, 2.00, 2.20, 1.00, 1.70, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.50, 1.10, 0.50, 2.00, 1.50, 2.50, 2.00, 2.50, 0.50, 2.00, 0.90, 0.50, 2.00, 2.20, 1.80, 2.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.60, 1.00, 2.00, 2.10, 2.70, 2.00, 2.70, 1.00, 2.00, 1.40, 0.30, 2.00, 2.40, 1.50, 2.20, - 2.30, 0.90, 2.10, 2.00, 1.30, 2.30, 2.00, 2.30, 2.10, 2.00, 1.70,-1.50, 2.00, 2.00,-0.20, 2.30, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.30,-0.10, 1.10, 2.00, 0.30, 1.30, 2.00, 1.30, 1.10, 2.00, 0.70,-2.50, 2.00, 1.00,-1.20, 1.30, - 2.70, 1.20, 2.40, 2.00, 1.70, 1.70, 2.00, 1.70, 2.40, 2.00, 2.00, 0.70, 2.00, 1.40, 1.90, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// U /\ | G -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.60, 2.40, 1.40, 2.00, 2.50, 2.30, 2.00, 2.30, 1.40, 2.00, 1.90, 0.20, 2.00, 2.30, 1.20, 1.50, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.50, 2.30, 1.30, 2.00, 2.40, 2.20, 2.00, 2.20, 1.30, 2.00, 1.80, 0.10, 2.00, 2.20, 1.10, 1.40, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.50, 1.30, 0.30, 2.00, 1.40, 2.20, 2.00, 2.20, 0.30, 2.00, 0.80, 0.90, 2.00, 2.20, 1.90, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.80, 0.80, 2.00, 1.90, 2.40, 2.00, 2.40, 0.80, 2.00, 1.40, 0.70, 2.00, 2.40, 1.60, 2.00, - 2.30, 1.10, 1.90, 2.00, 1.20, 2.00, 2.00, 2.00, 1.90, 2.00, 1.60,-1.10, 2.00, 2.00,-0.10, 2.00, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.30, 0.10, 0.90, 2.00, 0.20, 1.00, 2.00, 1.00, 0.90, 2.00, 0.70,-2.10, 2.00, 1.00,-1.10, 1.10, - 2.70, 1.40, 2.20, 2.00, 1.50, 1.40, 2.00, 1.40, 2.20, 2.00, 2.00, 1.10, 2.00, 1.40, 2.00, 0.60, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ A -// G /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.80, 2.30, 1.70, 2.00, 2.80, 2.80, 2.00, 2.80, 1.70, 2.00, 2.10, 0.00, 2.00, 2.50, 1.20, 1.90, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.90, 1.30, 2.00, 2.30, 2.30, 2.00, 2.30, 1.30, 2.00, 1.70,-0.50, 2.00, 2.00, 0.80, 1.50, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.70, 1.10, 2.00, 2.10, 2.70, 2.00, 2.70, 1.10, 2.00, 1.50, 0.30, 2.00, 2.40, 1.60, 2.30, - 2.20, 0.80, 2.00, 2.00, 1.20, 2.20, 2.00, 2.20, 2.00, 2.00, 1.60,-1.60, 2.00, 1.90,-0.30, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 1.00,-0.50, 0.70, 2.00, 0.00, 1.00, 2.00, 1.00, 0.70, 2.00, 0.30,-2.90, 2.00, 0.70,-1.60, 0.90, - 2.90, 1.50, 2.70, 2.00, 1.90, 1.90, 2.00, 1.90, 2.70, 2.00, 2.30, 0.90, 2.00, 1.60, 2.20, 1.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ C -// G /\ | G -// 3' <------ 5' - 2.10, 1.90, 0.10, 2.00, 1.80, 2.50, 2.00, 1.50, 0.70, 2.00, 1.80, 0.00, 2.00, 2.50, 0.40, 2.10, - 2.10, 1.90, 0.10, 2.00, 1.80, 1.90, 2.00, 0.90, 0.70, 2.00, 1.80,-1.00, 2.00, 1.90,-0.60, 1.10, - 1.10, 0.80,-0.90, 2.00, 0.80, 1.80, 2.00, 0.90,-0.30, 2.00, 0.70,-0.30, 2.00, 1.90, 0.10, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.70, 1.40,-0.30, 2.00, 1.40, 1.40, 2.00, 0.40, 0.30, 2.00, 1.30,-1.50, 2.00, 1.50,-1.10, 0.70, - 2.70, 1.90, 1.10, 2.00, 1.80, 1.90, 2.00, 0.90, 1.70, 2.00, 2.40, 0.00, 2.00, 1.90, 0.40, 1.10, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.40, 1.60, 0.80, 2.00, 1.50, 1.60, 2.00, 0.60, 1.40, 2.00, 2.10,-0.30, 2.00, 1.60, 0.10, 0.80, - 1.10, 0.80,-0.90, 2.00, 0.80, 1.80, 2.00, 0.90,-0.30, 2.00, 0.70,-0.30, 2.00, 1.90, 0.10, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.50, 1.20,-0.50, 2.00, 1.20, 1.80, 2.00, 0.80, 0.10, 2.00, 1.10,-0.70, 2.00, 1.90,-0.30, 1.50, - 1.60, 0.30, 0.40, 2.00, 0.30, 1.30, 2.00, 0.40, 1.00, 2.00, 1.20,-2.60, 2.00, 1.40,-2.20, 1.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.70, 1.90, 1.10, 2.00, 1.80, 1.90, 2.00, 0.90, 1.70, 2.00, 2.40, 0.00, 2.00, 1.90, 0.40, 1.10, - 0.30,-0.90,-0.90, 2.00,-1.00, 0.10, 2.00,-0.90,-0.30, 2.00, 0.00,-3.90, 2.00, 0.10,-3.50, 0.10, - 2.30, 1.00, 1.10, 2.00, 1.00, 1.00, 2.00, 0.00, 1.70, 2.00, 1.90,-0.10, 2.00, 1.10, 0.30, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// G /\ | C -// 3' <------ 5' - 2.00, 1.90, 1.00, 2.00, 2.40, 2.80, 2.00, 2.70, 1.00, 2.00, 1.80, 0.30, 2.00, 2.70, 1.80, 2.20, - 2.00, 1.90, 1.00, 2.00, 2.40, 2.20, 2.00, 2.10, 1.00, 2.00, 1.80,-0.70, 2.00, 2.10, 0.80, 1.20, - 1.00, 0.90, 0.00, 2.00, 1.30, 2.20, 2.00, 2.00, 0.00, 2.00, 0.70, 0.10, 2.00, 2.00, 1.60, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.60, 1.50, 0.60, 2.00, 1.90, 1.80, 2.00, 1.60, 0.60, 2.00, 1.30,-1.10, 2.00, 1.60, 0.40, 0.70, - 2.60, 1.90, 2.00, 2.00, 2.40, 2.20, 2.00, 2.10, 2.00, 2.00, 2.40, 0.30, 2.00, 2.10, 1.80, 1.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.60, 1.70, 2.00, 2.10, 1.90, 2.00, 1.80, 1.70, 2.00, 2.10, 0.00, 2.00, 1.80, 1.50, 0.90, - 1.00, 0.90, 0.00, 2.00, 1.30, 2.20, 2.00, 2.00, 0.00, 2.00, 0.70, 0.10, 2.00, 2.00, 1.60, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 1.40, 1.30, 0.40, 2.00, 1.70, 2.20, 2.00, 2.00, 0.40, 2.00, 1.10,-0.30, 2.00, 2.00, 1.20, 1.50, - 1.50, 0.40, 1.30, 2.00, 0.80, 1.70, 2.00, 1.50, 1.30, 2.00, 1.20,-2.20, 2.00, 1.50,-0.70, 1.50, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.60, 1.90, 2.00, 2.00, 2.40, 2.20, 2.00, 2.10, 2.00, 2.00, 2.40, 0.30, 2.00, 2.10, 1.80, 1.20, - 0.20,-0.90, 0.00, 2.00,-0.40, 0.40, 2.00, 0.30, 0.00, 2.00, 0.00,-3.50, 2.00, 0.30,-2.00, 0.20, - 2.20, 1.10, 2.00, 2.00, 1.50, 1.40, 2.00, 1.20, 2.00, 2.00, 1.90, 0.30, 2.00, 1.20, 1.80, 0.30, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// G /\ | A -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.80, 2.50, 1.50, 2.00, 2.60, 2.50, 2.00, 2.50, 1.50, 2.00, 2.10, 0.30, 2.00, 2.50, 1.30, 1.70, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 2.10, 1.10, 2.00, 2.20, 2.00, 2.00, 2.00, 1.10, 2.00, 1.60,-0.10, 2.00, 2.00, 0.90, 1.20, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.90, 0.90, 2.00, 2.00, 2.40, 2.00, 2.40, 0.90, 2.00, 1.40, 0.70, 2.00, 2.40, 1.70, 2.00, - 2.20, 1.00, 1.80, 2.00, 1.10, 1.90, 2.00, 1.90, 1.80, 2.00, 1.50,-1.20, 2.00, 1.90,-0.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 1.00,-0.30, 0.50, 2.00,-0.20, 0.70, 2.00, 0.70, 0.50, 2.00, 0.30,-2.50, 2.00, 0.70,-1.50, 0.70, - 2.90, 1.70, 2.50, 2.00, 1.80, 1.60, 2.00, 1.60, 2.50, 2.00, 2.20, 1.30, 2.00, 1.60, 2.30, 0.80, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// G /\ | U -// 3' <------ 5' - 2.80, 2.30, 1.70, 2.00, 2.80, 3.40, 2.00, 3.40, 1.70, 2.00, 2.10, 1.00, 2.00, 3.10, 2.20, 2.90, - 2.80, 2.30, 1.70, 2.00, 2.80, 2.80, 2.00, 2.80, 1.70, 2.00, 2.10, 0.00, 2.00, 2.50, 1.20, 1.90, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 1.90, 1.30, 2.00, 2.30, 2.30, 2.00, 2.30, 1.30, 2.00, 1.70,-0.50, 2.00, 2.00, 0.80, 1.50, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.00, 2.40, 2.00, 2.50, 2.50, 2.00, 2.50, 2.40, 2.00, 2.40, 0.70, 2.00, 2.20, 1.90, 1.60, - 1.70, 1.30, 0.70, 2.00, 1.70, 2.70, 2.00, 2.70, 0.70, 2.00, 1.10, 0.70, 2.00, 2.40, 2.00, 2.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.70, 1.10, 2.00, 2.10, 2.70, 2.00, 2.70, 1.10, 2.00, 1.50, 0.30, 2.00, 2.40, 1.60, 2.30, - 2.20, 0.80, 2.00, 2.00, 1.20, 2.20, 2.00, 2.20, 2.00, 2.00, 1.60,-1.60, 2.00, 1.90,-0.30, 2.20, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.30, 2.70, 2.00, 2.80, 2.80, 2.00, 2.80, 2.70, 2.00, 2.70, 1.00, 2.00, 2.50, 2.20, 1.90, - 1.00,-0.50, 0.70, 2.00, 0.00, 1.00, 2.00, 1.00, 0.70, 2.00, 0.30,-2.90, 2.00, 0.70,-1.60, 0.90, - 2.90, 1.50, 2.70, 2.00, 1.90, 1.90, 2.00, 1.90, 2.70, 2.00, 2.30, 0.90, 2.00, 1.60, 2.20, 1.10, - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// G /\ | G -// 3' <------ 5' - 2.80, 2.50, 1.50, 2.00, 2.60, 3.10, 2.00, 3.10, 1.50, 2.00, 2.10, 1.30, 2.00, 3.10, 2.30, 2.70, - 2.80, 2.50, 1.50, 2.00, 2.60, 2.50, 2.00, 2.50, 1.50, 2.00, 2.10, 0.30, 2.00, 2.50, 1.30, 1.70, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.30, 2.10, 1.10, 2.00, 2.20, 2.00, 2.00, 2.00, 1.10, 2.00, 1.60,-0.10, 2.00, 2.00, 0.90, 1.20, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.10, 2.20, 2.20, 2.00, 2.30, 2.20, 2.00, 2.20, 2.20, 2.00, 2.40, 1.00, 2.00, 2.20, 2.00, 1.40, - 1.70, 1.50, 0.50, 2.00, 1.60, 2.40, 2.00, 2.40, 0.50, 2.00, 1.00, 1.10, 2.00, 2.40, 2.10, 2.40, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 2.10, 1.90, 0.90, 2.00, 2.00, 2.40, 2.00, 2.40, 0.90, 2.00, 1.40, 0.70, 2.00, 2.40, 1.70, 2.00, - 2.20, 1.00, 1.80, 2.00, 1.10, 1.90, 2.00, 1.90, 1.80, 2.00, 1.50,-1.20, 2.00, 1.90,-0.20, 1.90, - 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, - 3.40, 2.50, 2.50, 2.00, 2.60, 2.50, 2.00, 2.50, 2.50, 2.00, 2.70, 1.30, 2.00, 2.50, 2.30, 1.70, - 1.00,-0.30, 0.50, 2.00,-0.20, 0.70, 2.00, 0.70, 0.50, 2.00, 0.30,-2.50, 2.00, 0.70,-1.50, 0.70, - 2.90, 1.70, 2.50, 2.00, 1.80, 1.60, 2.00, 1.60, 2.50, 2.00, 2.20, 1.30, 2.00, 1.60, 2.30, 0.80 -}; diff --git a/src/data/interior_loop_2_2_enthalpies.dat b/src/data/interior_loop_2_2_enthalpies.dat deleted file mode 100644 index 503cda3f..00000000 --- a/src/data/interior_loop_2_2_enthalpies.dat +++ /dev/null @@ -1,973 +0,0 @@ -// Tandem mismatch enthalpies (2 x 2 interior loops) from mfold Version 2.3 (Walter et al.:PNAS1994) -// Data tables for symetric interior loops of size 4 -// Enthalpies for RNA -// Data arrangement: -// -// Y -// ---------------------------------------------------------------- -// (X) A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// ---------------------------------------------------------------- -// 5' ------> 3' -// (*64)(*4) -// (*1536)A \/ \_/ A(*256) -// U /\ | U -// (*16)(*1) -// 3' <------ 5' -// -// (AA) . . . . . . . . . . . . . . . . -// (AC) . . . . . . . . . . . . . . . . -// (AG) . . . . . . . . . . . . . . . . -// (AU) . . . . . . . . . . . . . . . . -// (CA) . . . . . . . . . . . . . . . . -// (CC) . . . . . . . . . . . . . . . . -// (CG) . . . . . . . . . . . . . . . . -// (CU) . . . . . . . . . . . . . . . . -// (GA) . . . . . . . . . . . . . . . . -// (GC) . . . . . . . . . . . . . . . . -// (GG) . . . . . . . . . . . . . . . . -// (GU) . . . . . . . . . . . . . . . . -// (UA) . . . . . . . . . . . . . . . . -// (UC) . . . . . . . . . . . . . . . . -// (UG) . . . . . . . . . . . . . . . . -// (UU) . . . . . . . . . . . . . . . . - -double interior_loop_2_2_enthalpy[]= -{ - -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ A -// U /\ | U -// 3' <------ 5' - -8.30,-8.60,-8.10,-7.1,-10.60,-9.4,-11.10,-5.7,-13.20,-6.3,-13.20,-7.1,-10.20,-6.1,-11.10,-5.70, - -10.0,-10.30,-9.80,-8.8,-12.3,-11.1,-12.80,-7.4,-14.90,-8.0,-14.90,-8.8,-11.90,-7.8,-12.80,-7.40, - -10.0,-10.30,-9.80,-8.8,-12.3,-11.1,-12.80,-7.4,-14.90,-8.0,-14.90,-8.8,-11.90,-7.8,-12.80,-7.40, - -10.0,-10.30,-9.80,-8.8,-12.3,-11.1,-12.80,-7.4,-14.90,-8.0,-14.90,-8.8,-11.90,-7.8,-12.80,-7.40, - -6.60,-6.90,-6.40,-5.40,-8.90,-7.70,-9.40,-4.0,-11.50,-4.6,-11.50,-5.40,-8.50,-4.40,-9.40,-4.00, - -6.40,-6.70,-6.20,-5.20,-8.70,-7.50,-9.20,-3.8,-11.30,-4.4,-11.30,-5.20,-8.30,-4.20,-9.20,-3.80, - -6.40,-6.70,-6.20,-5.20,-8.70,-7.50,-9.20,-3.8,-11.30,-4.4,-11.30,-5.20,-8.30,-4.20,-9.20,-3.80, - -6.40,-6.70,-6.20,-5.20,-8.70,-7.50,-9.20,-3.8,-11.30,-4.4,-11.30,-5.20,-8.30,-4.20,-9.20,-3.80, - -7.40,-7.70,-7.20,-6.20,-9.70,-8.5,-10.20,-4.8,-12.30,-5.4,-12.30,-6.20,-9.30,-5.2,-10.20,-4.80, - -10.9,-11.2,-10.70,-9.7,-13.2,-12.0,-13.70,-8.3,-15.80,-8.9,-15.80,-9.7,-12.80,-8.7,-13.70,-8.30, - -10.9,-11.2,-10.70,-9.7,-13.2,-12.0,-13.70,-8.3,-15.80,-8.9,-15.80,-9.7,-12.80,-8.7,-13.70,-8.30, - -10.9,-11.2,-10.70,-9.7,-13.2,-12.0,-13.70,-8.3,-15.80,-8.9,-15.80,-9.7,-12.80,-8.7,-13.70,-8.30, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ C -// U /\ | G -// 3' <------ 5' - -9.5,-11.5,-11.40,-9.3,-13.10,-7.4,-11.70,-9.30,-9.90,-7.4,-10.50,-9.3,-13.10,-8.2,-11.7,-10.00, - -11.2,-13.2,-13.1,-11.0,-14.80,-9.1,-13.4,-11.0,-11.60,-9.1,-12.2,-11.0,-14.80,-9.9,-13.4,-11.70, - -11.2,-13.2,-13.1,-11.0,-14.80,-9.1,-13.4,-11.0,-11.60,-9.1,-12.2,-11.0,-14.80,-9.9,-13.4,-11.70, - -11.2,-13.2,-13.1,-11.0,-14.80,-9.1,-13.4,-11.0,-11.60,-9.1,-12.2,-11.0,-14.80,-9.9,-13.4,-11.70, - -7.80,-9.80,-9.70,-7.6,-11.40,-5.7,-10.00,-7.60,-8.20,-5.70,-8.80,-7.6,-11.40,-6.5,-10.00,-8.30, - -7.60,-9.60,-9.50,-7.4,-11.20,-5.50,-9.80,-7.40,-8.00,-5.50,-8.60,-7.4,-11.20,-6.30,-9.80,-8.10, - -7.60,-9.60,-9.50,-7.4,-11.20,-5.50,-9.80,-7.40,-8.00,-5.50,-8.60,-7.4,-11.20,-6.30,-9.80,-8.10, - -7.60,-9.60,-9.50,-7.4,-11.20,-5.50,-9.80,-7.40,-8.00,-5.50,-8.60,-7.4,-11.20,-6.30,-9.80,-8.10, - -8.6,-10.6,-10.50,-8.4,-12.20,-6.5,-10.80,-8.40,-9.00,-6.50,-9.60,-8.4,-12.20,-7.3,-10.80,-9.10, - -12.1,-14.1,-14.0,-11.9,-15.7,-10.0,-14.3,-11.9,-12.5,-10.0,-13.1,-11.9,-15.7,-10.8,-14.3,-12.60, - -12.1,-14.1,-14.0,-11.9,-15.7,-10.0,-14.3,-11.9,-12.5,-10.0,-13.1,-11.9,-15.7,-10.8,-14.3,-12.60, - -12.1,-14.1,-14.0,-11.9,-15.7,-10.0,-14.3,-11.9,-12.5,-10.0,-13.1,-11.9,-15.7,-10.8,-14.3,-12.60, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ G -// U /\ | C -// 3' <------ 5' - -4.00,-9.5,-13.7,-12.40, 5.20,-8.8,-13.7,-11.70, 6.00,-9.5,-13.7,-12.4,-14.6,-11.0,-13.7,-12.90, - -5.7,-11.2,-15.4,-14.10, 3.5,-10.5,-15.4,-13.40, 4.3,-11.2,-15.4,-14.1,-16.3,-12.7,-15.4,-14.60, - -5.7,-11.2,-15.4,-14.10, 3.5,-10.5,-15.4,-13.40, 4.3,-11.2,-15.4,-14.1,-16.3,-12.7,-15.4,-14.60, - -5.7,-11.2,-15.4,-14.10, 3.5,-10.5,-15.4,-13.40, 4.3,-11.2,-15.4,-14.1,-16.3,-12.7,-15.4,-14.60, - -2.30,-7.8,-12.0,-10.70, 6.90,-7.1,-12.0,-10.00, 7.70,-7.8,-12.0,-10.7,-12.90,-9.3,-12.0,-11.20, - -2.10,-7.6,-11.8,-10.50, 7.10,-6.9,-11.80,-9.80, 7.90,-7.6,-11.8,-10.5,-12.70,-9.1,-11.8,-11.00, - -2.10,-7.6,-11.8,-10.50, 7.10,-6.9,-11.80,-9.80, 7.90,-7.6,-11.8,-10.5,-12.70,-9.1,-11.8,-11.00, - -2.10,-7.6,-11.8,-10.50, 7.10,-6.9,-11.80,-9.80, 7.90,-7.6,-11.8,-10.5,-12.70,-9.1,-11.8,-11.00, - -3.10,-8.6,-12.8,-11.50, 6.10,-7.9,-12.8,-10.80, 6.90,-8.6,-12.8,-11.5,-13.7,-10.1,-12.8,-12.00, - -6.6,-12.1,-16.3,-15.00, 2.6,-11.4,-16.3,-14.30, 3.4,-12.1,-16.3,-15.0,-17.2,-13.6,-16.3,-15.50, - -6.6,-12.1,-16.3,-15.00, 2.6,-11.4,-16.3,-14.30, 3.4,-12.1,-16.3,-15.0,-17.2,-13.6,-16.3,-15.50, - -6.6,-12.1,-16.3,-15.00, 2.6,-11.4,-16.3,-14.30, 3.4,-12.1,-16.3,-15.0,-17.2,-13.6,-16.3,-15.50, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ U -// U /\ | A -// 3' <------ 5' - -8.60,-6.90,-7.70,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.60, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -6.90,-5.20,-6.00,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -7.70,-6.00,-6.80,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ G -// U /\ | U -// 3' <------ 5' - -11.50,-9.1,-10.90,-9.8,-12.20,-9.1,-12.40,-8.7,-13.90,-7.9,-13.50,-9.8,-12.40,-9.1,-12.40,-7.90, - -13.2,-10.8,-12.6,-11.5,-13.9,-10.8,-14.1,-10.4,-15.60,-9.6,-15.2,-11.5,-14.1,-10.8,-14.10,-9.60, - -13.2,-10.8,-12.6,-11.5,-13.9,-10.8,-14.1,-10.4,-15.60,-9.6,-15.2,-11.5,-14.1,-10.8,-14.10,-9.60, - -13.2,-10.8,-12.6,-11.5,-13.9,-10.8,-14.1,-10.4,-15.60,-9.6,-15.2,-11.5,-14.1,-10.8,-14.10,-9.60, - -9.80,-7.40,-9.20,-8.1,-10.50,-7.4,-10.70,-7.0,-12.20,-6.2,-11.80,-8.1,-10.70,-7.4,-10.70,-6.20, - -9.60,-7.20,-9.00,-7.9,-10.30,-7.2,-10.50,-6.8,-12.00,-6.0,-11.60,-7.9,-10.50,-7.2,-10.50,-6.00, - -9.60,-7.20,-9.00,-7.9,-10.30,-7.2,-10.50,-6.8,-12.00,-6.0,-11.60,-7.9,-10.50,-7.2,-10.50,-6.00, - -9.60,-7.20,-9.00,-7.9,-10.30,-7.2,-10.50,-6.8,-12.00,-6.0,-11.60,-7.9,-10.50,-7.2,-10.50,-6.00, - -10.60,-8.2,-10.00,-8.9,-11.30,-8.2,-11.50,-7.8,-13.00,-7.0,-12.60,-8.9,-11.50,-8.2,-11.50,-7.00, - -14.1,-11.7,-13.5,-12.4,-14.8,-11.7,-15.0,-11.3,-16.5,-10.5,-16.1,-12.4,-15.0,-11.7,-15.0,-10.50, - -14.1,-11.7,-13.5,-12.4,-14.8,-11.7,-15.0,-11.3,-16.5,-10.5,-16.1,-12.4,-15.0,-11.7,-15.0,-10.50, - -14.1,-11.7,-13.5,-12.4,-14.8,-11.7,-15.0,-11.3,-16.5,-10.5,-16.1,-12.4,-15.0,-11.7,-15.0,-10.50, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// A \/ \_/ U -// U /\ | G -// 3' <------ 5' - -8.60,-6.90,-7.70,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.60, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -6.90,-5.20,-6.00,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -7.70,-6.00,-6.80,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ A -// G /\ | U -// 3' <------ 5' - -3.70,-4.00,-3.50,-2.50,-6.00,-4.80,-6.50,-1.10,-8.60,-1.70,-8.60,-2.50,-5.60,-1.50,-6.50,-1.10, - 5.50, 5.20, 5.70, 6.70, 3.20, 4.40, 2.70, 8.10, 0.60, 7.50, 0.60, 6.70, 3.60, 7.70, 2.70, 8.10, - 6.30, 6.00, 6.50, 7.50, 4.00, 5.20, 3.50, 8.90, 1.40, 8.30, 1.40, 7.50, 4.40, 8.50, 3.50, 8.90, - -14.3,-14.6,-14.1,-13.1,-16.6,-15.4,-17.1,-11.7,-19.2,-12.3,-19.2,-13.1,-16.2,-12.1,-17.1,-11.70, - -9.20,-9.50,-9.00,-8.0,-11.5,-10.3,-12.00,-6.6,-14.10,-7.2,-14.10,-8.0,-11.10,-7.0,-12.00,-6.60, - -8.50,-8.80,-8.30,-7.3,-10.80,-9.6,-11.30,-5.9,-13.40,-6.5,-13.40,-7.3,-10.40,-6.3,-11.30,-5.90, - -9.20,-9.50,-9.00,-8.0,-11.5,-10.3,-12.00,-6.6,-14.10,-7.2,-14.10,-8.0,-11.10,-7.0,-12.00,-6.60, - -10.7,-11.0,-10.50,-9.5,-13.0,-11.8,-13.50,-8.1,-15.60,-8.7,-15.60,-9.5,-12.60,-8.5,-13.50,-8.10, - -13.4,-13.7,-13.2,-12.2,-15.7,-14.5,-16.2,-10.8,-18.3,-11.4,-18.3,-12.2,-15.3,-11.2,-16.2,-10.80, - -13.4,-13.7,-13.2,-12.2,-15.7,-14.5,-16.2,-10.8,-18.3,-11.4,-18.3,-12.2,-15.3,-11.2,-16.2,-10.80, - -13.4,-13.7,-13.2,-12.2,-15.7,-14.5,-16.2,-10.8,-18.3,-11.4,-18.3,-12.2,-15.3,-11.2,-16.2,-10.80, - -13.4,-13.7,-13.2,-12.2,-15.7,-14.5,-16.2,-10.8,-18.3,-11.4,-18.3,-12.2,-15.3,-11.2,-16.2,-10.80, - -12.1,-12.4,-11.9,-10.9,-14.4,-13.2,-14.90,-9.5,-17.0,-10.1,-17.0,-10.9,-14.00,-9.9,-14.90,-9.50, - -11.4,-11.7,-11.2,-10.2,-13.7,-12.5,-14.20,-8.8,-16.30,-9.4,-16.3,-10.2,-13.30,-9.2,-14.20,-8.80, - -12.1,-12.4,-11.9,-10.9,-14.4,-13.2,-14.90,-9.5,-17.0,-10.1,-17.0,-10.9,-14.00,-9.9,-14.90,-9.50, - -12.6,-12.9,-12.4,-11.4,-14.9,-13.7,-15.4,-10.0,-17.5,-10.6,-17.5,-11.4,-14.5,-10.4,-15.4,-10.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ C -// G /\ | G -// 3' <------ 5' - -4.90,-6.90,-6.80,-4.70,-8.50,-2.80,-7.10,-4.70,-5.30,-2.80,-5.90,-4.70,-8.50,-3.60,-7.10,-5.40, - 4.30, 2.30, 2.40, 4.50, 0.70, 6.40, 2.10, 4.50, 3.90, 6.40, 3.30, 4.50, 0.70, 5.60, 2.10, 3.80, - 5.10, 3.10, 3.20, 5.30, 1.50, 7.20, 2.90, 5.30, 4.70, 7.20, 4.10, 5.30, 1.50, 6.40, 2.90, 4.60, - -15.5,-17.5,-17.4,-15.3,-19.1,-13.4,-17.7,-15.3,-15.9,-13.4,-16.5,-15.3,-19.1,-14.2,-17.7,-16.00, - -10.4,-12.4,-12.3,-10.2,-14.00,-8.3,-12.6,-10.2,-10.80,-8.3,-11.4,-10.2,-14.00,-9.1,-12.6,-10.90, - -9.7,-11.7,-11.60,-9.5,-13.30,-7.6,-11.90,-9.5,-10.10,-7.6,-10.70,-9.5,-13.30,-8.4,-11.9,-10.20, - -10.4,-12.4,-12.3,-10.2,-14.00,-8.3,-12.6,-10.2,-10.80,-8.3,-11.4,-10.2,-14.00,-9.1,-12.6,-10.90, - -11.9,-13.9,-13.8,-11.7,-15.50,-9.8,-14.1,-11.7,-12.30,-9.8,-12.9,-11.7,-15.5,-10.6,-14.1,-12.40, - -14.6,-16.6,-16.5,-14.4,-18.2,-12.5,-16.8,-14.4,-15.0,-12.5,-15.6,-14.4,-18.2,-13.3,-16.8,-15.10, - -14.6,-16.6,-16.5,-14.4,-18.2,-12.5,-16.8,-14.4,-15.0,-12.5,-15.6,-14.4,-18.2,-13.3,-16.8,-15.10, - -14.6,-16.6,-16.5,-14.4,-18.2,-12.5,-16.8,-14.4,-15.0,-12.5,-15.6,-14.4,-18.2,-13.3,-16.8,-15.10, - -14.6,-16.6,-16.5,-14.4,-18.2,-12.5,-16.8,-14.4,-15.0,-12.5,-15.6,-14.4,-18.2,-13.3,-16.8,-15.10, - -13.3,-15.3,-15.2,-13.1,-16.9,-11.2,-15.5,-13.1,-13.7,-11.2,-14.3,-13.1,-16.9,-12.0,-15.5,-13.80, - -12.6,-14.6,-14.5,-12.4,-16.2,-10.5,-14.8,-12.4,-13.0,-10.5,-13.6,-12.4,-16.2,-11.3,-14.8,-13.10, - -13.3,-15.3,-15.2,-13.1,-16.9,-11.2,-15.5,-13.1,-13.7,-11.2,-14.3,-13.1,-16.9,-12.0,-15.5,-13.80, - -13.8,-15.8,-15.7,-13.6,-17.4,-11.7,-16.0,-13.6,-14.2,-11.7,-14.8,-13.6,-17.4,-12.5,-16.0,-14.30, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ G -// G /\ | C -// 3' <------ 5' - 0.60,-4.90,-9.10,-7.80, 9.80,-4.20,-9.10,-7.10,10.60,-4.90,-9.10,-7.8,-10.00,-6.40,-9.10,-8.30, - 9.80, 4.30, 0.10, 1.40,19.00, 5.00, 0.10, 2.10,19.80, 4.30, 0.10, 1.40,-0.80, 2.80, 0.10, 0.90, - 10.60, 5.10, 0.90, 2.20,19.80, 5.80, 0.90, 2.90,20.60, 5.10, 0.90, 2.20, 0.00, 3.60, 0.90, 1.70, - -10.0,-15.5,-19.7,-18.40,-0.8,-14.8,-19.7,-17.70, 0.0,-15.5,-19.7,-18.4,-20.6,-17.0,-19.7,-18.90, - -4.9,-10.4,-14.6,-13.30, 4.30,-9.7,-14.6,-12.60, 5.1,-10.4,-14.6,-13.3,-15.5,-11.9,-14.6,-13.80, - -4.20,-9.7,-13.9,-12.60, 5.00,-9.0,-13.9,-11.90, 5.80,-9.7,-13.9,-12.6,-14.8,-11.2,-13.9,-13.10, - -4.9,-10.4,-14.6,-13.30, 4.30,-9.7,-14.6,-12.60, 5.1,-10.4,-14.6,-13.3,-15.5,-11.9,-14.6,-13.80, - -6.4,-11.9,-16.1,-14.80, 2.8,-11.2,-16.1,-14.10, 3.6,-11.9,-16.1,-14.8,-17.0,-13.4,-16.1,-15.30, - -9.1,-14.6,-18.8,-17.50, 0.1,-13.9,-18.8,-16.80, 0.9,-14.6,-18.8,-17.5,-19.7,-16.1,-18.8,-18.00, - -9.1,-14.6,-18.8,-17.50, 0.1,-13.9,-18.8,-16.80, 0.9,-14.6,-18.8,-17.5,-19.7,-16.1,-18.8,-18.00, - -9.1,-14.6,-18.8,-17.50, 0.1,-13.9,-18.8,-16.80, 0.9,-14.6,-18.8,-17.5,-19.7,-16.1,-18.8,-18.00, - -9.1,-14.6,-18.8,-17.50, 0.1,-13.9,-18.8,-16.80, 0.9,-14.6,-18.8,-17.5,-19.7,-16.1,-18.8,-18.00, - -7.8,-13.3,-17.5,-16.20, 1.4,-12.6,-17.5,-15.50, 2.2,-13.3,-17.5,-16.2,-18.4,-14.8,-17.5,-16.70, - -7.1,-12.6,-16.8,-15.50, 2.1,-11.9,-16.8,-14.80, 2.9,-12.6,-16.8,-15.5,-17.7,-14.1,-16.8,-16.00, - -7.8,-13.3,-17.5,-16.20, 1.4,-12.6,-17.5,-15.50, 2.2,-13.3,-17.5,-16.2,-18.4,-14.8,-17.5,-16.70, - -8.3,-13.8,-18.0,-16.70, 0.9,-13.1,-18.0,-16.00, 1.7,-13.8,-18.0,-16.7,-18.9,-15.3,-18.0,-17.20, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ U -// G /\ | A -// 3' <------ 5' - -4.00,-2.30,-3.10,-3.00,-5.70,-2.10,-6.60,-3.00,-5.70,-2.10,-6.60,-3.00,-5.70,-2.10,-6.60,-3.00, - 5.20, 6.90, 6.10, 6.20, 3.50, 7.10, 2.60, 6.20, 3.50, 7.10, 2.60, 6.20, 3.50, 7.10, 2.60, 6.20, - 6.00, 7.70, 6.90, 7.00, 4.30, 7.90, 3.40, 7.00, 4.30, 7.90, 3.40, 7.00, 4.30, 7.90, 3.40, 7.00, - -14.6,-12.9,-13.7,-13.6,-16.3,-12.7,-17.2,-13.6,-16.3,-12.7,-17.2,-13.6,-16.3,-12.7,-17.2,-13.60, - -9.50,-7.80,-8.60,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.50, - -8.80,-7.10,-7.90,-7.8,-10.50,-6.9,-11.40,-7.8,-10.50,-6.9,-11.40,-7.8,-10.50,-6.9,-11.40,-7.80, - -9.50,-7.80,-8.60,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.50, - -11.00,-9.3,-10.1,-10.0,-12.70,-9.1,-13.6,-10.0,-12.70,-9.1,-13.6,-10.0,-12.70,-9.1,-13.6,-10.00, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -11.7,-10.0,-10.8,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.70, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -12.9,-11.2,-12.0,-11.9,-14.6,-11.0,-15.5,-11.9,-14.6,-11.0,-15.5,-11.9,-14.6,-11.0,-15.5,-11.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ G -// G /\ | U -// 3' <------ 5' - -6.90,-4.50,-6.30,-5.20,-7.60,-4.50,-7.80,-4.10,-9.30,-3.30,-8.90,-5.20,-7.80,-4.50,-7.80,-3.30, - 2.30, 4.70, 2.90, 4.00, 1.60, 4.70, 1.40, 5.10,-0.10, 5.90, 0.30, 4.00, 1.40, 4.70, 1.40, 5.90, - 3.10, 5.50, 3.70, 4.80, 2.40, 5.50, 2.20, 5.90, 0.70, 6.70, 1.10, 4.80, 2.20, 5.50, 2.20, 6.70, - -17.5,-15.1,-16.9,-15.8,-18.2,-15.1,-18.4,-14.7,-19.9,-13.9,-19.5,-15.8,-18.4,-15.1,-18.4,-13.90, - -12.4,-10.0,-11.8,-10.7,-13.1,-10.0,-13.30,-9.6,-14.80,-8.8,-14.4,-10.7,-13.3,-10.0,-13.30,-8.80, - -11.70,-9.3,-11.1,-10.0,-12.40,-9.3,-12.60,-8.9,-14.10,-8.1,-13.7,-10.0,-12.60,-9.3,-12.60,-8.10, - -12.4,-10.0,-11.8,-10.7,-13.1,-10.0,-13.30,-9.6,-14.80,-8.8,-14.4,-10.7,-13.3,-10.0,-13.30,-8.80, - -13.9,-11.5,-13.3,-12.2,-14.6,-11.5,-14.8,-11.1,-16.3,-10.3,-15.9,-12.2,-14.8,-11.5,-14.8,-10.30, - -16.6,-14.2,-16.0,-14.9,-17.3,-14.2,-17.5,-13.8,-19.0,-13.0,-18.6,-14.9,-17.5,-14.2,-17.5,-13.00, - -16.6,-14.2,-16.0,-14.9,-17.3,-14.2,-17.5,-13.8,-19.0,-13.0,-18.6,-14.9,-17.5,-14.2,-17.5,-13.00, - -16.6,-14.2,-16.0,-14.9,-17.3,-14.2,-17.5,-13.8,-19.0,-13.0,-18.6,-14.9,-17.5,-14.2,-17.5,-13.00, - -16.6,-14.2,-16.0,-14.9,-17.3,-14.2,-17.5,-13.8,-19.0,-13.0,-18.6,-14.9,-17.5,-14.2,-17.5,-13.00, - -15.3,-12.9,-14.7,-13.6,-16.0,-12.9,-16.2,-12.5,-17.7,-11.7,-17.3,-13.6,-16.2,-12.9,-16.2,-11.70, - -14.6,-12.2,-14.0,-12.9,-15.3,-12.2,-15.5,-11.8,-17.0,-11.0,-16.6,-12.9,-15.5,-12.2,-15.5,-11.00, - -15.3,-12.9,-14.7,-13.6,-16.0,-12.9,-16.2,-12.5,-17.7,-11.7,-17.3,-13.6,-16.2,-12.9,-16.2,-11.70, - -15.8,-13.4,-15.2,-14.1,-16.5,-13.4,-16.7,-13.0,-18.2,-12.2,-17.8,-14.1,-16.7,-13.4,-16.7,-12.20, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// C \/ \_/ U -// G /\ | G -// 3' <------ 5' - -4.00,-2.30,-3.10,-3.00,-5.70,-2.10,-6.60,-3.00,-5.70,-2.10,-6.60,-3.00,-5.70,-2.10,-6.60,-3.00, - 5.20, 6.90, 6.10, 6.20, 3.50, 7.10, 2.60, 6.20, 3.50, 7.10, 2.60, 6.20, 3.50, 7.10, 2.60, 6.20, - 6.00, 7.70, 6.90, 7.00, 4.30, 7.90, 3.40, 7.00, 4.30, 7.90, 3.40, 7.00, 4.30, 7.90, 3.40, 7.00, - -14.6,-12.9,-13.7,-13.6,-16.3,-12.7,-17.2,-13.6,-16.3,-12.7,-17.2,-13.6,-16.3,-12.7,-17.2,-13.60, - -9.50,-7.80,-8.60,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.50, - -8.80,-7.10,-7.90,-7.8,-10.50,-6.9,-11.40,-7.8,-10.50,-6.9,-11.40,-7.8,-10.50,-6.9,-11.40,-7.80, - -9.50,-7.80,-8.60,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.50, - -11.00,-9.3,-10.1,-10.0,-12.70,-9.1,-13.6,-10.0,-12.70,-9.1,-13.6,-10.0,-12.70,-9.1,-13.6,-10.00, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -13.7,-12.0,-12.8,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.7,-15.4,-11.8,-16.3,-12.70, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -11.7,-10.0,-10.8,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.70, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -12.9,-11.2,-12.0,-11.9,-14.6,-11.0,-15.5,-11.9,-14.6,-11.0,-15.5,-11.9,-14.6,-11.0,-15.5,-11.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ A -// C /\ | U -// 3' <------ 5' - -9.20,-9.50,-9.00,-8.0,-11.5,-10.3,-12.00,-6.6,-14.10,-7.2,-14.10,-8.0,-11.10,-7.0,-12.00,-6.60, - -12.8,-13.1,-12.6,-11.6,-15.1,-13.9,-15.6,-10.2,-17.7,-10.8,-17.7,-11.6,-14.7,-10.6,-15.6,-10.20, - -9.60,-9.90,-9.40,-8.4,-11.9,-10.7,-12.40,-7.0,-14.50,-7.6,-14.50,-8.4,-11.50,-7.4,-12.40,-7.00, - -12.8,-13.1,-12.6,-11.6,-15.1,-13.9,-15.6,-10.2,-17.7,-10.8,-17.7,-11.6,-14.7,-10.6,-15.6,-10.20, - -11.2,-11.5,-11.0,-10.0,-13.5,-12.3,-14.00,-8.6,-16.10,-9.2,-16.1,-10.0,-13.10,-9.0,-14.00,-8.60, - -7.10,-7.40,-6.90,-5.90,-9.40,-8.20,-9.90,-4.5,-12.00,-5.1,-12.00,-5.90,-9.00,-4.90,-9.90,-4.50, - -7.10,-7.40,-6.90,-5.90,-9.40,-8.20,-9.90,-4.5,-12.00,-5.1,-12.00,-5.90,-9.00,-4.90,-9.90,-4.50, - -7.90,-8.20,-7.70,-6.7,-10.20,-9.0,-10.70,-5.3,-12.80,-5.9,-12.80,-6.70,-9.80,-5.7,-10.70,-5.30, - -11.1,-11.4,-10.90,-9.9,-13.4,-12.2,-13.90,-8.5,-16.00,-9.1,-16.00,-9.9,-13.00,-8.9,-13.90,-8.50, - -11.4,-11.7,-11.2,-10.2,-13.7,-12.5,-14.20,-8.8,-16.30,-9.4,-16.3,-10.2,-13.30,-9.2,-14.20,-8.80, - -10.2,-10.5,-10.00,-9.0,-12.5,-11.3,-13.00,-7.6,-15.10,-8.2,-15.10,-9.0,-12.10,-8.0,-13.00,-7.60, - -11.4,-11.7,-11.2,-10.2,-13.7,-12.5,-14.20,-8.8,-16.30,-9.4,-16.3,-10.2,-13.30,-9.2,-14.20,-8.80, - -9.00,-9.30,-8.80,-7.8,-11.3,-10.1,-11.80,-6.4,-13.90,-7.0,-13.90,-7.8,-10.90,-6.8,-11.80,-6.40, - -9.00,-9.30,-8.80,-7.8,-11.3,-10.1,-11.80,-6.4,-13.90,-7.0,-13.90,-7.8,-10.90,-6.8,-11.80,-6.40, - -9.00,-9.30,-8.80,-7.8,-11.3,-10.1,-11.80,-6.4,-13.90,-7.0,-13.90,-7.8,-10.90,-6.8,-11.80,-6.40, - -9.7,-10.00,-9.50,-8.5,-12.0,-10.8,-12.50,-7.1,-14.60,-7.7,-14.60,-8.5,-11.60,-7.5,-12.50,-7.10, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ C -// C /\ | G -// 3' <------ 5' - -10.4,-12.4,-12.3,-10.2,-14.00,-8.3,-12.6,-10.2,-10.80,-8.3,-11.4,-10.2,-14.00,-9.1,-12.6,-10.90, - -14.0,-16.0,-15.9,-13.8,-17.6,-11.9,-16.2,-13.8,-14.4,-11.9,-15.0,-13.8,-17.6,-12.7,-16.2,-14.50, - -10.8,-12.8,-12.7,-10.6,-14.40,-8.7,-13.0,-10.6,-11.20,-8.7,-11.8,-10.6,-14.40,-9.5,-13.0,-11.30, - -14.0,-16.0,-15.9,-13.8,-17.6,-11.9,-16.2,-13.8,-14.4,-11.9,-15.0,-13.8,-17.6,-12.7,-16.2,-14.50, - -12.4,-14.4,-14.3,-12.2,-16.0,-10.3,-14.6,-12.2,-12.8,-10.3,-13.4,-12.2,-16.0,-11.1,-14.6,-12.90, - -8.3,-10.3,-10.20,-8.1,-11.90,-6.2,-10.50,-8.10,-8.70,-6.20,-9.30,-8.1,-11.90,-7.0,-10.50,-8.80, - -8.3,-10.3,-10.20,-8.1,-11.90,-6.2,-10.50,-8.10,-8.70,-6.20,-9.30,-8.1,-11.90,-7.0,-10.50,-8.80, - -9.1,-11.1,-11.00,-8.9,-12.70,-7.0,-11.30,-8.90,-9.50,-7.0,-10.10,-8.9,-12.70,-7.8,-11.30,-9.60, - -12.3,-14.3,-14.2,-12.1,-15.9,-10.2,-14.5,-12.1,-12.7,-10.2,-13.3,-12.1,-15.9,-11.0,-14.5,-12.80, - -12.6,-14.6,-14.5,-12.4,-16.2,-10.5,-14.8,-12.4,-13.0,-10.5,-13.6,-12.4,-16.2,-11.3,-14.8,-13.10, - -11.4,-13.4,-13.3,-11.2,-15.00,-9.3,-13.6,-11.2,-11.80,-9.3,-12.4,-11.2,-15.0,-10.1,-13.6,-11.90, - -12.6,-14.6,-14.5,-12.4,-16.2,-10.5,-14.8,-12.4,-13.0,-10.5,-13.6,-12.4,-16.2,-11.3,-14.8,-13.10, - -10.2,-12.2,-12.1,-10.0,-13.80,-8.1,-12.4,-10.0,-10.60,-8.1,-11.2,-10.0,-13.80,-8.9,-12.4,-10.70, - -10.2,-12.2,-12.1,-10.0,-13.80,-8.1,-12.4,-10.0,-10.60,-8.1,-11.2,-10.0,-13.80,-8.9,-12.4,-10.70, - -10.2,-12.2,-12.1,-10.0,-13.80,-8.1,-12.4,-10.0,-10.60,-8.1,-11.2,-10.0,-13.80,-8.9,-12.4,-10.70, - -10.9,-12.9,-12.8,-10.7,-14.50,-8.8,-13.1,-10.7,-11.30,-8.8,-11.9,-10.7,-14.50,-9.6,-13.1,-11.40, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// C /\ | C -// 3' <------ 5' - -4.9,-10.4,-14.6,-13.30, 4.30,-9.7,-14.6,-12.60, 5.1,-10.4,-14.6,-13.3,-15.5,-11.9,-14.6,-13.80, - -8.5,-14.0,-18.2,-16.90, 0.7,-13.3,-18.2,-16.20, 1.5,-14.0,-18.2,-16.9,-19.1,-15.5,-18.2,-17.40, - -5.3,-10.8,-15.0,-13.70, 3.9,-10.1,-15.0,-13.00, 4.7,-10.8,-15.0,-13.7,-15.9,-12.3,-15.0,-14.20, - -8.5,-14.0,-18.2,-16.90, 0.7,-13.3,-18.2,-16.20, 1.5,-14.0,-18.2,-16.9,-19.1,-15.5,-18.2,-17.40, - -6.9,-12.4,-16.6,-15.30, 2.3,-11.7,-16.6,-14.60, 3.1,-12.4,-16.6,-15.3,-17.5,-13.9,-16.6,-15.80, - -2.80,-8.3,-12.5,-11.20, 6.40,-7.6,-12.5,-10.50, 7.20,-8.3,-12.5,-11.2,-13.40,-9.8,-12.5,-11.70, - -2.80,-8.3,-12.5,-11.20, 6.40,-7.6,-12.5,-10.50, 7.20,-8.3,-12.5,-11.2,-13.40,-9.8,-12.5,-11.70, - -3.60,-9.1,-13.3,-12.00, 5.60,-8.4,-13.3,-11.30, 6.40,-9.1,-13.3,-12.0,-14.2,-10.6,-13.3,-12.50, - -6.8,-12.3,-16.5,-15.20, 2.4,-11.6,-16.5,-14.50, 3.2,-12.3,-16.5,-15.2,-17.4,-13.8,-16.5,-15.70, - -7.1,-12.6,-16.8,-15.50, 2.1,-11.9,-16.8,-14.80, 2.9,-12.6,-16.8,-15.5,-17.7,-14.1,-16.8,-16.00, - -5.9,-11.4,-15.6,-14.30, 3.3,-10.7,-15.6,-13.60, 4.1,-11.4,-15.6,-14.3,-16.5,-12.9,-15.6,-14.80, - -7.1,-12.6,-16.8,-15.50, 2.1,-11.9,-16.8,-14.80, 2.9,-12.6,-16.8,-15.5,-17.7,-14.1,-16.8,-16.00, - -4.7,-10.2,-14.4,-13.10, 4.50,-9.5,-14.4,-12.40, 5.3,-10.2,-14.4,-13.1,-15.3,-11.7,-14.4,-13.60, - -4.7,-10.2,-14.4,-13.10, 4.50,-9.5,-14.4,-12.40, 5.3,-10.2,-14.4,-13.1,-15.3,-11.7,-14.4,-13.60, - -4.7,-10.2,-14.4,-13.10, 4.50,-9.5,-14.4,-12.40, 5.3,-10.2,-14.4,-13.1,-15.3,-11.7,-14.4,-13.60, - -5.4,-10.9,-15.1,-13.80, 3.8,-10.2,-15.1,-13.10, 4.6,-10.9,-15.1,-13.8,-16.0,-12.4,-15.1,-14.30, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// C /\ | A -// 3' <------ 5' - -9.50,-7.80,-8.60,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.50, - -13.1,-11.4,-12.2,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.10, - -9.90,-8.20,-9.00,-8.9,-11.60,-8.0,-12.50,-8.9,-11.60,-8.0,-12.50,-8.9,-11.60,-8.0,-12.50,-8.90, - -13.1,-11.4,-12.2,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.10, - -11.50,-9.8,-10.6,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.50, - -7.40,-5.70,-6.50,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40, - -7.40,-5.70,-6.50,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40, - -8.20,-6.50,-7.30,-7.20,-9.90,-6.3,-10.80,-7.20,-9.90,-6.3,-10.80,-7.20,-9.90,-6.3,-10.80,-7.20, - -11.40,-9.7,-10.5,-10.4,-13.10,-9.5,-14.0,-10.4,-13.10,-9.5,-14.0,-10.4,-13.10,-9.5,-14.0,-10.40, - -11.7,-10.0,-10.8,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.70, - -10.50,-8.80,-9.60,-9.5,-12.20,-8.6,-13.10,-9.5,-12.20,-8.6,-13.10,-9.5,-12.20,-8.6,-13.10,-9.50, - -11.7,-10.0,-10.8,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.70, - -9.30,-7.60,-8.40,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.30, - -9.30,-7.60,-8.40,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.30, - -9.30,-7.60,-8.40,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.30, - -10.00,-8.30,-9.10,-9.0,-11.70,-8.1,-12.60,-9.0,-11.70,-8.1,-12.60,-9.0,-11.70,-8.1,-12.60,-9.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// C /\ | U -// 3' <------ 5' - -12.4,-10.0,-11.8,-10.7,-13.1,-10.0,-13.30,-9.6,-14.80,-8.8,-14.4,-10.7,-13.3,-10.0,-13.30,-8.80, - -16.0,-13.6,-15.4,-14.3,-16.7,-13.6,-16.9,-13.2,-18.4,-12.4,-18.0,-14.3,-16.9,-13.6,-16.9,-12.40, - -12.8,-10.4,-12.2,-11.1,-13.5,-10.4,-13.7,-10.0,-15.20,-9.2,-14.8,-11.1,-13.7,-10.4,-13.70,-9.20, - -16.0,-13.6,-15.4,-14.3,-16.7,-13.6,-16.9,-13.2,-18.4,-12.4,-18.0,-14.3,-16.9,-13.6,-16.9,-12.40, - -14.4,-12.0,-13.8,-12.7,-15.1,-12.0,-15.3,-11.6,-16.8,-10.8,-16.4,-12.7,-15.3,-12.0,-15.3,-10.80, - -10.30,-7.90,-9.70,-8.6,-11.00,-7.9,-11.20,-7.5,-12.70,-6.7,-12.30,-8.6,-11.20,-7.9,-11.20,-6.70, - -10.30,-7.90,-9.70,-8.6,-11.00,-7.9,-11.20,-7.5,-12.70,-6.7,-12.30,-8.6,-11.20,-7.9,-11.20,-6.70, - -11.10,-8.7,-10.50,-9.4,-11.80,-8.7,-12.00,-8.3,-13.50,-7.5,-13.10,-9.4,-12.00,-8.7,-12.00,-7.50, - -14.3,-11.9,-13.7,-12.6,-15.0,-11.9,-15.2,-11.5,-16.7,-10.7,-16.3,-12.6,-15.2,-11.9,-15.2,-10.70, - -14.6,-12.2,-14.0,-12.9,-15.3,-12.2,-15.5,-11.8,-17.0,-11.0,-16.6,-12.9,-15.5,-12.2,-15.5,-11.00, - -13.4,-11.0,-12.8,-11.7,-14.1,-11.0,-14.3,-10.6,-15.80,-9.8,-15.4,-11.7,-14.3,-11.0,-14.30,-9.80, - -14.6,-12.2,-14.0,-12.9,-15.3,-12.2,-15.5,-11.8,-17.0,-11.0,-16.6,-12.9,-15.5,-12.2,-15.5,-11.00, - -12.20,-9.8,-11.6,-10.5,-12.90,-9.8,-13.10,-9.4,-14.60,-8.6,-14.2,-10.5,-13.10,-9.8,-13.10,-8.60, - -12.20,-9.8,-11.6,-10.5,-12.90,-9.8,-13.10,-9.4,-14.60,-8.6,-14.2,-10.5,-13.10,-9.8,-13.10,-8.60, - -12.20,-9.8,-11.6,-10.5,-12.90,-9.8,-13.10,-9.4,-14.60,-8.6,-14.2,-10.5,-13.10,-9.8,-13.10,-8.60, - -12.9,-10.5,-12.3,-11.2,-13.6,-10.5,-13.8,-10.1,-15.30,-9.3,-14.9,-11.2,-13.8,-10.5,-13.80,-9.30, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// C /\ | G -// 3' <------ 5' - -9.50,-7.80,-8.60,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.5,-11.20,-7.6,-12.10,-8.50, - -13.1,-11.4,-12.2,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.10, - -9.90,-8.20,-9.00,-8.9,-11.60,-8.0,-12.50,-8.9,-11.60,-8.0,-12.50,-8.9,-11.60,-8.0,-12.50,-8.90, - -13.1,-11.4,-12.2,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.1,-14.8,-11.2,-15.7,-12.10, - -11.50,-9.8,-10.6,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.50, - -7.40,-5.70,-6.50,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40, - -7.40,-5.70,-6.50,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40,-9.10,-5.5,-10.00,-6.40, - -8.20,-6.50,-7.30,-7.20,-9.90,-6.3,-10.80,-7.20,-9.90,-6.3,-10.80,-7.20,-9.90,-6.3,-10.80,-7.20, - -11.40,-9.7,-10.5,-10.4,-13.10,-9.5,-14.0,-10.4,-13.10,-9.5,-14.0,-10.4,-13.10,-9.5,-14.0,-10.40, - -11.7,-10.0,-10.8,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.70, - -10.50,-8.80,-9.60,-9.5,-12.20,-8.6,-13.10,-9.5,-12.20,-8.6,-13.10,-9.5,-12.20,-8.6,-13.10,-9.50, - -11.7,-10.0,-10.8,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.7,-13.40,-9.8,-14.3,-10.70, - -9.30,-7.60,-8.40,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.30, - -9.30,-7.60,-8.40,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.30, - -9.30,-7.60,-8.40,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.3,-11.00,-7.4,-11.90,-8.30, - -10.00,-8.30,-9.10,-9.0,-11.70,-8.1,-12.60,-9.0,-11.70,-8.1,-12.60,-9.0,-11.70,-8.1,-12.60,-9.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ A -// A /\ | U -// 3' <------ 5' - -8.00,-8.30,-7.80,-6.8,-10.30,-9.1,-10.80,-5.4,-12.90,-6.0,-12.90,-6.80,-9.90,-5.8,-10.80,-5.40, - -10.3,-10.6,-10.10,-9.1,-12.6,-11.4,-13.10,-7.7,-15.20,-8.3,-15.20,-9.1,-12.20,-8.1,-13.10,-7.70, - -12.9,-13.2,-12.7,-11.7,-15.2,-14.0,-15.7,-10.3,-17.8,-10.9,-17.8,-11.7,-14.8,-10.7,-15.7,-10.30, - -9.9,-10.20,-9.70,-8.7,-12.2,-11.0,-12.70,-7.3,-14.80,-7.9,-14.80,-8.7,-11.80,-7.7,-12.70,-7.30, - -8.30,-8.60,-8.10,-7.1,-10.60,-9.4,-11.10,-5.7,-13.20,-6.3,-13.20,-7.1,-10.20,-6.1,-11.10,-5.70, - -9.10,-9.40,-8.90,-7.9,-11.4,-10.2,-11.90,-6.5,-14.00,-7.1,-14.00,-7.9,-11.00,-6.9,-11.90,-6.50, - -6.00,-6.30,-5.80,-4.80,-8.30,-7.10,-8.80,-3.4,-10.90,-4.0,-10.90,-4.80,-7.90,-3.80,-8.80,-3.40, - -5.80,-6.10,-5.60,-4.60,-8.10,-6.90,-8.60,-3.2,-10.70,-3.8,-10.70,-4.60,-7.70,-3.60,-8.60,-3.20, - -7.80,-8.10,-7.60,-6.6,-10.10,-8.9,-10.60,-5.2,-12.70,-5.8,-12.70,-6.60,-9.70,-5.6,-10.60,-5.20, - -10.8,-11.1,-10.60,-9.6,-13.1,-11.9,-13.60,-8.2,-15.70,-8.8,-15.70,-9.6,-12.70,-8.6,-13.60,-8.20, - -12.9,-13.2,-12.7,-11.7,-15.2,-14.0,-15.7,-10.3,-17.8,-10.9,-17.8,-11.7,-14.8,-10.7,-15.7,-10.30, - -10.8,-11.1,-10.60,-9.6,-13.1,-11.9,-13.60,-8.2,-15.70,-8.8,-15.70,-9.6,-12.70,-8.6,-13.60,-8.20, - -6.80,-7.10,-6.60,-5.60,-9.10,-7.90,-9.60,-4.2,-11.70,-4.8,-11.70,-5.60,-8.70,-4.60,-9.60,-4.20, - -5.40,-5.70,-5.20,-4.20,-7.70,-6.50,-8.20,-2.8,-10.30,-3.4,-10.30,-4.20,-7.30,-3.20,-8.20,-2.80, - -6.80,-7.10,-6.60,-5.60,-9.10,-7.90,-9.60,-4.2,-11.70,-4.8,-11.70,-5.60,-8.70,-4.60,-9.60,-4.20, - -5.40,-5.70,-5.20,-4.20,-7.70,-6.50,-8.20,-2.8,-10.30,-3.4,-10.30,-4.20,-7.30,-3.20,-8.20,-2.80, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ C -// A /\ | G -// 3' <------ 5' - -9.2,-11.2,-11.10,-9.0,-12.80,-7.1,-11.40,-9.00,-9.60,-7.1,-10.20,-9.0,-12.80,-7.9,-11.40,-9.70, - -11.5,-13.5,-13.4,-11.3,-15.10,-9.4,-13.7,-11.3,-11.90,-9.4,-12.5,-11.3,-15.1,-10.2,-13.7,-12.00, - -14.1,-16.1,-16.0,-13.9,-17.7,-12.0,-16.3,-13.9,-14.5,-12.0,-15.1,-13.9,-17.7,-12.8,-16.3,-14.60, - -11.1,-13.1,-13.0,-10.9,-14.70,-9.0,-13.3,-10.9,-11.50,-9.0,-12.1,-10.9,-14.70,-9.8,-13.3,-11.60, - -9.5,-11.5,-11.40,-9.3,-13.10,-7.4,-11.70,-9.30,-9.90,-7.4,-10.50,-9.3,-13.10,-8.2,-11.7,-10.00, - -10.3,-12.3,-12.2,-10.1,-13.90,-8.2,-12.5,-10.1,-10.70,-8.2,-11.3,-10.1,-13.90,-9.0,-12.5,-10.80, - -7.20,-9.20,-9.10,-7.0,-10.80,-5.10,-9.40,-7.00,-7.60,-5.10,-8.20,-7.0,-10.80,-5.90,-9.40,-7.70, - -7.00,-9.00,-8.90,-6.8,-10.60,-4.90,-9.20,-6.80,-7.40,-4.90,-8.00,-6.8,-10.60,-5.70,-9.20,-7.50, - -9.0,-11.0,-10.90,-8.8,-12.60,-6.9,-11.20,-8.80,-9.40,-6.9,-10.00,-8.8,-12.60,-7.7,-11.20,-9.50, - -12.0,-14.0,-13.9,-11.8,-15.60,-9.9,-14.2,-11.8,-12.40,-9.9,-13.0,-11.8,-15.6,-10.7,-14.2,-12.50, - -14.1,-16.1,-16.0,-13.9,-17.7,-12.0,-16.3,-13.9,-14.5,-12.0,-15.1,-13.9,-17.7,-12.8,-16.3,-14.60, - -12.0,-14.0,-13.9,-11.8,-15.60,-9.9,-14.2,-11.8,-12.40,-9.9,-13.0,-11.8,-15.6,-10.7,-14.2,-12.50, - -8.0,-10.00,-9.90,-7.8,-11.60,-5.9,-10.20,-7.80,-8.40,-5.90,-9.00,-7.8,-11.60,-6.7,-10.20,-8.50, - -6.60,-8.60,-8.50,-6.4,-10.20,-4.50,-8.80,-6.40,-7.00,-4.50,-7.60,-6.4,-10.20,-5.30,-8.80,-7.10, - -8.0,-10.00,-9.90,-7.8,-11.60,-5.9,-10.20,-7.80,-8.40,-5.90,-9.00,-7.8,-11.60,-6.7,-10.20,-8.50, - -6.60,-8.60,-8.50,-6.4,-10.20,-4.50,-8.80,-6.40,-7.00,-4.50,-7.60,-6.4,-10.20,-5.30,-8.80,-7.10, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// A /\ | C -// 3' <------ 5' - -3.70,-9.2,-13.4,-12.10, 5.50,-8.5,-13.4,-11.40, 6.30,-9.2,-13.4,-12.1,-14.3,-10.7,-13.4,-12.60, - -6.0,-11.5,-15.7,-14.40, 3.2,-10.8,-15.7,-13.70, 4.0,-11.5,-15.7,-14.4,-16.6,-13.0,-15.7,-14.90, - -8.6,-14.1,-18.3,-17.00, 0.6,-13.4,-18.3,-16.30, 1.4,-14.1,-18.3,-17.0,-19.2,-15.6,-18.3,-17.50, - -5.6,-11.1,-15.3,-14.00, 3.6,-10.4,-15.3,-13.30, 4.4,-11.1,-15.3,-14.0,-16.2,-12.6,-15.3,-14.50, - -4.00,-9.5,-13.7,-12.40, 5.20,-8.8,-13.7,-11.70, 6.00,-9.5,-13.7,-12.4,-14.6,-11.0,-13.7,-12.90, - -4.8,-10.3,-14.5,-13.20, 4.40,-9.6,-14.5,-12.50, 5.2,-10.3,-14.5,-13.2,-15.4,-11.8,-14.5,-13.70, - -1.70,-7.2,-11.4,-10.10, 7.50,-6.5,-11.40,-9.40, 8.30,-7.2,-11.4,-10.1,-12.30,-8.7,-11.4,-10.60, - -1.50,-7.0,-11.20,-9.90, 7.70,-6.3,-11.20,-9.20, 8.50,-7.0,-11.20,-9.9,-12.10,-8.5,-11.2,-10.40, - -3.50,-9.0,-13.2,-11.90, 5.70,-8.3,-13.2,-11.20, 6.50,-9.0,-13.2,-11.9,-14.1,-10.5,-13.2,-12.40, - -6.5,-12.0,-16.2,-14.90, 2.7,-11.3,-16.2,-14.20, 3.5,-12.0,-16.2,-14.9,-17.1,-13.5,-16.2,-15.40, - -8.6,-14.1,-18.3,-17.00, 0.6,-13.4,-18.3,-16.30, 1.4,-14.1,-18.3,-17.0,-19.2,-15.6,-18.3,-17.50, - -6.5,-12.0,-16.2,-14.90, 2.7,-11.3,-16.2,-14.20, 3.5,-12.0,-16.2,-14.9,-17.1,-13.5,-16.2,-15.40, - -2.50,-8.0,-12.2,-10.90, 6.70,-7.3,-12.2,-10.20, 7.50,-8.0,-12.2,-10.9,-13.10,-9.5,-12.2,-11.40, - -1.10,-6.6,-10.80,-9.50, 8.10,-5.9,-10.80,-8.80, 8.90,-6.6,-10.80,-9.5,-11.70,-8.1,-10.8,-10.00, - -2.50,-8.0,-12.2,-10.90, 6.70,-7.3,-12.2,-10.20, 7.50,-8.0,-12.2,-10.9,-13.10,-9.5,-12.2,-11.40, - -1.10,-6.6,-10.80,-9.50, 8.10,-5.9,-10.80,-8.80, 8.90,-6.6,-10.80,-9.5,-11.70,-8.1,-10.8,-10.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// A /\ | A -// 3' <------ 5' - -8.30,-6.60,-7.40,-7.3,-10.00,-6.4,-10.90,-7.3,-10.00,-6.4,-10.90,-7.3,-10.00,-6.4,-10.90,-7.30, - -10.60,-8.90,-9.70,-9.6,-12.30,-8.7,-13.20,-9.6,-12.30,-8.7,-13.20,-9.6,-12.30,-8.7,-13.20,-9.60, - -13.2,-11.5,-12.3,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.20, - -10.20,-8.50,-9.30,-9.2,-11.90,-8.3,-12.80,-9.2,-11.90,-8.3,-12.80,-9.2,-11.90,-8.3,-12.80,-9.20, - -8.60,-6.90,-7.70,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.60, - -9.40,-7.70,-8.50,-8.4,-11.10,-7.5,-12.00,-8.4,-11.10,-7.5,-12.00,-8.4,-11.10,-7.5,-12.00,-8.40, - -6.30,-4.60,-5.40,-5.30,-8.00,-4.40,-8.90,-5.30,-8.00,-4.40,-8.90,-5.30,-8.00,-4.40,-8.90,-5.30, - -6.10,-4.40,-5.20,-5.10,-7.80,-4.20,-8.70,-5.10,-7.80,-4.20,-8.70,-5.10,-7.80,-4.20,-8.70,-5.10, - -8.10,-6.40,-7.20,-7.10,-9.80,-6.2,-10.70,-7.10,-9.80,-6.2,-10.70,-7.10,-9.80,-6.2,-10.70,-7.10, - -11.10,-9.4,-10.2,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.10, - -13.2,-11.5,-12.3,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.20, - -11.10,-9.4,-10.2,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.10, - -7.10,-5.40,-6.20,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10, - -5.70,-4.00,-4.80,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70, - -7.10,-5.40,-6.20,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10, - -5.70,-4.00,-4.80,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// A /\ | U -// 3' <------ 5' - -11.20,-8.8,-10.60,-9.5,-11.90,-8.8,-12.10,-8.4,-13.60,-7.6,-13.20,-9.5,-12.10,-8.8,-12.10,-7.60, - -13.5,-11.1,-12.9,-11.8,-14.2,-11.1,-14.4,-10.7,-15.90,-9.9,-15.5,-11.8,-14.4,-11.1,-14.40,-9.90, - -16.1,-13.7,-15.5,-14.4,-16.8,-13.7,-17.0,-13.3,-18.5,-12.5,-18.1,-14.4,-17.0,-13.7,-17.0,-12.50, - -13.1,-10.7,-12.5,-11.4,-13.8,-10.7,-14.0,-10.3,-15.50,-9.5,-15.1,-11.4,-14.0,-10.7,-14.00,-9.50, - -11.50,-9.1,-10.90,-9.8,-12.20,-9.1,-12.40,-8.7,-13.90,-7.9,-13.50,-9.8,-12.40,-9.1,-12.40,-7.90, - -12.30,-9.9,-11.7,-10.6,-13.00,-9.9,-13.20,-9.5,-14.70,-8.7,-14.3,-10.6,-13.20,-9.9,-13.20,-8.70, - -9.20,-6.80,-8.60,-7.50,-9.90,-6.8,-10.10,-6.4,-11.60,-5.6,-11.20,-7.5,-10.10,-6.8,-10.10,-5.60, - -9.00,-6.60,-8.40,-7.30,-9.70,-6.60,-9.90,-6.2,-11.40,-5.4,-11.00,-7.30,-9.90,-6.60,-9.90,-5.40, - -11.00,-8.6,-10.40,-9.3,-11.70,-8.6,-11.90,-8.2,-13.40,-7.4,-13.00,-9.3,-11.90,-8.6,-11.90,-7.40, - -14.0,-11.6,-13.4,-12.3,-14.7,-11.6,-14.9,-11.2,-16.4,-10.4,-16.0,-12.3,-14.9,-11.6,-14.9,-10.40, - -16.1,-13.7,-15.5,-14.4,-16.8,-13.7,-17.0,-13.3,-18.5,-12.5,-18.1,-14.4,-17.0,-13.7,-17.0,-12.50, - -14.0,-11.6,-13.4,-12.3,-14.7,-11.6,-14.9,-11.2,-16.4,-10.4,-16.0,-12.3,-14.9,-11.6,-14.9,-10.40, - -10.00,-7.60,-9.40,-8.3,-10.70,-7.6,-10.90,-7.2,-12.40,-6.4,-12.00,-8.3,-10.90,-7.6,-10.90,-6.40, - -8.60,-6.20,-8.00,-6.90,-9.30,-6.20,-9.50,-5.8,-11.00,-5.0,-10.60,-6.90,-9.50,-6.20,-9.50,-5.00, - -10.00,-7.60,-9.40,-8.3,-10.70,-7.6,-10.90,-7.2,-12.40,-6.4,-12.00,-8.3,-10.90,-7.6,-10.90,-6.40, - -8.60,-6.20,-8.00,-6.90,-9.30,-6.20,-9.50,-5.8,-11.00,-5.0,-10.60,-6.90,-9.50,-6.20,-9.50,-5.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// A /\ | G -// 3' <------ 5' - -8.30,-6.60,-7.40,-7.3,-10.00,-6.4,-10.90,-7.3,-10.00,-6.4,-10.90,-7.3,-10.00,-6.4,-10.90,-7.30, - -10.60,-8.90,-9.70,-9.6,-12.30,-8.7,-13.20,-9.6,-12.30,-8.7,-13.20,-9.6,-12.30,-8.7,-13.20,-9.60, - -13.2,-11.5,-12.3,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.20, - -10.20,-8.50,-9.30,-9.2,-11.90,-8.3,-12.80,-9.2,-11.90,-8.3,-12.80,-9.2,-11.90,-8.3,-12.80,-9.20, - -8.60,-6.90,-7.70,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.60, - -9.40,-7.70,-8.50,-8.4,-11.10,-7.5,-12.00,-8.4,-11.10,-7.5,-12.00,-8.4,-11.10,-7.5,-12.00,-8.40, - -6.30,-4.60,-5.40,-5.30,-8.00,-4.40,-8.90,-5.30,-8.00,-4.40,-8.90,-5.30,-8.00,-4.40,-8.90,-5.30, - -6.10,-4.40,-5.20,-5.10,-7.80,-4.20,-8.70,-5.10,-7.80,-4.20,-8.70,-5.10,-7.80,-4.20,-8.70,-5.10, - -8.10,-6.40,-7.20,-7.10,-9.80,-6.2,-10.70,-7.10,-9.80,-6.2,-10.70,-7.10,-9.80,-6.2,-10.70,-7.10, - -11.10,-9.4,-10.2,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.10, - -13.2,-11.5,-12.3,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.2,-14.9,-11.3,-15.8,-12.20, - -11.10,-9.4,-10.2,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.1,-12.80,-9.2,-13.7,-10.10, - -7.10,-5.40,-6.20,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10, - -5.70,-4.00,-4.80,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70, - -7.10,-5.40,-6.20,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10,-8.80,-5.20,-9.70,-6.10, - -5.70,-4.00,-4.80,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70,-7.40,-3.80,-8.30,-4.70, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ A -// U /\ | U -// 3' <------ 5' - -8.30,-8.60,-8.10,-7.1,-10.60,-9.4,-11.10,-5.7,-13.20,-6.3,-13.20,-7.1,-10.20,-6.1,-11.10,-5.70, - -10.0,-10.30,-9.80,-8.8,-12.3,-11.1,-12.80,-7.4,-14.90,-8.0,-14.90,-8.8,-11.90,-7.8,-12.80,-7.40, - -10.0,-10.30,-9.80,-8.8,-12.3,-11.1,-12.80,-7.4,-14.90,-8.0,-14.90,-8.8,-11.90,-7.8,-12.80,-7.40, - -10.0,-10.30,-9.80,-8.8,-12.3,-11.1,-12.80,-7.4,-14.90,-8.0,-14.90,-8.8,-11.90,-7.8,-12.80,-7.40, - -6.60,-6.90,-6.40,-5.40,-8.90,-7.70,-9.40,-4.0,-11.50,-4.6,-11.50,-5.40,-8.50,-4.40,-9.40,-4.00, - -6.40,-6.70,-6.20,-5.20,-8.70,-7.50,-9.20,-3.8,-11.30,-4.4,-11.30,-5.20,-8.30,-4.20,-9.20,-3.80, - -6.40,-6.70,-6.20,-5.20,-8.70,-7.50,-9.20,-3.8,-11.30,-4.4,-11.30,-5.20,-8.30,-4.20,-9.20,-3.80, - -6.40,-6.70,-6.20,-5.20,-8.70,-7.50,-9.20,-3.8,-11.30,-4.4,-11.30,-5.20,-8.30,-4.20,-9.20,-3.80, - -7.40,-7.70,-7.20,-6.20,-9.70,-8.5,-10.20,-4.8,-12.30,-5.4,-12.30,-6.20,-9.30,-5.2,-10.20,-4.80, - -10.9,-11.2,-10.70,-9.7,-13.2,-12.0,-13.70,-8.3,-15.80,-8.9,-15.80,-9.7,-12.80,-8.7,-13.70,-8.30, - -10.9,-11.2,-10.70,-9.7,-13.2,-12.0,-13.70,-8.3,-15.80,-8.9,-15.80,-9.7,-12.80,-8.7,-13.70,-8.30, - -10.9,-11.2,-10.70,-9.7,-13.2,-12.0,-13.70,-8.3,-15.80,-8.9,-15.80,-9.7,-12.80,-8.7,-13.70,-8.30, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, - -7.30,-7.60,-7.10,-6.10,-9.60,-8.4,-10.10,-4.7,-12.20,-5.3,-12.20,-6.10,-9.20,-5.1,-10.10,-4.70, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ C -// U /\ | G -// 3' <------ 5' - -9.5,-11.5,-11.40,-9.3,-13.10,-7.4,-11.70,-9.30,-9.90,-7.4,-10.50,-9.3,-13.10,-8.2,-11.7,-10.00, - -11.2,-13.2,-13.1,-11.0,-14.80,-9.1,-13.4,-11.0,-11.60,-9.1,-12.2,-11.0,-14.80,-9.9,-13.4,-11.70, - -11.2,-13.2,-13.1,-11.0,-14.80,-9.1,-13.4,-11.0,-11.60,-9.1,-12.2,-11.0,-14.80,-9.9,-13.4,-11.70, - -11.2,-13.2,-13.1,-11.0,-14.80,-9.1,-13.4,-11.0,-11.60,-9.1,-12.2,-11.0,-14.80,-9.9,-13.4,-11.70, - -7.80,-9.80,-9.70,-7.6,-11.40,-5.7,-10.00,-7.60,-8.20,-5.70,-8.80,-7.6,-11.40,-6.5,-10.00,-8.30, - -7.60,-9.60,-9.50,-7.4,-11.20,-5.50,-9.80,-7.40,-8.00,-5.50,-8.60,-7.4,-11.20,-6.30,-9.80,-8.10, - -7.60,-9.60,-9.50,-7.4,-11.20,-5.50,-9.80,-7.40,-8.00,-5.50,-8.60,-7.4,-11.20,-6.30,-9.80,-8.10, - -7.60,-9.60,-9.50,-7.4,-11.20,-5.50,-9.80,-7.40,-8.00,-5.50,-8.60,-7.4,-11.20,-6.30,-9.80,-8.10, - -8.6,-10.6,-10.50,-8.4,-12.20,-6.5,-10.80,-8.40,-9.00,-6.50,-9.60,-8.4,-12.20,-7.3,-10.80,-9.10, - -12.1,-14.1,-14.0,-11.9,-15.7,-10.0,-14.3,-11.9,-12.5,-10.0,-13.1,-11.9,-15.7,-10.8,-14.3,-12.60, - -12.1,-14.1,-14.0,-11.9,-15.7,-10.0,-14.3,-11.9,-12.5,-10.0,-13.1,-11.9,-15.7,-10.8,-14.3,-12.60, - -12.1,-14.1,-14.0,-11.9,-15.7,-10.0,-14.3,-11.9,-12.5,-10.0,-13.1,-11.9,-15.7,-10.8,-14.3,-12.60, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, - -8.5,-10.5,-10.40,-8.3,-12.10,-6.4,-10.70,-8.30,-8.90,-6.40,-9.50,-8.3,-12.10,-7.2,-10.70,-9.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// U /\ | C -// 3' <------ 5' - -4.00,-9.5,-13.7,-12.40, 5.20,-8.8,-13.7,-11.70, 6.00,-9.5,-13.7,-12.4,-14.6,-11.0,-13.7,-12.90, - -5.7,-11.2,-15.4,-14.10, 3.5,-10.5,-15.4,-13.40, 4.3,-11.2,-15.4,-14.1,-16.3,-12.7,-15.4,-14.60, - -5.7,-11.2,-15.4,-14.10, 3.5,-10.5,-15.4,-13.40, 4.3,-11.2,-15.4,-14.1,-16.3,-12.7,-15.4,-14.60, - -5.7,-11.2,-15.4,-14.10, 3.5,-10.5,-15.4,-13.40, 4.3,-11.2,-15.4,-14.1,-16.3,-12.7,-15.4,-14.60, - -2.30,-7.8,-12.0,-10.70, 6.90,-7.1,-12.0,-10.00, 7.70,-7.8,-12.0,-10.7,-12.90,-9.3,-12.0,-11.20, - -2.10,-7.6,-11.8,-10.50, 7.10,-6.9,-11.80,-9.80, 7.90,-7.6,-11.8,-10.5,-12.70,-9.1,-11.8,-11.00, - -2.10,-7.6,-11.8,-10.50, 7.10,-6.9,-11.80,-9.80, 7.90,-7.6,-11.8,-10.5,-12.70,-9.1,-11.8,-11.00, - -2.10,-7.6,-11.8,-10.50, 7.10,-6.9,-11.80,-9.80, 7.90,-7.6,-11.8,-10.5,-12.70,-9.1,-11.8,-11.00, - -3.10,-8.6,-12.8,-11.50, 6.10,-7.9,-12.8,-10.80, 6.90,-8.6,-12.8,-11.5,-13.7,-10.1,-12.8,-12.00, - -6.6,-12.1,-16.3,-15.00, 2.6,-11.4,-16.3,-14.30, 3.4,-12.1,-16.3,-15.0,-17.2,-13.6,-16.3,-15.50, - -6.6,-12.1,-16.3,-15.00, 2.6,-11.4,-16.3,-14.30, 3.4,-12.1,-16.3,-15.0,-17.2,-13.6,-16.3,-15.50, - -6.6,-12.1,-16.3,-15.00, 2.6,-11.4,-16.3,-14.30, 3.4,-12.1,-16.3,-15.0,-17.2,-13.6,-16.3,-15.50, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, - -3.00,-8.5,-12.7,-11.40, 6.20,-7.8,-12.7,-10.70, 7.00,-8.5,-12.7,-11.4,-13.6,-10.0,-12.7,-11.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// U /\ | A -// 3' <------ 5' - -8.60,-6.90,-7.70,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.60, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -6.90,-5.20,-6.00,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -7.70,-6.00,-6.80,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ G -// U /\ | U -// 3' <------ 5' - -11.50,-9.1,-10.90,-9.8,-12.20,-9.1,-12.40,-8.7,-13.90,-7.9,-13.50,-9.8,-12.40,-9.1,-12.40,-7.90, - -13.2,-10.8,-12.6,-11.5,-13.9,-10.8,-14.1,-10.4,-15.60,-9.6,-15.2,-11.5,-14.1,-10.8,-14.10,-9.60, - -13.2,-10.8,-12.6,-11.5,-13.9,-10.8,-14.1,-10.4,-15.60,-9.6,-15.2,-11.5,-14.1,-10.8,-14.10,-9.60, - -13.2,-10.8,-12.6,-11.5,-13.9,-10.8,-14.1,-10.4,-15.60,-9.6,-15.2,-11.5,-14.1,-10.8,-14.10,-9.60, - -9.80,-7.40,-9.20,-8.1,-10.50,-7.4,-10.70,-7.0,-12.20,-6.2,-11.80,-8.1,-10.70,-7.4,-10.70,-6.20, - -9.60,-7.20,-9.00,-7.9,-10.30,-7.2,-10.50,-6.8,-12.00,-6.0,-11.60,-7.9,-10.50,-7.2,-10.50,-6.00, - -9.60,-7.20,-9.00,-7.9,-10.30,-7.2,-10.50,-6.8,-12.00,-6.0,-11.60,-7.9,-10.50,-7.2,-10.50,-6.00, - -9.60,-7.20,-9.00,-7.9,-10.30,-7.2,-10.50,-6.8,-12.00,-6.0,-11.60,-7.9,-10.50,-7.2,-10.50,-6.00, - -10.60,-8.2,-10.00,-8.9,-11.30,-8.2,-11.50,-7.8,-13.00,-7.0,-12.60,-8.9,-11.50,-8.2,-11.50,-7.00, - -14.1,-11.7,-13.5,-12.4,-14.8,-11.7,-15.0,-11.3,-16.5,-10.5,-16.1,-12.4,-15.0,-11.7,-15.0,-10.50, - -14.1,-11.7,-13.5,-12.4,-14.8,-11.7,-15.0,-11.3,-16.5,-10.5,-16.1,-12.4,-15.0,-11.7,-15.0,-10.50, - -14.1,-11.7,-13.5,-12.4,-14.8,-11.7,-15.0,-11.3,-16.5,-10.5,-16.1,-12.4,-15.0,-11.7,-15.0,-10.50, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, - -10.50,-8.10,-9.90,-8.8,-11.20,-8.1,-11.40,-7.7,-12.90,-6.9,-12.50,-8.8,-11.40,-8.1,-11.40,-6.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// G \/ \_/ U -// U /\ | G -// 3' <------ 5' - -8.60,-6.90,-7.70,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.6,-10.30,-6.7,-11.20,-7.60, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -10.30,-8.60,-9.40,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.3,-12.00,-8.4,-12.90,-9.30, - -6.90,-5.20,-6.00,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90,-8.60,-5.00,-9.50,-5.90, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -6.70,-5.00,-5.80,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70,-8.40,-4.80,-9.30,-5.70, - -7.70,-6.00,-6.80,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70,-9.40,-5.8,-10.30,-6.70, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -11.20,-9.5,-10.3,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.2,-12.90,-9.3,-13.8,-10.20, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, - -7.60,-5.90,-6.70,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60,-9.30,-5.7,-10.20,-6.60, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ A -// G /\ | U -// 3' <------ 5' - -11.2,-11.5,-11.0,-10.0,-13.5,-12.3,-14.00,-8.6,-16.10,-9.2,-16.1,-10.0,-13.10,-9.0,-14.00,-8.60, - -11.9,-12.2,-11.7,-10.7,-14.2,-13.0,-14.70,-9.3,-16.80,-9.9,-16.8,-10.7,-13.80,-9.7,-14.70,-9.30, - -13.6,-13.9,-13.4,-12.4,-15.9,-14.7,-16.4,-11.0,-18.5,-11.6,-18.5,-12.4,-15.5,-11.4,-16.4,-11.00, - -12.1,-12.4,-11.9,-10.9,-14.4,-13.2,-14.90,-9.5,-17.0,-10.1,-17.0,-10.9,-14.00,-9.9,-14.90,-9.50, - -8.80,-9.10,-8.60,-7.6,-11.10,-9.9,-11.60,-6.2,-13.70,-6.8,-13.70,-7.6,-10.70,-6.6,-11.60,-6.20, - -8.80,-9.10,-8.60,-7.6,-11.10,-9.9,-11.60,-6.2,-13.70,-6.8,-13.70,-7.6,-10.70,-6.6,-11.60,-6.20, - -7.60,-7.90,-7.40,-6.40,-9.90,-8.7,-10.40,-5.0,-12.50,-5.6,-12.50,-6.40,-9.50,-5.4,-10.40,-5.00, - -8.80,-9.10,-8.60,-7.6,-11.10,-9.9,-11.60,-6.2,-13.70,-6.8,-13.70,-7.6,-10.70,-6.6,-11.60,-6.20, - -10.6,-10.9,-10.40,-9.4,-12.9,-11.7,-13.40,-8.0,-15.50,-8.6,-15.50,-9.4,-12.50,-8.4,-13.40,-8.00, - -12.1,-12.4,-11.9,-10.9,-14.4,-13.2,-14.90,-9.5,-17.0,-10.1,-17.0,-10.9,-14.00,-9.9,-14.90,-9.50, - -13.2,-13.5,-13.0,-12.0,-15.5,-14.3,-16.0,-10.6,-18.1,-11.2,-18.1,-12.0,-15.1,-11.0,-16.0,-10.60, - -12.1,-12.4,-11.9,-10.9,-14.4,-13.2,-14.90,-9.5,-17.0,-10.1,-17.0,-10.9,-14.00,-9.9,-14.90,-9.50, - -9.50,-9.80,-9.30,-8.3,-11.8,-10.6,-12.30,-6.9,-14.40,-7.5,-14.40,-8.3,-11.40,-7.3,-12.30,-6.90, - -8.40,-8.70,-8.20,-7.2,-10.70,-9.5,-11.20,-5.8,-13.30,-6.4,-13.30,-7.2,-10.30,-6.2,-11.20,-5.80, - -9.50,-9.80,-9.30,-8.3,-11.8,-10.6,-12.30,-6.9,-14.40,-7.5,-14.40,-8.3,-11.40,-7.3,-12.30,-6.90, - -7.60,-7.90,-7.40,-6.40,-9.90,-8.7,-10.40,-5.0,-12.50,-5.6,-12.50,-6.40,-9.50,-5.4,-10.40,-5.00, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ C -// G /\ | G -// 3' <------ 5' - -12.4,-14.4,-14.3,-12.2,-16.0,-10.3,-14.6,-12.2,-12.8,-10.3,-13.4,-12.2,-16.0,-11.1,-14.6,-12.90, - -13.1,-15.1,-15.0,-12.9,-16.7,-11.0,-15.3,-12.9,-13.5,-11.0,-14.1,-12.9,-16.7,-11.8,-15.3,-13.60, - -14.8,-16.8,-16.7,-14.6,-18.4,-12.7,-17.0,-14.6,-15.2,-12.7,-15.8,-14.6,-18.4,-13.5,-17.0,-15.30, - -13.3,-15.3,-15.2,-13.1,-16.9,-11.2,-15.5,-13.1,-13.7,-11.2,-14.3,-13.1,-16.9,-12.0,-15.5,-13.80, - -10.0,-12.0,-11.90,-9.8,-13.60,-7.9,-12.20,-9.8,-10.40,-7.9,-11.00,-9.8,-13.60,-8.7,-12.2,-10.50, - -10.0,-12.0,-11.90,-9.8,-13.60,-7.9,-12.20,-9.8,-10.40,-7.9,-11.00,-9.8,-13.60,-8.7,-12.2,-10.50, - -8.8,-10.8,-10.70,-8.6,-12.40,-6.7,-11.00,-8.60,-9.20,-6.70,-9.80,-8.6,-12.40,-7.5,-11.00,-9.30, - -10.0,-12.0,-11.90,-9.8,-13.60,-7.9,-12.20,-9.8,-10.40,-7.9,-11.00,-9.8,-13.60,-8.7,-12.2,-10.50, - -11.8,-13.8,-13.7,-11.6,-15.40,-9.7,-14.0,-11.6,-12.20,-9.7,-12.8,-11.6,-15.4,-10.5,-14.0,-12.30, - -13.3,-15.3,-15.2,-13.1,-16.9,-11.2,-15.5,-13.1,-13.7,-11.2,-14.3,-13.1,-16.9,-12.0,-15.5,-13.80, - -14.4,-16.4,-16.3,-14.2,-18.0,-12.3,-16.6,-14.2,-14.8,-12.3,-15.4,-14.2,-18.0,-13.1,-16.6,-14.90, - -13.3,-15.3,-15.2,-13.1,-16.9,-11.2,-15.5,-13.1,-13.7,-11.2,-14.3,-13.1,-16.9,-12.0,-15.5,-13.80, - -10.7,-12.7,-12.6,-10.5,-14.30,-8.6,-12.9,-10.5,-11.10,-8.6,-11.7,-10.5,-14.30,-9.4,-12.9,-11.20, - -9.6,-11.6,-11.50,-9.4,-13.20,-7.5,-11.80,-9.4,-10.00,-7.5,-10.60,-9.4,-13.20,-8.3,-11.8,-10.10, - -10.7,-12.7,-12.6,-10.5,-14.30,-8.6,-12.9,-10.5,-11.10,-8.6,-11.7,-10.5,-14.30,-9.4,-12.9,-11.20, - -8.8,-10.8,-10.70,-8.6,-12.40,-6.7,-11.00,-8.60,-9.20,-6.70,-9.80,-8.6,-12.40,-7.5,-11.00,-9.30, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// G /\ | C -// 3' <------ 5' - -6.9,-12.4,-16.6,-15.30, 2.3,-11.7,-16.6,-14.60, 3.1,-12.4,-16.6,-15.3,-17.5,-13.9,-16.6,-15.80, - -7.6,-13.1,-17.3,-16.00, 1.6,-12.4,-17.3,-15.30, 2.4,-13.1,-17.3,-16.0,-18.2,-14.6,-17.3,-16.50, - -9.3,-14.8,-19.0,-17.70,-0.1,-14.1,-19.0,-17.00, 0.7,-14.8,-19.0,-17.7,-19.9,-16.3,-19.0,-18.20, - -7.8,-13.3,-17.5,-16.20, 1.4,-12.6,-17.5,-15.50, 2.2,-13.3,-17.5,-16.2,-18.4,-14.8,-17.5,-16.70, - -4.5,-10.0,-14.2,-12.90, 4.70,-9.3,-14.2,-12.20, 5.5,-10.0,-14.2,-12.9,-15.1,-11.5,-14.2,-13.40, - -4.5,-10.0,-14.2,-12.90, 4.70,-9.3,-14.2,-12.20, 5.5,-10.0,-14.2,-12.9,-15.1,-11.5,-14.2,-13.40, - -3.30,-8.8,-13.0,-11.70, 5.90,-8.1,-13.0,-11.00, 6.70,-8.8,-13.0,-11.7,-13.9,-10.3,-13.0,-12.20, - -4.5,-10.0,-14.2,-12.90, 4.70,-9.3,-14.2,-12.20, 5.5,-10.0,-14.2,-12.9,-15.1,-11.5,-14.2,-13.40, - -6.3,-11.8,-16.0,-14.70, 2.9,-11.1,-16.0,-14.00, 3.7,-11.8,-16.0,-14.7,-16.9,-13.3,-16.0,-15.20, - -7.8,-13.3,-17.5,-16.20, 1.4,-12.6,-17.5,-15.50, 2.2,-13.3,-17.5,-16.2,-18.4,-14.8,-17.5,-16.70, - -8.9,-14.4,-18.6,-17.30, 0.3,-13.7,-18.6,-16.60, 1.1,-14.4,-18.6,-17.3,-19.5,-15.9,-18.6,-17.80, - -7.8,-13.3,-17.5,-16.20, 1.4,-12.6,-17.5,-15.50, 2.2,-13.3,-17.5,-16.2,-18.4,-14.8,-17.5,-16.70, - -5.2,-10.7,-14.9,-13.60, 4.0,-10.0,-14.9,-12.90, 4.8,-10.7,-14.9,-13.6,-15.8,-12.2,-14.9,-14.10, - -4.10,-9.6,-13.8,-12.50, 5.10,-8.9,-13.8,-11.80, 5.90,-9.6,-13.8,-12.5,-14.7,-11.1,-13.8,-13.00, - -5.2,-10.7,-14.9,-13.60, 4.0,-10.0,-14.9,-12.90, 4.8,-10.7,-14.9,-13.6,-15.8,-12.2,-14.9,-14.10, - -3.30,-8.8,-13.0,-11.70, 5.90,-8.1,-13.0,-11.00, 6.70,-8.8,-13.0,-11.7,-13.9,-10.3,-13.0,-12.20, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// G /\ | A -// 3' <------ 5' - -11.50,-9.8,-10.6,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.50, - -12.2,-10.5,-11.3,-11.2,-13.9,-10.3,-14.8,-11.2,-13.9,-10.3,-14.8,-11.2,-13.9,-10.3,-14.8,-11.20, - -13.9,-12.2,-13.0,-12.9,-15.6,-12.0,-16.5,-12.9,-15.6,-12.0,-16.5,-12.9,-15.6,-12.0,-16.5,-12.90, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -9.10,-7.40,-8.20,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.10, - -9.10,-7.40,-8.20,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.10, - -7.90,-6.20,-7.00,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90, - -9.10,-7.40,-8.20,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.10, - -10.90,-9.2,-10.00,-9.9,-12.60,-9.0,-13.50,-9.9,-12.60,-9.0,-13.50,-9.9,-12.60,-9.0,-13.50,-9.90, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -13.5,-11.8,-12.6,-12.5,-15.2,-11.6,-16.1,-12.5,-15.2,-11.6,-16.1,-12.5,-15.2,-11.6,-16.1,-12.50, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -9.80,-8.10,-8.90,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.80, - -8.70,-7.00,-7.80,-7.7,-10.40,-6.8,-11.30,-7.7,-10.40,-6.8,-11.30,-7.7,-10.40,-6.8,-11.30,-7.70, - -9.80,-8.10,-8.90,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.80, - -7.90,-6.20,-7.00,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ G -// G /\ | U -// 3' <------ 5' - -14.4,-12.0,-13.8,-12.7,-15.1,-12.0,-15.3,-11.6,-16.8,-10.8,-16.4,-12.7,-15.3,-12.0,-15.3,-10.80, - -15.1,-12.7,-14.5,-13.4,-15.8,-12.7,-16.0,-12.3,-17.5,-11.5,-17.1,-13.4,-16.0,-12.7,-16.0,-11.50, - -16.8,-14.4,-16.2,-15.1,-17.5,-14.4,-17.7,-14.0,-19.2,-13.2,-18.8,-15.1,-17.7,-14.4,-17.7,-13.20, - -15.3,-12.9,-14.7,-13.6,-16.0,-12.9,-16.2,-12.5,-17.7,-11.7,-17.3,-13.6,-16.2,-12.9,-16.2,-11.70, - -12.00,-9.6,-11.4,-10.3,-12.70,-9.6,-12.90,-9.2,-14.40,-8.4,-14.0,-10.3,-12.90,-9.6,-12.90,-8.40, - -12.00,-9.6,-11.4,-10.3,-12.70,-9.6,-12.90,-9.2,-14.40,-8.4,-14.0,-10.3,-12.90,-9.6,-12.90,-8.40, - -10.80,-8.4,-10.20,-9.1,-11.50,-8.4,-11.70,-8.0,-13.20,-7.2,-12.80,-9.1,-11.70,-8.4,-11.70,-7.20, - -12.00,-9.6,-11.4,-10.3,-12.70,-9.6,-12.90,-9.2,-14.40,-8.4,-14.0,-10.3,-12.90,-9.6,-12.90,-8.40, - -13.8,-11.4,-13.2,-12.1,-14.5,-11.4,-14.7,-11.0,-16.2,-10.2,-15.8,-12.1,-14.7,-11.4,-14.7,-10.20, - -15.3,-12.9,-14.7,-13.6,-16.0,-12.9,-16.2,-12.5,-17.7,-11.7,-17.3,-13.6,-16.2,-12.9,-16.2,-11.70, - -16.4,-14.0,-15.8,-14.7,-17.1,-14.0,-17.3,-13.6,-18.8,-12.8,-18.4,-14.7,-17.3,-14.0,-17.3,-12.80, - -15.3,-12.9,-14.7,-13.6,-16.0,-12.9,-16.2,-12.5,-17.7,-11.7,-17.3,-13.6,-16.2,-12.9,-16.2,-11.70, - -12.7,-10.3,-12.1,-11.0,-13.4,-10.3,-13.60,-9.9,-15.10,-9.1,-14.7,-11.0,-13.6,-10.3,-13.60,-9.10, - -11.60,-9.2,-11.00,-9.9,-12.30,-9.2,-12.50,-8.8,-14.00,-8.0,-13.60,-9.9,-12.50,-9.2,-12.50,-8.00, - -12.7,-10.3,-12.1,-11.0,-13.4,-10.3,-13.60,-9.9,-15.10,-9.1,-14.7,-11.0,-13.6,-10.3,-13.60,-9.10, - -10.80,-8.4,-10.20,-9.1,-11.50,-8.4,-11.70,-8.0,-13.20,-7.2,-12.80,-9.1,-11.70,-8.4,-11.70,-7.20, -// -// Y -// --------------------------------------------------------------------------------------------- -// A A A A C C C C G G G G U U U U -// A C G U A C G U A C G U A C G U -// --------------------------------------------------------------------------------------------- -// 5' ------> 3' -// U \/ \_/ U -// G /\ | G -// 3' <------ 5' - -11.50,-9.8,-10.6,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.5,-13.20,-9.6,-14.1,-10.50, - -12.2,-10.5,-11.3,-11.2,-13.9,-10.3,-14.8,-11.2,-13.9,-10.3,-14.8,-11.2,-13.9,-10.3,-14.8,-11.20, - -13.9,-12.2,-13.0,-12.9,-15.6,-12.0,-16.5,-12.9,-15.6,-12.0,-16.5,-12.9,-15.6,-12.0,-16.5,-12.90, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -9.10,-7.40,-8.20,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.10, - -9.10,-7.40,-8.20,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.10, - -7.90,-6.20,-7.00,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90, - -9.10,-7.40,-8.20,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.1,-10.80,-7.2,-11.70,-8.10, - -10.90,-9.2,-10.00,-9.9,-12.60,-9.0,-13.50,-9.9,-12.60,-9.0,-13.50,-9.9,-12.60,-9.0,-13.50,-9.90, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -13.5,-11.8,-12.6,-12.5,-15.2,-11.6,-16.1,-12.5,-15.2,-11.6,-16.1,-12.5,-15.2,-11.6,-16.1,-12.50, - -12.4,-10.7,-11.5,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.4,-14.1,-10.5,-15.0,-11.40, - -9.80,-8.10,-8.90,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.80, - -8.70,-7.00,-7.80,-7.7,-10.40,-6.8,-11.30,-7.7,-10.40,-6.8,-11.30,-7.7,-10.40,-6.8,-11.30,-7.70, - -9.80,-8.10,-8.90,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.8,-11.50,-7.9,-12.40,-8.80, - -7.90,-6.20,-7.00,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90,-9.60,-6.0,-10.50,-6.90 -}; diff --git a/src/data/loop_destabilizing_energies.dat b/src/data/loop_destabilizing_energies.dat deleted file mode 100644 index 826dd295..00000000 --- a/src/data/loop_destabilizing_energies.dat +++ /dev/null @@ -1,39 +0,0 @@ -// Loop destabilizing energies from Vienna Package 1.7 -// DESTABILIZING ENERGIES BY SIZE OF LOOP (INTERPOLATE WHERE NEEDED) -// hp3 ave calc no tmm;hp4 ave calc with tmm; ave all bulges - -double loop_destabilizing_energies[] = -{ -// INTERNAL BULGE HAIRPIN SIZE -//------------------------------------------------------- - 0.0, 3.80, 0.0, // 1 - 0.0, 2.80, 0.0, // 2 - 0.0, 3.20, 5.70, // 3 - 1.70, 3.60, 5.60, // 4 - 1.80, 4.00, 5.60, // 5 - 2.00, 4.40, 5.40, // 6 - 2.20, 4.59, 5.90, // 7 - 2.30, 4.70, 5.60, // 8 - 2.40, 4.80, 6.40, // 9 - 2.50, 4.90, 6.50, // 10 - 2.60, 5.00, 6.60, // 11 - 2.70, 5.10, 6.70, // 12 - 2.78, 5.19, 6.78, // 13 - 2.86, 5.27, 6.86, // 14 - 2.94, 5.34, 6.94, // 15 - 3.01, 5.41, 7.01, // 16 - 3.07, 5.48, 7.07, // 17 - 3.13, 5.54, 7.13, // 18 - 3.19, 5.60, 7.19, // 19 - 3.25, 5.65, 7.25, // 20 - 3.30, 5.71, 7.30, // 21 - 3.35, 5.76, 7.35, // 22 - 3.40, 5.80, 7.40, // 23 - 3.45, 5.85, 7.44, // 24 - 3.49, 5.89, 7.49, // 25 - 3.53, 5.94, 7.53, // 26 - 3.57, 5.98, 7.57, // 27 - 3.61, 6.02, 7.61, // 28 - 3.65, 6.05, 7.65, // 29 - 3.69, 6.09, 7.69 // 30 -}; diff --git a/src/data/loop_destabilizing_energies.zuker.dat b/src/data/loop_destabilizing_energies.zuker.dat deleted file mode 100644 index 2f950bec..00000000 --- a/src/data/loop_destabilizing_energies.zuker.dat +++ /dev/null @@ -1,39 +0,0 @@ -// Loop destabilizing energies from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// DESTABILIZING ENERGIES BY SIZE OF LOOP (INTERPOLATE WHERE NEEDED) -// hp3 ave calc no tmm;hp4 ave calc with tmm; ave all bulges - -const double loop_destabilizing_energies[] = -{ -// INTERNAL BULGE HAIRPIN SIZE -//------------------------------------------------------- - 0.0, 3.80, 0.0, // 1 - 0.0, 2.80, 0.0, // 2 - 0.0, 3.20, 5.70, // 3 - 1.70, 3.60, 5.60, // 4 - 1.80, 4.00, 5.60, // 5 - 2.00, 4.40, 5.40, // 6 - 2.20, 4.60, 5.90, // 7 - 2.30, 4.70, 5.60, // 8 - 2.40, 4.80, 6.40, // 9 - 2.50, 4.90, 6.50, // 10 - 2.60, 5.00, 6.60, // 11 - 2.70, 5.10, 6.70, // 12 - 2.80, 5.20, 6.80, // 13 - 2.90, 5.30, 6.90, // 14 - 3.00, 5.40, 6.90, // 15 - 3.00, 5.40, 7.00, // 16 - 3.10, 5.50, 7.10, // 17 - 3.10, 5.50, 7.10, // 18 - 3.20, 5.60, 7.20, // 19 - 3.30, 5.70, 7.20, // 20 - 3.30, 5.70, 7.30, // 21 - 3.40, 5.80, 7.30, // 22 - 3.40, 5.80, 7.40, // 23 - 3.40, 5.80, 7.40, // 24 - 3.50, 5.90, 7.50, // 25 - 3.50, 5.90, 7.50, // 26 - 3.60, 6.00, 7.50, // 27 - 3.60, 6.00, 7.60, // 28 - 3.60, 6.00, 7.60, // 29 - 3.70, 6.10, 7.70 // 30 -}; \ No newline at end of file diff --git a/src/data/single_base_stacking_energies.dat b/src/data/single_base_stacking_energies.dat deleted file mode 100644 index 217503fc..00000000 --- a/src/data/single_base_stacking_energies.dat +++ /dev/null @@ -1,96 +0,0 @@ -// Single base stacking energies from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// Data Arangement: -// X -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// 1)AX(3 -// 2)A -// 3' <== 5' -// A=0 , C=1 , G=2 , U=3 -// 3' dangling end matrix coordinates = 16*(1)+4*(2)+(3) -// 5' dangling end matrix coordinates = 64+16*(1)+4*(2)+(3) - -double single_base_stacking_energy[]= -{ -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.80,-0.50,-0.80,-0.60, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.70,-0.80,-1.70,-1.20, 0.0, 0.0, 0.0, 0.0, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, -1.10,-0.40,-1.30,-0.60, 0.0, 0.0, 0.0, 0.0, -0.80,-0.50,-0.80,-0.60, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -0.70,-0.10,-0.70,-0.10, 0.0, 0.0, 0.0, 0.0, -0.70,-0.10,-0.70,-0.10, 0.0, 0.0, 0.0, 0.0, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// A A A A -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.30,-0.10,-0.20,-0.20, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// C C C C -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.20,-0.30,-0.00,-0.00, 0.0, 0.0, 0.0, 0.0, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// G G G G -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, -0.50,-0.30,-0.20,-0.10, 0.0, 0.0, 0.0, 0.0, -0.30,-0.10,-0.20,-0.20, - -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// U U U U -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -0.30,-0.30,-0.40,-0.20, 0.0, 0.0, 0.0, 0.0, -0.30,-0.30,-0.40,-0.20, 0.0, 0.0, 0.0, 0.0 -}; diff --git a/src/data/single_base_stacking_enthalpies.dat b/src/data/single_base_stacking_enthalpies.dat deleted file mode 100644 index aa133ddd..00000000 --- a/src/data/single_base_stacking_enthalpies.dat +++ /dev/null @@ -1,89 +0,0 @@ -// Single base stacking enthalpies from mfold Version 2.3 (Walter et al.:PNAS1994) -// Data Arangement: -// X -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// 1)AX(3 -// 2)A -// 3' <== 5' -// A=0 , C=1 , G=2 , U=3 -// 3' dangling end matrix coordinates = 16*(1)+4*(2)+(3) -// 5' dangling end matrix coordinates = 64+16*(1)+4*(2)+(3) - -double single_base_stacking_enthalpies[]= -{ -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -4.90,-0.90,-5.50,-2.30, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -9.00,-4.10,-8.60,-7.50, 0.0, 0.0, 0.0, 0.0, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, -7.40,-2.80,-6.40,-3.60, 0.0, 0.0, 0.0, 0.0, -4.90,-0.90,-5.50,-2.30, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// A C G U -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -5.70,-0.70,-5.80,-2.20, 0.0, 0.0, 0.0, 0.0, -7.40,-2.40,-7.20,-4.90, 0.0, 0.0, 0.0, 0.0, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// A A A A -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.50, 6.90,-0.60,-0.60, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// C C C C -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.60, 0.70,-4.60,-0.40, 0.0, 0.0, 0.0, 0.0, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// G G G G -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, -2.40, 3.30, 0.80,-1.40, 0.0, 0.0, 0.0, 0.0, -1.50, 5.10, 0.10, 1.00, -// X X X X -// ------------------ ------------------ ------------------ ------------------ -// A C G U A C G U A C G U A C G U -// ------------------ ------------------ ------------------ ------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// U U U U -// AX CX GX UX -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 1.60, 2.20, 0.70, 3.10, 0.0, 0.0, 0.0, 0.0, 1.60, 2.20, 0.70, 3.10, 0.0, 0.0, 0.0, 0.0 -}; diff --git a/src/data/stacking_energies.dat b/src/data/stacking_energies.dat deleted file mode 100644 index 01791d25..00000000 --- a/src/data/stacking_energies.dat +++ /dev/null @@ -1,70 +0,0 @@ -// Stacking energies from Lu, Turner & Mathews:NAR2006 -// Data Arangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// 1)AX(2 -// 3)AY(4 -// 3' <== 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) -0.70 -0.10 -0.70 -0.10 -// -// A=0 , C=1 , G=2 , U=3 -// matrix coordinates = 64*(1)+16*(2)+4*(3)+(4) - -double stacking_energies[]= -{ -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.90, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.20, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.10, 0.0, -0.60, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.10, 0.0, -1.40, 0.0, -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.10, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.30, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.40, 0.0, -1.40, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.10, 0.0, -2.10, 0.0, 0.0, 0.0, 0.0, 0.0, -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.40, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.30, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.40, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.50, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, -3.30, 0.0, -1.50, 0.0, 0.0, 0.0, 0.0, 0.0, -2.10, 0.0, -0.50, - 0.0, 0.0, 0.0, 0.0, -2.20, 0.0, -2.50, 0.0, 0.0, 0.0, 0.0, 0.0, -1.40, 0.0, 1.30, 0.0, -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, -1.30, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.00, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, -2.40, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.50, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, -2.10, 0.0, -1.00, 0.0, 0.0, 0.0, 0.0, 0.0, -1.40, 0.0, 0.30, 0.0, 0.0, 0.0, 0.0, --0.90, 0.0, -1.30, 0.0, 0.0, 0.0, 0.0, 0.0, -0.60, 0.0, -0.50, 0.0, 0.0, 0.0, 0.0, 0.0 -}; - diff --git a/src/data/stacking_enthalpies.dat b/src/data/stacking_enthalpies.dat deleted file mode 100644 index afe69680..00000000 --- a/src/data/stacking_enthalpies.dat +++ /dev/null @@ -1,70 +0,0 @@ -// Stacking enthalpies from Lu, Turner & Mathews:NAR2006 -// Data Arangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// 1)AX(2 -// 3)AY(4 -// 3' <== 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) -0.70 -0.10 -0.70 -0.10 -// -// A=0 , C=1 , G=2 , U=3 -// matrix coordinates = 64*(1)+16*(2)+4*(3)+(4) - -double stacking_enthalpies[]= -{ -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.80, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-11.40, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-10.50, 0.0, -3.20, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -9.40, 0.0, -8.80, 0.0, -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-10.40, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-13.40, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-10.60, 0.0, -5.60, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-10.50, 0.0,-12.10, 0.0, 0.0, 0.0, 0.0, 0.0, -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-12.40, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-12.80, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-14.90, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,-12.60, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0,-13.40, 0.0, -8.30, 0.0, 0.0, 0.0, 0.0, 0.0,-12.10, 0.0,-13.50, - 0.0, 0.0, 0.0, 0.0,-11.40, 0.0,-12.60, 0.0, 0.0, 0.0, 0.0, 0.0, -8.80, 0.0,-14.60, 0.0, -// Y Y Y Y -//------------------------ ------------------------ ------------------------ ------------------------ -// A C G U A C G U A C G U A C G U -//------------------------ ------------------------ ------------------------ ------------------------ -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, -7.70, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -7.00, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0,-12.40, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -8.30, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0,-10.40, 0.0, -7.00, 0.0, 0.0, 0.0, 0.0, 0.0, -5.60, 0.0, -9.30, 0.0, 0.0, 0.0, 0.0, --6.80, 0.0,-12.80, 0.0, 0.0, 0.0, 0.0, 0.0, -3.20, 0.0,-13.50, 0.0, 0.0, 0.0, 0.0, 0.0 -}; - diff --git a/src/data/terminal_mismatch_enthalpies.dat b/src/data/terminal_mismatch_enthalpies.dat deleted file mode 100644 index 3dd42964..00000000 --- a/src/data/terminal_mismatch_enthalpies.dat +++ /dev/null @@ -1,73 +0,0 @@ -// Terminal mismatch and base pair enthalpies from mfold Version 2.3 (Walter et al.:PNAS1994) -// Data Arangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// 1)AX(2 -// 3)AY(4 -// 3' <== 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) -0.70 -0.10 -0.70 -0.10 -// -// -------------------------------- -// STACKING ENTHALPIES : TERMINAL MISMATCHES AND BASE-PAIRS -// -// A=0 , C=1 , G=2 , U=3 -// matrix coordinates = 64*(1)+16*(2)+4*(3)+(4) - -double mismatch_enthalpies[]= -{ -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, -4.00, 0.0, 0.0, 0.0, -4.30, 0.0, 0.0, 0.0, -3.80, -4.30, -6.00, -6.00, -6.00, - 0.0, 0.0, -5.20, 0.0, 0.0, 0.0, -7.20, 0.0, 0.0, 0.0, -7.10, 0.0, -2.60, -2.40, -2.40, -2.40, - 0.0,-10.30, 0.0, -7.20, 0.0, -5.20, 0.0, -4.80, 0.0, -9.40, 0.0, -6.60, -3.40, -6.90, -6.90, -6.90, - -4.30, 0.0, -4.30, 0.0, -2.60, 0.0, -2.60, 0.0, -3.40, 0.0, -3.40, 0.0, -3.30, -3.30, -3.30, -3.30, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, -6.30, 0.0, 0.0, 0.0, -5.10,-10.30, -9.50,-10.30,-10.30, 0.0, 0.0, 0.0, -1.4, - 0.0, 0.0, -8.80, 0.0, 0.0, 0.0, -3.10, 0.0, -5.20, -4.50, -5.20, -6.70, 0.0, 0.0, -5.0, 0.0, - 0.0, -9.50, 0.0, -7.90, 0.0, -4.50, 0.0, -4.80, -9.40, -9.40, -9.40, -9.40, 0.0, -7.4, 0.0, -4.4, - -6.00, 0.0, -6.00, 0.0, -2.40, 0.0, -2.40, 0.0, -8.10, -7.40, -8.10, -8.60, -3.3, 0.0, -3.3, 0.0, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, -8.9, -5.20, -8.80, -5.60, -8.80, 0.0, 0.0, 0.0, -8.9, -4.30, -6.00, -6.00, -6.00, - 0.0, 0.0, -5.6, 0.0, -7.20, -3.10, -3.10, -3.90, 0.0, 0.0, -6.2, 0.0, -2.60, -2.40, -2.40, -2.40, - 0.0, -10.3, 0.0, -9.6, -7.10, -7.40, -6.20, -7.40, 0.0, -9.4, 0.0, -9.2, -3.40, -6.90, -6.90, -6.90, - -6.0, 0.0, -6.0, 0.0, -5.00, -5.00, -5.00, -5.70, -6.9, 0.0, -6.9, 0.0, -3.30, -3.30, -3.30, -3.30, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -4.00, -6.30, -8.90, -5.90, 0.0, 0.0, 0.0, -1.80, -7.20, -7.90, -9.60, -8.10, 0.0, 0.0, 0.0, 1.40, - -4.30, -5.10, -2.00, -1.80, 0.0, 0.0, -3.90, 0.0, -4.80, -4.80, -3.60, -4.80, 0.0, 0.0, -5.70, 0.0, - -3.80, -6.80, -8.90, -6.80, 0.0, -6.70, 0.0, -4.80, -6.60, -8.10, -9.20, -8.10, 0.0, -8.60, 0.0, 0.0, - -2.80, -1.40, -2.80, -1.40, -2.40, 0.0, -2.40, 0.0, -5.50, -4.40, -5.50, -3.60, -3.30, 0.0, -3.30, -3.60 -}; - diff --git a/src/data/terminal_mismatch_hairpin.dat b/src/data/terminal_mismatch_hairpin.dat deleted file mode 100644 index 6b3a0f36..00000000 --- a/src/data/terminal_mismatch_hairpin.dat +++ /dev/null @@ -1,73 +0,0 @@ -// Terminal mismatch stacking energies (hairpin loops) from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// Data Arangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// 1)AX(2 -// 3)AY(4 -// 3' <== 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) -0.70 -0.10 -0.70 -0.10 -// -// -------------------------------- -// STACKING ENERGIES : TERMINAL MISMATCHES AND BASE-PAIRS -// -// A=0 , C=1 , G=2 , U=3 -// matrix coordinates = 64*(1)+16*(2)+4*(3)+(4) - -double mismatch_energies_hairpin[]= -{ -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.30, -0.50, -0.30, -0.30, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.10, -0.20, -1.50, -0.20, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.10, -1.20, -0.20, 0.20, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.30, -0.30, -0.60, -1.10, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.50, -1.50, -1.40, -1.80, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.00, -0.90, -2.90, -0.80, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.20, -2.00, -1.60, -1.10, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.70, -1.40, -1.80, -2.00, 0.0, 0.0, 0.0, 0.0, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, -1.10, -1.50, -1.30, -2.10, 0.0, 0.0, 0.0, 0.0, 0.20, -0.50, -0.30, -0.30, - 0.0, 0.0, 0.0, 0.0, -1.10, -0.70, -2.40, -0.50, 0.0, 0.0, 0.0, 0.0, -0.10, -0.20, -1.50, -0.20, - 0.0, 0.0, 0.0, 0.0, -2.40, -2.90, -1.40, -1.20, 0.0, 0.0, 0.0, 0.0, -0.90, -1.10, -0.30, 0.00, - 0.0, 0.0, 0.0, 0.0, -1.90, -1.00, -2.20, -1.50, 0.0, 0.0, 0.0, 0.0, -0.30, -0.30, -0.40, -1.10, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - -0.50, -0.30, -0.60, -0.50, 0.0, 0.0, 0.0, 0.0, -0.50, -0.30, -0.60, -0.50, 0.0, 0.0, 0.0, 0.0, - -0.20, -0.10, -1.20, -0.00, 0.0, 0.0, 0.0, 0.0, -0.20, -0.10, -1.70, 0.00, 0.0, 0.0, 0.0, 0.0, - -1.40, -1.20, -0.70, -0.20, 0.0, 0.0, 0.0, 0.0, -0.80, -1.20, -0.30, -0.70, 0.0, 0.0, 0.0, 0.0, - -0.30, -0.10, -0.50, -0.80, 0.0, 0.0, 0.0, 0.0, -0.60, -0.10, -0.60, -0.80, 0.0, 0.0, 0.0, 0.0 -}; - diff --git a/src/data/terminal_mismatch_interior.dat b/src/data/terminal_mismatch_interior.dat deleted file mode 100644 index 8f5692ee..00000000 --- a/src/data/terminal_mismatch_interior.dat +++ /dev/null @@ -1,73 +0,0 @@ -// Terminal mismatch stacking energies (interior loops) from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) -// Data Arangement: -// Y -// ------------------ -// (X) A C G U -// ------------------ -// 5' ==> 3' -// (*64)AX(*16) -// (*4)AY(*1) -// 3' <== 5' -// (A) . . . . -// (C) . . . . -// (G) . . . . -// (U) -0.70 -0.10 -0.70 -0.10 -// -// -------------------------------- -// STACKING ENERGIES : TERMINAL MISMATCHES AND BASE-PAIRS -// -// A=0 , C=1 , G=2 , U=3 -// matrix coordinates = 64*(1)+16*(2)+4*(3)+(4) - -double mismatch_energies_interior[]= -{ -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// AX AX AX AX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, -0.40, 0.70, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, 0.70, 0.70, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.40, 0.70, 0.70, 0.70, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, 0.70, 0.00, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// CX CX CX CX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00, -0.00, -1.10, -0.00, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00, -0.00, -0.00, -0.00, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.10, -0.00, -0.00, -0.00, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00, -0.00, -0.00, -0.70, 0.0, 0.0, 0.0, 0.0, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// GX GX GX GX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.0, 0.0, 0.0, 0.0, -0.00, -0.00, -1.10, -0.00, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, -0.40, 0.70, - 0.0, 0.0, 0.0, 0.0, -0.00, -0.00, -0.00, -0.00, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, 0.70, 0.70, - 0.0, 0.0, 0.0, 0.0, -1.10, -0.00, -0.00, -0.00, 0.0, 0.0, 0.0, 0.0, -0.40, 0.70, 0.70, 0.70, - 0.0, 0.0, 0.0, 0.0, -0.00, -0.00, -0.00, -0.70, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, 0.70, 0.00, -// Y Y Y Y -// -------------------------- -------------------------- -------------------------- -------------------------- -// A C G U A C G U A C G U A C G U -// -------------------------- -------------------------- -------------------------- -------------------------- -// 5' --> 3' 5' --> 3' 5' --> 3' 5' --> 3' -// UX UX UX UX -// AY CY GY UY -// 3' <-- 5' 3' <-- 5' 3' <-- 5' 3' <-- 5' - 0.70, 0.70, -0.40, 0.70, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, -0.40, 0.70, 0.0, 0.0, 0.0, 0.0, - 0.70, 0.70, 0.70, 0.70, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, 0.70, 0.70, 0.0, 0.0, 0.0, 0.0, - -0.40, 0.70, 0.70, 0.70, 0.0, 0.0, 0.0, 0.0, -0.40, 0.70, 0.70, 0.70, 0.0, 0.0, 0.0, 0.0, - 0.70, 0.70, 0.70, 0.00, 0.0, 0.0, 0.0, 0.0, 0.70, 0.70, 0.70, 0.00, 0.0, 0.0, 0.0, 0.0 -}; - diff --git a/src/data/tetra_loops.dat b/src/data/tetra_loops.dat deleted file mode 100644 index 764408c8..00000000 --- a/src/data/tetra_loops.dat +++ /dev/null @@ -1,43 +0,0 @@ -// Tetra-loops from mfold Version 3.0 (Mathews,Sabina, Zuker & Turner:JMB1999) - -//#include - -double tetra_loop_energy(char* str) -{ - double energy = 0.0; - - // Seq Energy - // -------------------------------------- - if (str=="GGGGAC") energy = -3.00 ; - else if (str=="GGUGAC") energy = -3.00 ; - else if (str=="CGAAAG") energy = -3.00 ; - else if (str=="GGAGAC") energy = -3.00 ; - else if (str=="CGCAAG") energy = -3.00 ; - else if (str=="GGAAAC") energy = -3.00 ; - else if (str=="CGGAAG") energy = -3.00 ; - else if (str=="CUUCGG") energy = -3.00 ; - else if (str=="CGUGAG") energy = -3.00 ; - else if (str=="CGAAGG") energy = -2.50 ; - else if (str=="CUACGG") energy = -2.50 ; - else if (str=="GGCAAC") energy = -2.50 ; - else if (str=="CGCGAG") energy = -2.50 ; - else if (str=="UGAGAG") energy = -2.50 ; - else if (str=="CGAGAG") energy = -2.00 ; - else if (str=="AGAAAU") energy = -2.00 ; - else if (str=="CGUAAG") energy = -2.00 ; - else if (str=="CUAACG") energy = -2.00 ; - else if (str=="UGAAAG") energy = -2.00 ; - else if (str=="GGAAGC") energy = -1.50 ; - else if (str=="GGGAAC") energy = -1.50 ; - else if (str=="UGAAAA") energy = -1.50 ; - else if (str=="AGCAAU") energy = -1.50 ; - else if (str=="AGUAAU") energy = -1.50 ; - else if (str=="CGGGAG") energy = -1.50 ; - else if (str=="AGUGAU") energy = -1.50 ; - else if (str=="GGCGAC") energy = -1.50 ; - else if (str=="GGGAGC") energy = -1.50 ; - else if (str=="GUGAAC") energy = -1.50 ; - else if (str=="UGGAAA") energy = -1.50 ; - - return energy; -}; diff --git a/src/easylogging++.h b/src/easylogging++.h new file mode 100644 index 00000000..245c00a9 --- /dev/null +++ b/src/easylogging++.h @@ -0,0 +1,6700 @@ +// +// Bismillah ar-Rahmaan ar-Raheem +// +// Easylogging++ v9.83 +// Single-header only, cross-platform logging library for C++ applications +// +// Copyright (c) 2016 muflihun.com +// +// This library is released under the MIT Licence. +// http://easylogging.muflihun.com/licence.php +// +// easylogging@muflihun.com +// +// https://github.com/easylogging/easyloggingpp +// http://easylogging.muflihun.com +// http://muflihun.com +// +#ifndef EASYLOGGINGPP_H +#define EASYLOGGINGPP_H +// Compilers and C++0x/C++11 Evaluation +#if (defined(__GNUC__)) +# define ELPP_COMPILER_GCC 1 +#else +# define ELPP_COMPILER_GCC 0 +#endif +#if ELPP_COMPILER_GCC +# define ELPP_GCC_VERSION (__GNUC__ * 10000 \ ++ __GNUC_MINOR__ * 100 \ ++ __GNUC_PATCHLEVEL__) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define ELPP_CXX0X 1 +# elif(ELPP_GCC_VERSION >= 40801) +# define ELPP_CXX11 1 +# endif +#endif +// Visual C++ +#if defined(_MSC_VER) +# define ELPP_COMPILER_MSVC 1 +#else +# define ELPP_COMPILER_MSVC 0 +#endif +#define ELPP_CRT_DBG_WARNINGS ELPP_COMPILER_MSVC +#if ELPP_COMPILER_MSVC +# if (_MSC_VER == 1600) +# define ELPP_CXX0X 1 +# elif(_MSC_VER >= 1700) +# define ELPP_CXX11 1 +# endif +#endif +// Clang++ +#if (defined(__clang__) && (__clang__ == 1)) +# define ELPP_COMPILER_CLANG 1 +#else +# define ELPP_COMPILER_CLANG 0 +#endif +#if ELPP_COMPILER_CLANG +# define ELPP_CLANG_VERSION (__clang_major__ * 10000 \ ++ __clang_minor__ * 100 \ ++ __clang_patchlevel__) +# if (ELPP_CLANG_VERSION >= 30300) +# define ELPP_CXX11 1 +# endif // (ELPP_CLANG_VERSION >= 30300) +#endif +#if (defined(__MINGW32__) || defined(__MINGW64__)) +# define ELPP_MINGW 1 +#else +# define ELPP_MINGW 0 +#endif +#if (defined(__CYGWIN__) && (__CYGWIN__ == 1)) +# define ELPP_CYGWIN 1 +#else +# define ELPP_CYGWIN 0 +#endif +#if (defined(__INTEL_COMPILER)) +# define ELPP_COMPILER_INTEL 1 +#else +# define ELPP_COMPILER_INTEL 0 +#endif +// Operating System Evaluation +// Windows +#if (defined(_WIN32) || defined(_WIN64)) +# define ELPP_OS_WINDOWS 1 +#else +# define ELPP_OS_WINDOWS 0 +#endif +// Linux +#if (defined(__linux) || defined(__linux__)) +# define ELPP_OS_LINUX 1 +#else +# define ELPP_OS_LINUX 0 +#endif +#if (defined(__APPLE__)) +# define ELPP_OS_MAC 1 +#else +# define ELPP_OS_MAC 0 +#endif +#if (defined(__FreeBSD__)) +# define ELPP_OS_FREEBSD 1 +#else +# define ELPP_OS_FREEBSD 0 +#endif +#if (defined(__sun)) +# define ELPP_OS_SOLARIS 1 +#else +# define ELPP_OS_SOLARIS 0 +#endif +// Unix +#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS)) +# define ELPP_OS_UNIX 1 +#else +# define ELPP_OS_UNIX 0 +#endif +#if (defined(__ANDROID__)) +# define ELPP_OS_ANDROID 1 +#else +# define ELPP_OS_ANDROID 0 +#endif +// Evaluating Cygwin as *nix OS +#if !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN +# undef ELPP_OS_UNIX +# undef ELPP_OS_LINUX +# define ELPP_OS_UNIX 1 +# define ELPP_OS_LINUX 1 +#endif // !ELPP_OS_UNIX && !ELPP_OS_WINDOWS && ELPP_CYGWIN +#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_INFO) +# define ELPP_INTERNAL_DEBUGGING_OUT_INFO std::cout +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +#if !defined(ELPP_INTERNAL_DEBUGGING_OUT_ERROR) +# define ELPP_INTERNAL_DEBUGGING_OUT_ERROR std::cerr +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +#if !defined(ELPP_INTERNAL_DEBUGGING_ENDL) +# define ELPP_INTERNAL_DEBUGGING_ENDL std::endl +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +#if !defined(ELPP_INTERNAL_DEBUGGING_MSG) +# define ELPP_INTERNAL_DEBUGGING_MSG(msg) msg +#endif // !defined(ELPP_INTERNAL_DEBUGGING_OUT) +// Internal Assertions and errors +#if !defined(ELPP_DISABLE_ASSERT) +# if (defined(ELPP_DEBUG_ASSERT_FAILURE)) +# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ +std::stringstream internalInfoStream; internalInfoStream << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ +<< "EASYLOGGING++ ASSERTION FAILED (LINE: " << __LINE__ << ") [" #expr << "] WITH MESSAGE \"" \ +<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" << ELPP_INTERNAL_DEBUGGING_ENDL; base::utils::abort(1, \ +"ELPP Assertion failure, please define ELPP_DEBUG_ASSERT_FAILURE"); } +# else +# define ELPP_ASSERT(expr, msg) if (!(expr)) { \ +std::stringstream internalInfoStream; internalInfoStream << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR\ +<< "ASSERTION FAILURE FROM EASYLOGGING++ (LINE: " \ +<< __LINE__ << ") [" #expr << "] WITH MESSAGE \"" << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << "\"" \ +<< ELPP_INTERNAL_DEBUGGING_ENDL; } +# endif // (defined(ELPP_DEBUG_ASSERT_FAILURE)) +#else +# define ELPP_ASSERT(x, y) +#endif //(!defined(ELPP_DISABLE_ASSERT) +#if ELPP_COMPILER_MSVC +# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ +{ char buff[256]; strerror_s(buff, 256, errno); \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << buff << " [" << errno << "]";} (void)0 +#else +# define ELPP_INTERNAL_DEBUGGING_WRITE_PERROR \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR << ": " << strerror(errno) << " [" << errno << "]"; (void)0 +#endif // ELPP_COMPILER_MSVC +#if defined(ELPP_DEBUG_ERRORS) +# if !defined(ELPP_INTERNAL_ERROR) +# define ELPP_INTERNAL_ERROR(msg, pe) { \ +std::stringstream internalInfoStream; internalInfoStream << " " << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_ERROR \ +<< "ERROR FROM EASYLOGGING++ (LINE: " << __LINE__ << ") " \ +<< ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) << ELPP_INTERNAL_DEBUGGING_ENDL; \ +if (pe) { ELPP_INTERNAL_DEBUGGING_OUT_ERROR << " "; ELPP_INTERNAL_DEBUGGING_WRITE_PERROR; }} (void)0 +# endif +#else +# undef ELPP_INTERNAL_INFO +# define ELPP_INTERNAL_ERROR(msg, pe) +#endif // defined(ELPP_DEBUG_ERRORS) +#if (defined(ELPP_DEBUG_INFO)) +# if !(defined(ELPP_INTERNAL_INFO_LEVEL)) +# define ELPP_INTERNAL_INFO_LEVEL 9 +# endif // !(defined(ELPP_INTERNAL_INFO_LEVEL)) +# if !defined(ELPP_INTERNAL_INFO) +# define ELPP_INTERNAL_INFO(lvl, msg) { if (lvl <= ELPP_INTERNAL_INFO_LEVEL) { \ +std::stringstream internalInfoStream; internalInfoStream << " " << msg; \ +ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStream.str()) \ +<< ELPP_INTERNAL_DEBUGGING_ENDL; }} +# endif +#else +# undef ELPP_INTERNAL_INFO +# define ELPP_INTERNAL_INFO(lvl, msg) +#endif // (defined(ELPP_DEBUG_INFO)) +#if defined(ELPP_STACKTRACE_ON_CRASH) +# if (ELPP_COMPILER_GCC && !ELPP_MINGW) +# define ELPP_STACKTRACE 1 +# else +# if ELPP_COMPILER_MSVC +# pragma message("Stack trace not available for this compiler") +# else +# warning "Stack trace not available for this compiler"; +# endif // ELPP_COMPILER_MSVC +# endif // ELPP_COMPILER_GCC +#endif // (defined(ELPP_STACKTRACE_ON_CRASH)) +// Miscellaneous macros +#define ELPP_UNUSED(x) (void)x +#if ELPP_OS_UNIX +// Log file permissions for unix-based systems +# define ELPP_LOG_PERMS S_IRUSR | S_IWUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IXOTH +#endif // ELPP_OS_UNIX +#if defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC +# if defined(ELPP_EXPORT_SYMBOLS) +# define ELPP_EXPORT __declspec(dllexport) +# else +# define ELPP_EXPORT __declspec(dllimport) +# endif // defined(ELPP_EXPORT_SYMBOLS) +#else +# define ELPP_EXPORT +#endif // defined(ELPP_AS_DLL) && ELPP_COMPILER_MSVC +// Some special functions that are VC++ specific +#undef STRTOK +#undef STRERROR +#undef STRCAT +#undef STRCPY +#if ELPP_CRT_DBG_WARNINGS +# define STRTOK(a, b, c) strtok_s(a, b, c) +# define STRERROR(a, b, c) strerror_s(a, b, c) +# define STRCAT(a, b, len) strcat_s(a, len, b) +# define STRCPY(a, b, len) strcpy_s(a, len, b) +#else +# define STRTOK(a, b, c) strtok(a, b) +# define STRERROR(a, b, c) strerror(c) +# define STRCAT(a, b, len) strcat(a, b) +# define STRCPY(a, b, len) strcpy(a, b) +#endif +// Compiler specific support evaluations +#if ((!ELPP_MINGW && !ELPP_COMPILER_CLANG) || defined(ELPP_FORCE_USE_STD_THREAD)) +# define ELPP_USE_STD_THREADING 1 +#else +# define ELPP_USE_STD_THREADING 0 +#endif +#undef ELPP_FINAL +#if ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) +# define ELPP_FINAL +#else +# define ELPP_FINAL final +#endif // ELPP_COMPILER_INTEL || (ELPP_GCC_VERSION < 40702) +#if defined(ELPP_EXPERIMENTAL_ASYNC) +# define ELPP_ASYNC_LOGGING 1 +#else +# define ELPP_ASYNC_LOGGING 0 +#endif // defined(ELPP_EXPERIMENTAL_ASYNC) +#if defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING +# define ELPP_THREADING_ENABLED 1 +#else +# define ELPP_THREADING_ENABLED 0 +#endif // defined(ELPP_THREAD_SAFE) || ELPP_ASYNC_LOGGING +// Function macro ELPP_FUNC +#undef ELPP_FUNC +#if ELPP_COMPILER_MSVC // Visual C++ +# define ELPP_FUNC __FUNCSIG__ +#elif ELPP_COMPILER_GCC // GCC +# define ELPP_FUNC __PRETTY_FUNCTION__ +#elif ELPP_COMPILER_INTEL // Intel C++ +# define ELPP_FUNC __PRETTY_FUNCTION__ +#elif ELPP_COMPILER_CLANG // Clang++ +# define ELPP_FUNC __PRETTY_FUNCTION__ +#else +# if defined(__func__) +# define ELPP_FUNC __func__ +# else +# define ELPP_FUNC "" +# endif // defined(__func__) +#endif // defined(_MSC_VER) +#undef ELPP_VARIADIC_TEMPLATES_SUPPORTED +// Keep following line commented until features are fixed +#define ELPP_VARIADIC_TEMPLATES_SUPPORTED \ +(ELPP_COMPILER_GCC || ELPP_COMPILER_CLANG || ELPP_COMPILER_INTEL || (ELPP_COMPILER_MSVC && _MSC_VER >= 1800)) +// Logging Enable/Disable macros +#define ELPP_LOGGING_ENABLED (!defined(ELPP_DISABLE_LOGS)) +#if (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG)))) +# define ELPP_DEBUG_LOG 1 +#else +# define ELPP_DEBUG_LOG 0 +#endif // (!defined(ELPP_DISABLE_DEBUG_LOGS) && (ELPP_LOGGING_ENABLED) && ((defined(_DEBUG)) || (!defined(NDEBUG)))) +#if (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_INFO_LOG 1 +#else +# define ELPP_INFO_LOG 0 +#endif // (!defined(ELPP_DISABLE_INFO_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_WARNING_LOG 1 +#else +# define ELPP_WARNING_LOG 0 +#endif // (!defined(ELPP_DISABLE_WARNING_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_ERROR_LOG 1 +#else +# define ELPP_ERROR_LOG 0 +#endif // (!defined(ELPP_DISABLE_ERROR_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_FATAL_LOG 1 +#else +# define ELPP_FATAL_LOG 0 +#endif // (!defined(ELPP_DISABLE_FATAL_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_TRACE_LOG 1 +#else +# define ELPP_TRACE_LOG 0 +#endif // (!defined(ELPP_DISABLE_TRACE_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) +# define ELPP_VERBOSE_LOG 1 +#else +# define ELPP_VERBOSE_LOG 0 +#endif // (!defined(ELPP_DISABLE_VERBOSE_LOGS) && (ELPP_LOGGING_ENABLED)) +#if (!(ELPP_CXX0X || ELPP_CXX11)) +# error "Easylogging++ 9.0+ is only compatible with C++0x (or higher) compliant compiler" +#endif // (!(ELPP_CXX0X || ELPP_CXX11)) +// Headers +#if defined(ELPP_SYSLOG) +# include +#endif // defined(ELPP_SYSLOG) +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(ELPP_UNICODE) +# include +# if ELPP_OS_WINDOWS +# include +# endif // ELPP_OS_WINDOWS +#endif // defined(ELPP_UNICODE) +#if ELPP_STACKTRACE +# include +# include +#endif // ELPP_STACKTRACE +#if ELPP_OS_ANDROID +# include +#endif // ELPP_OS_ANDROID +#if ELPP_OS_UNIX +# include +# include +#elif ELPP_OS_WINDOWS +# include +# include +# if defined(WIN32_LEAN_AND_MEAN) +# if defined(ELPP_WINSOCK2) +# include +# else +# include +# endif // defined(ELPP_WINSOCK2) +# endif // defined(WIN32_LEAN_AND_MEAN) +#endif // ELPP_OS_UNIX +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if ELPP_THREADING_ENABLED +# if ELPP_USE_STD_THREADING +# include +# include +# else +# if ELPP_OS_UNIX +# include +# endif // ELPP_OS_UNIX +# endif // ELPP_USE_STD_THREADING +#endif // ELPP_THREADING_ENABLED +#if ELPP_ASYNC_LOGGING +# if defined(ELPP_NO_SLEEP_FOR) +# include +# endif // defined(ELPP_NO_SLEEP_FOR) +# include +# include +# include +#endif // ELPP_ASYNC_LOGGING +#if defined(ELPP_STL_LOGGING) +// For logging STL based templates +# include +# include +# include +# include +# include +# include +# if defined(ELPP_LOG_STD_ARRAY) +# include +# endif // defined(ELPP_LOG_STD_ARRAY) +# if defined(ELPP_LOG_UNORDERED_MAP) +# include +# endif // defined(ELPP_LOG_UNORDERED_MAP) +# if defined(ELPP_LOG_UNORDERED_SET) +# include +# endif // defined(ELPP_UNORDERED_SET) +#endif // defined(ELPP_STL_LOGGING) +#if defined(ELPP_QT_LOGGING) +// For logging Qt based classes & templates +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif // defined(ELPP_QT_LOGGING) +#if defined(ELPP_BOOST_LOGGING) +// For logging boost based classes & templates +# include +# include +# include +# include +# include +# include +# include +# include +#endif // defined(ELPP_BOOST_LOGGING) +#if defined(ELPP_WXWIDGETS_LOGGING) +// For logging wxWidgets based classes & templates +# include +#endif // defined(ELPP_WXWIDGETS_LOGGING) +// Forward declarations +namespace el { + class Logger; + class LogMessage; + class PerformanceTrackingData; + class Loggers; + class Helpers; + template class Callback; + class LogDispatchCallback; + class PerformanceTrackingCallback; + class LogDispatchData; + namespace base { + class Storage; + class RegisteredLoggers; + class PerformanceTracker; + class MessageBuilder; + class Writer; + class PErrorWriter; + class LogDispatcher; + class DefaultLogBuilder; + class DefaultLogDispatchCallback; +#if ELPP_ASYNC_LOGGING + class AsyncLogDispatchCallback; + class AsyncDispatchWorker; +#endif // ELPP_ASYNC_LOGGING + class DefaultPerformanceTrackingCallback; + } // namespace base +} // namespace el +/// @brief Easylogging++ entry namespace +namespace el { + /// @brief Namespace containing base/internal functionality used by Easylogging++ + namespace base { + /// @brief Data types used by Easylogging++ + namespace type { +#undef ELPP_LITERAL +#undef ELPP_STRLEN +#undef ELPP_COUT +#if defined(ELPP_UNICODE) +# define ELPP_LITERAL(txt) L##txt +# define ELPP_STRLEN wcslen +# if defined ELPP_CUSTOM_COUT +# define ELPP_COUT ELPP_CUSTOM_COUT +# else +# define ELPP_COUT std::wcout +# endif // defined ELPP_CUSTOM_COUT + typedef wchar_t char_t; + typedef std::wstring string_t; + typedef std::wstringstream stringstream_t; + typedef std::wfstream fstream_t; + typedef std::wostream ostream_t; +#else +# define ELPP_LITERAL(txt) txt +# define ELPP_STRLEN strlen +# if defined ELPP_CUSTOM_COUT +# define ELPP_COUT ELPP_CUSTOM_COUT +# else +# define ELPP_COUT std::cout +# endif // defined ELPP_CUSTOM_COUT + typedef char char_t; + typedef std::string string_t; + typedef std::stringstream stringstream_t; + typedef std::fstream fstream_t; + typedef std::ostream ostream_t; +#endif // defined(ELPP_UNICODE) +#if defined(ELPP_CUSTOM_COUT_LINE) +# define ELPP_COUT_LINE(logLine) ELPP_CUSTOM_COUT_LINE(logLine) +#else +# define ELPP_COUT_LINE(logLine) logLine << std::flush +#endif // defined(ELPP_CUSTOM_COUT_LINE) + typedef unsigned short EnumType; + typedef std::shared_ptr StoragePointer; + typedef int VerboseLevel; + typedef std::shared_ptr LogDispatchCallbackPtr; + typedef std::shared_ptr PerformanceTrackingCallbackPtr; + typedef std::unique_ptr PerformanceTrackerPtr; + } // namespace type + /// @brief Internal helper class that prevent copy constructor for class + /// + /// @detail When using this class simply inherit it privately + class NoCopy { + protected: + NoCopy(void) {} + private: + NoCopy(const NoCopy&); + NoCopy& operator=(const NoCopy&); + }; + /// @brief Internal helper class that makes all default constructors private. + /// + /// @detail This prevents initializing class making it static unless an explicit constructor is declared. + /// When using this class simply inherit it privately + class StaticClass { + private: + StaticClass(void); + StaticClass(const StaticClass&); + StaticClass& operator=(const StaticClass&); + }; + } // namespace base + /// @brief Represents enumeration for severity level used to determine level of logging + /// + /// @detail With Easylogging++, developers may disable or enable any level regardless of + /// what the severity is. Or they can choose to log using hierarchical logging flag + enum class Level : base::type::EnumType { + /// @brief Generic level that represents all the levels. Useful when setting global configuration for all levels + Global = 1, + /// @brief Information that can be useful to back-trace certain events - mostly useful than debug logs. + Trace = 2, + /// @brief Informational events most useful for developers to debug application + Debug = 4, + /// @brief Severe error information that will presumably abort application + Fatal = 8, + /// @brief Information representing errors in application but application will keep running + Error = 16, + /// @brief Useful when application has potentially harmful situtaions + Warning = 32, + /// @brief Information that can be highly useful and vary with verbose logging level. + Verbose = 64, + /// @brief Mainly useful to represent current progress of application + Info = 128, + /// @brief Represents unknown level + Unknown = 1010 + }; + /// @brief Static class that contains helper functions for el::Level + class LevelHelper : base::StaticClass { + public: + /// @brief Represents minimum valid level. Useful when iterating through enum. + static const base::type::EnumType kMinValid = static_cast(Level::Trace); + /// @brief Represents maximum valid level. This is used internally and you should not need it. + static const base::type::EnumType kMaxValid = static_cast(Level::Info); + /// @brief Casts level to int, useful for iterating through enum. + static base::type::EnumType castToInt(Level level) { + return static_cast(level); + } + /// @brief Casts int(ushort) to level, useful for iterating through enum. + static Level castFromInt(base::type::EnumType l) { + return static_cast(l); + } + /// @brief Converts level to associated const char* + /// @return Upper case string based level. + static const char* convertToString(Level level) { + // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet. + if (level == Level::Global) return "GLOBAL"; + if (level == Level::Debug) return "DEBUG"; + if (level == Level::Info) return "INFO"; + if (level == Level::Warning) return "WARNING"; + if (level == Level::Error) return "ERROR"; + if (level == Level::Fatal) return "FATAL"; + if (level == Level::Verbose) return "VERBOSE"; + if (level == Level::Trace) return "TRACE"; + return "UNKNOWN"; + } + /// @brief Converts from levelStr to Level + /// @param levelStr Upper case string based level. + /// Lower case is also valid but providing upper case is recommended. + static Level convertFromString(const char* levelStr) { + if ((strcmp(levelStr, "GLOBAL") == 0) || (strcmp(levelStr, "global") == 0)) + return Level::Global; + if ((strcmp(levelStr, "DEBUG") == 0) || (strcmp(levelStr, "debug") == 0)) + return Level::Debug; + if ((strcmp(levelStr, "INFO") == 0) || (strcmp(levelStr, "info") == 0)) + return Level::Info; + if ((strcmp(levelStr, "WARNING") == 0) || (strcmp(levelStr, "warning") == 0)) + return Level::Warning; + if ((strcmp(levelStr, "ERROR") == 0) || (strcmp(levelStr, "error") == 0)) + return Level::Error; + if ((strcmp(levelStr, "FATAL") == 0) || (strcmp(levelStr, "fatal") == 0)) + return Level::Fatal; + if ((strcmp(levelStr, "VERBOSE") == 0) || (strcmp(levelStr, "verbose") == 0)) + return Level::Verbose; + if ((strcmp(levelStr, "TRACE") == 0) || (strcmp(levelStr, "trace") == 0)) + return Level::Trace; + return Level::Unknown; + } + /// @brief Applies specified function to each level starting from startIndex + /// @param startIndex initial value to start the iteration from. This is passed as pointer and + /// is left-shifted so this can be used inside function (fn) to represent current level. + /// @param fn function to apply with each level. This bool represent whether or not to stop iterating through levels. + static inline void forEachLevel(base::type::EnumType* startIndex, const std::function& fn) { + base::type::EnumType lIndexMax = LevelHelper::kMaxValid; + do { + if (fn()) { + break; + } + *startIndex = static_cast(*startIndex << 1); + } while (*startIndex <= lIndexMax); + } + }; + /// @brief Represents enumeration of ConfigurationType used to configure or access certain aspect + /// of logging + enum class ConfigurationType : base::type::EnumType { + /// @brief Determines whether or not corresponding level and logger of logging is enabled + /// You may disable all logs by using el::Level::Global + Enabled = 1, + /// @brief Whether or not to write corresponding log to log file + ToFile = 2, + /// @brief Whether or not to write corresponding level and logger log to standard output. + /// By standard output meaning termnal, command prompt etc + ToStandardOutput = 4, + /// @brief Determines format of logging corresponding level and logger. + Format = 8, + /// @brief Determines log file (full path) to write logs to for correponding level and logger + Filename = 16, + /// @brief Specifies milliseconds width. Width can be within range (1-6) + MillisecondsWidth = 32, + /// @brief Determines whether or not performance tracking is enabled. + /// + /// @detail This does not depend on logger or level. Performance tracking always uses 'performance' logger + PerformanceTracking = 64, + /// @brief Specifies log file max size. + /// + /// @detail If file size of corresponding log file (for corresponding level) is >= specified size, log file will + /// be truncated and re-initiated. + MaxLogFileSize = 128, + /// @brief Specifies number of log entries to hold until we flush pending log data + LogFlushThreshold = 256, + /// @brief Represents unknown configuration + Unknown = 1010 + }; + /// @brief Static class that contains helper functions for el::ConfigurationType + class ConfigurationTypeHelper : base::StaticClass { + public: + /// @brief Represents minimum valid configuration type. Useful when iterating through enum. + static const base::type::EnumType kMinValid = static_cast(ConfigurationType::Enabled); + /// @brief Represents maximum valid configuration type. This is used internally and you should not need it. + static const base::type::EnumType kMaxValid = static_cast(ConfigurationType::MaxLogFileSize); + /// @brief Casts configuration type to int, useful for iterating through enum. + static base::type::EnumType castToInt(ConfigurationType configurationType) { + return static_cast(configurationType); + } + /// @brief Casts int(ushort) to configurationt type, useful for iterating through enum. + static ConfigurationType castFromInt(base::type::EnumType c) { + return static_cast(c); + } + /// @brief Converts configuration type to associated const char* + /// @returns Upper case string based configuration type. + static const char* convertToString(ConfigurationType configurationType) { + // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet. + if (configurationType == ConfigurationType::Enabled) return "ENABLED"; + if (configurationType == ConfigurationType::Filename) return "FILENAME"; + if (configurationType == ConfigurationType::Format) return "FORMAT"; + if (configurationType == ConfigurationType::ToFile) return "TO_FILE"; + if (configurationType == ConfigurationType::ToStandardOutput) return "TO_STANDARD_OUTPUT"; + if (configurationType == ConfigurationType::MillisecondsWidth) return "MILLISECONDS_WIDTH"; + if (configurationType == ConfigurationType::PerformanceTracking) return "PERFORMANCE_TRACKING"; + if (configurationType == ConfigurationType::MaxLogFileSize) return "MAX_LOG_FILE_SIZE"; + if (configurationType == ConfigurationType::LogFlushThreshold) return "LOG_FLUSH_THRESHOLD"; + return "UNKNOWN"; + } + /// @brief Converts from configStr to ConfigurationType + /// @param configStr Upper case string based configuration type. + /// Lower case is also valid but providing upper case is recommended. + static ConfigurationType convertFromString(const char* configStr) { + if ((strcmp(configStr, "ENABLED") == 0) || (strcmp(configStr, "enabled") == 0)) + return ConfigurationType::Enabled; + if ((strcmp(configStr, "TO_FILE") == 0) || (strcmp(configStr, "to_file") == 0)) + return ConfigurationType::ToFile; + if ((strcmp(configStr, "TO_STANDARD_OUTPUT") == 0) || (strcmp(configStr, "to_standard_output") == 0)) + return ConfigurationType::ToStandardOutput; + if ((strcmp(configStr, "FORMAT") == 0) || (strcmp(configStr, "format") == 0)) + return ConfigurationType::Format; + if ((strcmp(configStr, "FILENAME") == 0) || (strcmp(configStr, "filename") == 0)) + return ConfigurationType::Filename; + if ((strcmp(configStr, "MILLISECONDS_WIDTH") == 0) || (strcmp(configStr, "milliseconds_width") == 0)) + return ConfigurationType::MillisecondsWidth; + if ((strcmp(configStr, "PERFORMANCE_TRACKING") == 0) || (strcmp(configStr, "performance_tracking") == 0)) + return ConfigurationType::PerformanceTracking; + if ((strcmp(configStr, "MAX_LOG_FILE_SIZE") == 0) || (strcmp(configStr, "max_log_file_size") == 0)) + return ConfigurationType::MaxLogFileSize; + if ((strcmp(configStr, "LOG_FLUSH_THRESHOLD") == 0) || (strcmp(configStr, "log_flush_threshold") == 0)) + return ConfigurationType::LogFlushThreshold; + return ConfigurationType::Unknown; + } + /// @brief Applies specified function to each configuration type starting from startIndex + /// @param startIndex initial value to start the iteration from. This is passed by pointer and is left-shifted + /// so this can be used inside function (fn) to represent current configuration type. + /// @param fn function to apply with each configuration type. + /// This bool represent whether or not to stop iterating through configurations. + static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function& fn) { + base::type::EnumType cIndexMax = ConfigurationTypeHelper::kMaxValid; + do { + if (fn()) { + break; + } + *startIndex = static_cast(*startIndex << 1); + } while (*startIndex <= cIndexMax); + } + }; + /// @brief Flags used while writing logs. This flags are set by user + enum class LoggingFlag : base::type::EnumType { + /// @brief Makes sure we have new line for each container log entry + NewLineForContainer = 1, + /// @brief Makes sure if -vmodule is used and does not specifies a module, then verbose + /// logging is allowed via that module. + AllowVerboseIfModuleNotSpecified = 2, + /// @brief When handling crashes by default, detailed crash reason will be logged as well + LogDetailedCrashReason = 4, + /// @brief Allows to disable application abortion when logged using FATAL level + DisableApplicationAbortOnFatalLog = 8, + /// @brief Flushes log with every log-entry (performance sensative) - Disabled by default + ImmediateFlush = 16, + /// @brief Enables strict file rolling + StrictLogFileSizeCheck = 32, + /// @brief Make terminal output colorful for supported terminals + ColoredTerminalOutput = 64, + /// @brief Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network") + MultiLoggerSupport = 128, + /// @brief Disables comparing performance tracker's checkpoints + DisablePerformanceTrackingCheckpointComparison = 256, + /// @brief Disable VModules + DisableVModules = 512, + /// @brief Disable VModules extensions + DisableVModulesExtensions = 1024, + /// @brief Enables hierarchical logging + HierarchicalLogging = 2048, + /// @brief Creates logger automatically when not available + CreateLoggerAutomatically = 4096, + /// @brief Adds spaces b/w logs that separated by left-shift operator + AutoSpacing = 8192, + /// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only) + FixedTimeFormat = 16384 + }; + namespace base { + /// @brief Namespace containing constants used internally. + namespace consts { + // Level log values - These are values that are replaced in place of %level format specifier + static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO "); + static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG"); + static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARN "); + static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR"); + static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL"); + static const base::type::char_t* kVerboseLevelLogValue = ELPP_LITERAL("VER"); + static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE"); + static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I"); + static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D"); + static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W"); + static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E"); + static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F"); + static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V"); + static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T"); + // Format specifiers - These are used to define log format + static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app"); + static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger"); + static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread"); + static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level"); + static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort"); + static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime"); + static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file"); + static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase"); + static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line"); + static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc"); + static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func"); + static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user"); + static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host"); + static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg"); + static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel"); + static const char* kDateTimeFormatSpecifierForFilename = "%datetime"; + // Date/time + static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; + static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August", + "September", "October", "November", "December" }; + static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g"; + static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m"; + static const int kYearBase = 1900; + static const char* kAm = "AM"; + static const char* kPm = "PM"; + // Miscellaneous constants + static const char* kDefaultLoggerId = "default"; + static const char* kPerformanceLoggerId = "performance"; +#if defined(ELPP_SYSLOG) + static const char* kSysLogLoggerId = "syslog"; +#endif // defined(ELPP_SYSLOG) + static const char* kNullPointer = "nullptr"; + static const char kFormatSpecifierChar = '%'; +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED + static const char kFormatSpecifierCharValue = 'v'; +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED + static const unsigned int kMaxLogPerContainer = 100; + static const unsigned int kMaxLogPerCounter = 100000; + static const unsigned int kDefaultMillisecondsWidth = 3; + static const base::type::VerboseLevel kMaxVerboseLevel = 9; + static const char* kUnknownUser = "user"; + static const char* kUnknownHost = "unknown-host"; +#if defined(ELPP_DEFAULT_LOG_FILE) + static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE; +#else +# if ELPP_OS_UNIX +# if ELPP_OS_ANDROID + static const char* kDefaultLogFile = "logs/myeasylog.log"; +# else + static const char* kDefaultLogFile = "logs/myeasylog.log"; +# endif // ELPP_OS_ANDROID +# elif ELPP_OS_WINDOWS + static const char* kDefaultLogFile = "logs\\myeasylog.log"; +# endif // ELPP_OS_UNIX +#endif // defined(ELPP_DEFAULT_LOG_FILE) +#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) + static const char* kDefaultLogFileParam = "--default-log-file"; +#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) +#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) + static const char* kLoggingFlagsParam = "--logging-flags"; +#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) +#if ELPP_OS_WINDOWS + static const char* kFilePathSeperator = "\\"; +#else + static const char* kFilePathSeperator = "/"; +#endif // ELPP_OS_WINDOWS + static const char* kValidLoggerIdSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._"; + static const char* kConfigurationComment = "##"; + static const char* kConfigurationLevel = "*"; + static const char* kConfigurationLoggerId = "--"; + static const std::size_t kSourceFilenameMaxLength = 100; + static const std::size_t kSourceLineMaxLength = 10; + static const Level kPerformanceTrackerDefaultLevel = Level::Info; + const struct { + double value; + const base::type::char_t* unit; + } kTimeFormats[] = { + { 1000.0f, ELPP_LITERAL("mis") }, + { 1000.0f, ELPP_LITERAL("ms") }, + { 60.0f, ELPP_LITERAL("seconds") }, + { 60.0f, ELPP_LITERAL("minutes") }, + { 24.0f, ELPP_LITERAL("hours") }, + { 7.0f, ELPP_LITERAL("days") } + }; + static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]); + const struct { + int numb; + const char* name; + const char* brief; + const char* detail; + } kCrashSignals[] = { + // NOTE: Do not re-order, if you do please check CrashHandler(bool) constructor and CrashHandler::setHandler(..) + { SIGABRT, "SIGABRT", "Abnormal termination", + "Program was abnormally terminated." }, + { SIGFPE, "SIGFPE", "Erroneous arithmetic operation", + "Arithemetic operation issue such as division by zero or operation resulting in overflow." }, + { SIGILL, "SIGILL", "Illegal instruction", + "Generally due to a corruption in the code or to an attempt to execute data."}, + { SIGSEGV, "SIGSEGV", "Invalid access to memory", + "Program is trying to read an invalid (unallocated, deleted or corrupted) or inaccessible memory." }, + { SIGINT, "SIGINT", "Interactive attention signal", + "Interruption generated (generally) by user or operating system." }, + }; + static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]); + } // namespace consts + } // namespace base + typedef std::function PreRollOutCallback; + namespace base { + static inline void defaultPreRollOutCallback(const char*, std::size_t) {} + /// @brief Enum to represent timestamp unit + enum class TimestampUnit : base::type::EnumType { + Microsecond = 0, Millisecond = 1, Second = 2, Minute = 3, Hour = 4, Day = 5 + }; + /// @brief Format flags used to determine specifiers that are active for performance improvements. + enum class FormatFlags : base::type::EnumType { + DateTime = 1<<1, LoggerId = 1<<2, File = 1<<3, Line = 1<<4, Location = 1<<5, Function = 1<<6, + User = 1<<7, Host = 1<<8, LogMessage = 1<<9, VerboseLevel = 1<<10, AppName = 1<<11, ThreadId = 1<<12, + Level = 1<<13, FileBase = 1<<14, LevelShort = 1<<15 + }; + /// @brief A milliseconds width class containing actual width and offset for date/time + class MillisecondsWidth { + public: + MillisecondsWidth(void) { init(base::consts::kDefaultMillisecondsWidth); } + explicit MillisecondsWidth(int width) { init(width); } + bool operator==(const MillisecondsWidth& msWidth) { return m_width == msWidth.m_width && m_offset == msWidth.m_offset; } + int m_width; unsigned int m_offset; + private: + void init(int width) { + if (width < 1 || width > 6) { + width = base::consts::kDefaultMillisecondsWidth; + } + m_width = width; + switch (m_width) { + case 3: m_offset = 1000; break; + case 4: m_offset = 100; break; + case 5: m_offset = 10; break; + case 6: m_offset = 1; break; + default: m_offset = 1000; break; + } + } + }; + /// @brief Namespace containing utility functions/static classes used internally + namespace utils { + /// @brief Deletes memory safely and points to null + template + static inline + typename std::enable_if::value, void>::type + safeDelete(T*& pointer) { + if (pointer == nullptr) + return; + delete pointer; + pointer = nullptr; + } + /// @brief Gets value of const char* but if it is nullptr, a string nullptr is returned + static inline const char* charPtrVal(const char* pointer) { + return pointer == nullptr ? base::consts::kNullPointer : pointer; + } + /// @brief Aborts application due with user-defined status + static inline void abort(int status, const std::string& reason = std::string()) { + // Both status and reason params are there for debugging with tools like gdb etc + ELPP_UNUSED(status); + ELPP_UNUSED(reason); +#if defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) + // Ignore msvc critical error dialog - break instead (on debug mode) + _asm int 3 +#else + ::abort(); +#endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) + } + /// @brief Bitwise operations for C++11 strong enum class. This casts e into Flag_T and returns value after bitwise operation + /// Use these function as
flag = bitwise::Or(MyEnum::val1, flag);
+ namespace bitwise { + template + static inline base::type::EnumType And(Enum e, base::type::EnumType flag) { + return static_cast(flag) & static_cast(e); + } + template + static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) { + return static_cast(flag) & ~(static_cast(e)); + } + template + static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) { + return static_cast(flag) | static_cast(e); + } + } // namespace bitwise + template + static inline void addFlag(Enum e, base::type::EnumType* flag) { + *flag = base::utils::bitwise::Or(e, *flag); + } + template + static inline void removeFlag(Enum e, base::type::EnumType* flag) { + *flag = base::utils::bitwise::Not(e, *flag); + } + template + static inline bool hasFlag(Enum e, base::type::EnumType flag) { + return base::utils::bitwise::And(e, flag) > 0x0; + } + } // namespace utils + namespace threading { +#if ELPP_THREADING_ENABLED +# if !ELPP_USE_STD_THREADING + namespace internal { + /// @brief A mutex wrapper for compiler that dont yet support std::mutex + class Mutex : base::NoCopy { + public: + Mutex(void) { +# if ELPP_OS_UNIX + pthread_mutex_init(&m_underlyingMutex, nullptr); +# elif ELPP_OS_WINDOWS + InitializeCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + virtual ~Mutex(void) { +# if ELPP_OS_UNIX + pthread_mutex_destroy(&m_underlyingMutex); +# elif ELPP_OS_WINDOWS + DeleteCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + inline void lock(void) { +# if ELPP_OS_UNIX + pthread_mutex_lock(&m_underlyingMutex); +# elif ELPP_OS_WINDOWS + EnterCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + inline bool try_lock(void) { +# if ELPP_OS_UNIX + return (pthread_mutex_trylock(&m_underlyingMutex) == 0); +# elif ELPP_OS_WINDOWS + return TryEnterCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + inline void unlock(void) { +# if ELPP_OS_UNIX + pthread_mutex_unlock(&m_underlyingMutex); +# elif ELPP_OS_WINDOWS + LeaveCriticalSection(&m_underlyingMutex); +# endif // ELPP_OS_UNIX + } + + private: +# if ELPP_OS_UNIX + pthread_mutex_t m_underlyingMutex; +# elif ELPP_OS_WINDOWS + CRITICAL_SECTION m_underlyingMutex; +# endif // ELPP_OS_UNIX + }; + /// @brief Scoped lock for compiler that dont yet support std::lock_guard + template + class ScopedLock : base::NoCopy { + public: + explicit ScopedLock(M& mutex) { + m_mutex = &mutex; + m_mutex->lock(); + } + + virtual ~ScopedLock(void) { + m_mutex->unlock(); + } + private: + M* m_mutex; + ScopedLock(void); + }; + } // namespace internal + /// @brief Gets ID of currently running threading in windows systems. On unix, nothing is returned. + static inline std::string getCurrentThreadId(void) { + std::stringstream ss; +# if (ELPP_OS_WINDOWS) + ss << GetCurrentThreadId(); +# endif // (ELPP_OS_WINDOWS) + return ss.str(); + } + static inline void msleep(int) { + // No implementation for non std::thread version + } + typedef base::threading::internal::Mutex Mutex; + typedef base::threading::internal::ScopedLock ScopedLock; +# else + /// @brief Gets ID of currently running threading using std::this_thread::get_id() + static inline std::string getCurrentThreadId(void) { + std::stringstream ss; + ss << std::this_thread::get_id(); + return ss.str(); + } + static inline void msleep(int ms) { + // Only when async logging enabled - this is because async is strict on compiler +# if ELPP_ASYNC_LOGGING +# if defined(ELPP_NO_SLEEP_FOR) + usleep(ms * 1000); +# else + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); +# endif // defined(ELPP_NO_SLEEP_FOR) +# else + ELPP_UNUSED(ms); +# endif // ELPP_ASYNC_LOGGING + } + typedef std::mutex Mutex; + typedef std::lock_guard ScopedLock; +# endif // !ELPP_USE_STD_THREADING +#else + namespace internal { + /// @brief Mutex wrapper used when multi-threading is disabled. + class NoMutex : base::NoCopy { + public: + NoMutex(void) {} + inline void lock(void) {} + inline bool try_lock(void) { return true; } + inline void unlock(void) {} + }; + /// @brief Lock guard wrapper used when multi-threading is disabled. + template + class NoScopedLock : base::NoCopy { + public: + explicit NoScopedLock(Mutex&) { + } + virtual ~NoScopedLock(void) { + } + private: + NoScopedLock(void); + }; + } // namespace internal + static inline std::string getCurrentThreadId(void) { + return std::string(); + } + static inline void msleep(int) { + // No custom implementation + } + typedef base::threading::internal::NoMutex Mutex; + typedef base::threading::internal::NoScopedLock ScopedLock; +#endif // ELPP_THREADING_ENABLED + /// @brief Base of thread safe class, this class is inheritable-only + class ThreadSafe { + public: + virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); } + virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); } + virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; } + protected: + ThreadSafe(void) {} + virtual ~ThreadSafe(void) {} + private: + base::threading::Mutex m_mutex; + }; + } // namespace threading + namespace utils { + class File : base::StaticClass { + public: + /// @brief Creates new out file stream for specified filename. + /// @return Pointer to newly created fstream or nullptr + static base::type::fstream_t* newFileStream(const std::string& filename) { + base::type::fstream_t *fs = new base::type::fstream_t(filename.c_str(), + base::type::fstream_t::out +#if !defined(ELPP_FRESH_LOG_FILE) + | base::type::fstream_t::app +#endif + ); +#if defined(ELPP_UNICODE) + std::locale elppUnicodeLocale(""); +# if ELPP_OS_WINDOWS + std::locale elppUnicodeLocaleWindows(elppUnicodeLocale, new std::codecvt_utf8_utf16); + elppUnicodeLocale = elppUnicodeLocaleWindows; +# endif // ELPP_OS_WINDOWS + fs->imbue(elppUnicodeLocale); +#endif // defined(ELPP_UNICODE) + if (fs->is_open()) { + fs->flush(); + } else { + base::utils::safeDelete(fs); + ELPP_INTERNAL_ERROR("Bad file [" << filename << "]", true); + } + return fs; + } + + /// @brief Gets size of file provided in stream + static std::size_t getSizeOfFile(base::type::fstream_t* fs) { + if (fs == nullptr) { + return 0; + } + std::streampos currPos = fs->tellg(); + fs->seekg(0, fs->end); + std::size_t size = static_cast(fs->tellg()); + fs->seekg(currPos); + return size; + } + + /// @brief Determines whether or not provided path exist in current file system + static inline bool pathExists(const char* path, bool considerFile = false) { + if (path == nullptr) { + return false; + } +#if ELPP_OS_UNIX + ELPP_UNUSED(considerFile); + struct stat st; + return (stat(path, &st) == 0); +#elif ELPP_OS_WINDOWS + DWORD fileType = GetFileAttributesA(path); + if (fileType == INVALID_FILE_ATTRIBUTES) { + return false; + } + return considerFile ? true : ((fileType & FILE_ATTRIBUTE_DIRECTORY) == 0 ? false : true); +#endif // ELPP_OS_UNIX + } + + /// @brief Creates specified path on file system + /// @param path Path to create. + static bool createPath(const std::string& path) { + if (path.empty()) { + return false; + } + if (base::utils::File::pathExists(path.c_str())) { + return true; + } + int status = -1; + + char* currPath = const_cast(path.c_str()); + std::string builtPath = std::string(); +#if ELPP_OS_UNIX + if (path[0] == '/') { + builtPath = "/"; + } + currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0); +#elif ELPP_OS_WINDOWS + // Use secure functions API + char* nextTok_ = nullptr; + currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_); + ELPP_UNUSED(nextTok_); +#endif // ELPP_OS_UNIX + while (currPath != nullptr) { + builtPath.append(currPath); + builtPath.append(base::consts::kFilePathSeperator); +#if ELPP_OS_UNIX + status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS); + currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, 0); +#elif ELPP_OS_WINDOWS + status = _mkdir(builtPath.c_str()); + currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, &nextTok_); +#endif // ELPP_OS_UNIX + } + if (status == -1) { + ELPP_INTERNAL_ERROR("Error while creating path [" << path << "]", true); + return false; + } + return true; + } + /// @brief Extracts path of filename with leading slash + static std::string extractPathFromFilename(const std::string& fullPath, + const char* seperator = base::consts::kFilePathSeperator) { + if ((fullPath == "") || (fullPath.find(seperator) == std::string::npos)) { + return fullPath; + } + std::size_t lastSlashAt = fullPath.find_last_of(seperator); + if (lastSlashAt == 0) { + return std::string(seperator); + } + return fullPath.substr(0, lastSlashAt + 1); + } + /// @brief builds stripped filename and puts it in buff + static void buildStrippedFilename(const char* filename, char buff[], + std::size_t limit = base::consts::kSourceFilenameMaxLength) { + std::size_t sizeOfFilename = strlen(filename); + if (sizeOfFilename >= limit) { + filename += (sizeOfFilename - limit); + if (filename[0] != '.' && filename[1] != '.') { // prepend if not already + filename += 3; // 3 = '..' + STRCAT(buff, "..", limit); + } + } + STRCAT(buff, filename, limit); + } + /// @brief builds base filename and puts it in buff + static void buildBaseFilename(const std::string& fullPath, char buff[], + std::size_t limit = base::consts::kSourceFilenameMaxLength, + const char* seperator = base::consts::kFilePathSeperator) { + const char *filename = fullPath.c_str(); + std::size_t lastSlashAt = fullPath.find_last_of(seperator); + filename += lastSlashAt ? lastSlashAt+1 : 0; + std::size_t sizeOfFilename = strlen(filename); + if (sizeOfFilename >= limit) { + filename += (sizeOfFilename - limit); + if (filename[0] != '.' && filename[1] != '.') { // prepend if not already + filename += 3; // 3 = '..' + STRCAT(buff, "..", limit); + } + } + STRCAT(buff, filename, limit); + } + }; + /// @brief String utilities helper class used internally. You should not use it. + class Str : base::StaticClass { + public: + /// @brief Checks if character is digit. Dont use libc implementation of it to prevent locale issues. + static inline bool isDigit(char c) { + return c >= '0' && c <= '9'; + } + + /// @brief Matches wildcards, '*' and '?' only supported. + static bool wildCardMatch(const char* str, const char* pattern) { + while (*pattern) { + switch (*pattern) { + case '?': + if (!*str) + return false; + ++str; + ++pattern; + break; + case '*': + if (wildCardMatch(str, pattern + 1)) + return true; + if (*str && wildCardMatch(str + 1, pattern)) + return true; + return false; + default: + if (*str++ != *pattern++) + return false; + break; + } + } + return !*str && !*pattern; + } + + /// @brief Trims string from start + /// @param [in,out] str String to trim + static inline std::string& ltrim(std::string& str) { + str.erase(str.begin(), std::find_if(str.begin(), str.end(), std::not1(std::ptr_fun(&std::isspace)))); + return str; + } + + /// @brief Trim string from end + /// @param [in,out] str String to trim + static inline std::string& rtrim(std::string& str) { + str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun(&std::isspace))).base(), str.end()); + return str; + } + + /// @brief Trims string from left and right + /// @param [in,out] str String to trim + static inline std::string& trim(std::string& str) { + return ltrim(rtrim(str)); + } + + /// @brief Determines whether or not str starts with specified string + /// @param str String to check + /// @param start String to check against + /// @return Returns true if starts with specified string, false otherwise + static inline bool startsWith(const std::string& str, const std::string& start) { + return (str.length() >= start.length()) && (str.compare(0, start.length(), start) == 0); + } + + /// @brief Determines whether or not str ends with specified string + /// @param str String to check + /// @param end String to check against + /// @return Returns true if ends with specified string, false otherwise + static inline bool endsWith(const std::string& str, const std::string& end) { + return (str.length() >= end.length()) && (str.compare(str.length() - end.length(), end.length(), end) == 0); + } + + /// @brief Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performance. + /// @param [in,out] str String to replace from + /// @param replaceWhat Character to replace + /// @param replaceWith Character to replace with + /// @return Modified version of str + static inline std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith) { + std::replace(str.begin(), str.end(), replaceWhat, replaceWith); + return str; + } + + /// @brief Replaces all instances of 'replaceWhat' with 'replaceWith'. (String version) Replaces in place + /// @param str String to replace from + /// @param replaceWhat Character to replace + /// @param replaceWith Character to replace with + /// @return Modified (original) str + static inline std::string& replaceAll(std::string& str, const std::string& replaceWhat, // NOLINT + const std::string& replaceWith) { + if (replaceWhat == replaceWith) + return str; + std::size_t foundAt = std::string::npos; + while ((foundAt = str.find(replaceWhat, foundAt + 1)) != std::string::npos) { + str.replace(foundAt, replaceWhat.length(), replaceWith); + } + return str; + } + + static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, // NOLINT + const base::type::string_t& replaceWith) { + std::size_t foundAt = base::type::string_t::npos; + while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) { + if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) { + str.erase(foundAt > 0 ? foundAt - 1 : 0, 1); + ++foundAt; + } else { + str.replace(foundAt, replaceWhat.length(), replaceWith); + return; + } + } + } +#if defined(ELPP_UNICODE) + static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat, // NOLINT + const std::string& replaceWith) { + replaceFirstWithEscape(str, replaceWhat, base::type::string_t(replaceWith.begin(), replaceWith.end())); + } +#endif // defined(ELPP_UNICODE) + /// @brief Converts string to uppercase + /// @param str String to convert + /// @return Uppercase string + static inline std::string& toUpper(std::string& str) { + std::transform(str.begin(), str.end(), str.begin(), ::toupper); + return str; + } + + /// @brief Compares cstring equality - uses strcmp + static inline bool cStringEq(const char* s1, const char* s2) { + if (s1 == nullptr && s2 == nullptr) return true; + if (s1 == nullptr || s2 == nullptr) return false; + return strcmp(s1, s2) == 0; + } + + /// @brief Compares cstring equality (case-insensitive) - uses toupper(char) + /// Dont use strcasecmp because of CRT (VC++) + static bool cStringCaseEq(const char* s1, const char* s2) { + if (s1 == nullptr && s2 == nullptr) return true; + if (s1 == nullptr || s2 == nullptr) return false; + if (strlen(s1) != strlen(s2)) return false; + while (*s1 != '\0' && *s2 != '\0') { + if (::toupper(*s1) != ::toupper(*s2)) return false; + ++s1; + ++s2; + } + return true; + } + + /// @brief Returns true if c exist in str + static inline bool contains(const char* str, char c) { + for (; *str; ++str) { + if (*str == c) + return true; + } + return false; + } + + static inline char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true) { + char localBuff[10] = ""; + char* p = localBuff + sizeof(localBuff) - 2; + if (n > 0) { + for (; n > 0 && p > localBuff && len > 0; n /= 10, --len) + *--p = static_cast(n % 10 + '0'); + } else { + *--p = '0'; + --len; + } + if (zeroPadded) + while (p > localBuff && len-- > 0) *--p = static_cast('0'); + return addToBuff(p, buf, bufLim); + } + + static inline char* addToBuff(const char* str, char* buf, const char* bufLim) { + while ((buf < bufLim) && ((*buf = *str++) != '\0')) + ++buf; + return buf; + } + + static inline char* clearBuff(char buff[], std::size_t lim) { + STRCPY(buff, "", lim); + ELPP_UNUSED(lim); // For *nix we dont have anything using lim in above STRCPY macro + return buff; + } + + /// @brief Converst wchar* to char* + /// NOTE: Need to free return value after use! + static char* wcharPtrToCharPtr(const wchar_t* line) { + std::size_t len_ = wcslen(line) + 1; + char* buff_ = static_cast(malloc(len_ + 1)); +# if ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) + std::wcstombs(buff_, line, len_); +# elif ELPP_OS_WINDOWS + std::size_t convCount_ = 0; + mbstate_t mbState_; + ::memset(static_cast(&mbState_), 0, sizeof(mbState_)); + wcsrtombs_s(&convCount_, buff_, len_, &line, len_, &mbState_); +# endif // ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) + return buff_; + } + }; + /// @brief Operating System helper static class used internally. You should not use it. + class OS : base::StaticClass { + public: +#if ELPP_OS_WINDOWS + /// @brief Gets environment variables for Windows based OS. + /// We are not using getenv(const char*) because of CRT deprecation + /// @param varname Variable name to get environment variable value for + /// @return If variable exist the value of it otherwise nullptr + static const char* getWindowsEnvironmentVariable(const char* varname) { + const DWORD bufferLen = 50; + static char buffer[bufferLen]; + if (GetEnvironmentVariableA(varname, buffer, bufferLen)) { + return buffer; + } + return nullptr; + } +#endif // ELPP_OS_WINDOWS +#if ELPP_OS_ANDROID + /// @brief Reads android property value + static inline std::string getProperty(const char* prop) { + char propVal[PROP_VALUE_MAX + 1]; + int ret = __system_property_get(prop, propVal); + return ret == 0 ? std::string() : std::string(propVal); + } + + /// @brief Reads android device name + static std::string getDeviceName(void) { + std::stringstream ss; + std::string manufacturer = getProperty("ro.product.manufacturer"); + std::string model = getProperty("ro.product.model"); + if (manufacturer.empty() || model.empty()) { + return std::string(); + } + ss << manufacturer << "-" << model; + return ss.str(); + } +#endif // ELPP_OS_ANDROID + + /// @brief Runs command on terminal and returns the output. + /// + /// @detail This is applicable only on unix based systems, for all other OS, an empty string is returned. + /// @param command Bash command + /// @return Result of bash output or empty string if no result found. + static const std::string getBashOutput(const char* command) { +#if (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) + if (command == nullptr) { + return std::string(); + } + FILE* proc = nullptr; + if ((proc = popen(command, "r")) == nullptr) { + ELPP_INTERNAL_ERROR("\nUnable to run command [" << command << "]", true); + return std::string(); + } + char hBuff[4096]; + if (fgets(hBuff, sizeof(hBuff), proc) != nullptr) { + pclose(proc); + if (hBuff[strlen(hBuff) - 1] == '\n') { + hBuff[strlen(hBuff) - 1] = '\0'; + } + return std::string(hBuff); + } + return std::string(); +#else + ELPP_UNUSED(command); + return std::string(); +#endif // (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) + } + + /// @brief Gets environment variable. This is cross-platform and CRT safe (for VC++) + /// @param variableName Environment variable name + /// @param defaultVal If no environment variable or value found the value to return by default + /// @param alternativeBashCommand If environment variable not found what would be alternative bash command + /// in order to look for value user is looking for. E.g, for 'user' alternative command will 'whoami' + static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal, const char* alternativeBashCommand = nullptr) { +#if ELPP_OS_UNIX + const char* val = getenv(variableName); +#elif ELPP_OS_WINDOWS + const char* val = getWindowsEnvironmentVariable(variableName); +#endif // ELPP_OS_UNIX + if ((val == nullptr) || ((strcmp(val, "") == 0))) { +#if ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) + // Try harder on unix-based systems + std::string valBash = base::utils::OS::getBashOutput(alternativeBashCommand); + if (valBash.empty()) { + return std::string(defaultVal); + } else { + return valBash; + } +#elif ELPP_OS_WINDOWS || ELPP_OS_UNIX + ELPP_UNUSED(alternativeBashCommand); + return std::string(defaultVal); +#endif // ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) + } + return std::string(val); + } + /// @brief Gets current username. + static inline std::string currentUser(void) { +#if ELPP_OS_UNIX && !ELPP_OS_ANDROID + return getEnvironmentVariable("USER", base::consts::kUnknownUser, "whoami"); +#elif ELPP_OS_WINDOWS + return getEnvironmentVariable("USERNAME", base::consts::kUnknownUser); +#elif ELPP_OS_ANDROID + ELPP_UNUSED(base::consts::kUnknownUser); + return std::string("android"); +#else + return std::string(); +#endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID + } + + /// @brief Gets current host name or computer name. + /// + /// @detail For android systems this is device name with its manufacturer and model seperated by hyphen + static inline std::string currentHost(void) { +#if ELPP_OS_UNIX && !ELPP_OS_ANDROID + return getEnvironmentVariable("HOSTNAME", base::consts::kUnknownHost, "hostname"); +#elif ELPP_OS_WINDOWS + return getEnvironmentVariable("COMPUTERNAME", base::consts::kUnknownHost); +#elif ELPP_OS_ANDROID + ELPP_UNUSED(base::consts::kUnknownHost); + return getDeviceName(); +#else + return std::string(); +#endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID + } + /// @brief Whether or not terminal supports colors + static inline bool termSupportsColor(void) { + std::string term = getEnvironmentVariable("TERM", ""); + return term == "xterm" || term == "xterm-color" || term == "xterm-256color" + || term == "screen" || term == "linux" || term == "cygwin" + || term == "screen-256color"; + } + }; + extern std::string s_currentUser; + extern std::string s_currentHost; + extern bool s_termSupportsColor; +#define ELPP_INITI_BASIC_DECLR \ +namespace el {\ +namespace base {\ +namespace utils {\ +std::string s_currentUser = el::base::utils::OS::currentUser(); \ +std::string s_currentHost = el::base::utils::OS::currentHost(); \ +bool s_termSupportsColor = el::base::utils::OS::termSupportsColor(); \ +}\ +}\ +} + /// @brief Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str + class DateTime : base::StaticClass { + public: + /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current millisecond. + /// + /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided + /// @param [in,out] tv Pointer that gets updated + static void gettimeofday(struct timeval* tv) { +#if ELPP_OS_WINDOWS + if (tv != nullptr) { +# if ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) + const unsigned __int64 delta_ = 11644473600000000Ui64; +# else + const unsigned __int64 delta_ = 11644473600000000ULL; +# endif // ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) + const double secOffSet = 0.000001; + const unsigned long usecOffSet = 1000000; + FILETIME fileTime; + GetSystemTimeAsFileTime(&fileTime); + unsigned __int64 present = 0; + present |= fileTime.dwHighDateTime; + present = present << 32; + present |= fileTime.dwLowDateTime; + present /= 10; // mic-sec + // Subtract the difference + present -= delta_; + tv->tv_sec = static_cast(present * secOffSet); + tv->tv_usec = static_cast(present % usecOffSet); + } +#else + ::gettimeofday(tv, nullptr); +#endif // ELPP_OS_WINDOWS + } + + /// @brief Gets current date and time with milliseconds. + /// @param format User provided date/time format + /// @param msWidth A pointer to base::MillisecondsWidth from configuration (non-null) + /// @returns string based date time in specified format. + static inline std::string getDateTime(const char* format, const base::MillisecondsWidth* msWidth) { + struct timeval currTime; + gettimeofday(&currTime); + struct ::tm timeInfo; + buildTimeInfo(&currTime, &timeInfo); + const int kBuffSize = 30; + char buff_[kBuffSize] = ""; + parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast(currTime.tv_usec / msWidth->m_offset), msWidth); + return std::string(buff_); + } + + /// @brief Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc + static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit) { + double result = static_cast(time); + base::type::EnumType start = static_cast(timestampUnit); + const base::type::char_t* unit = base::consts::kTimeFormats[start].unit; + for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) { + if (result <= base::consts::kTimeFormats[i].value) { + break; + } + result /= base::consts::kTimeFormats[i].value; + unit = base::consts::kTimeFormats[i + 1].unit; + } + base::type::stringstream_t ss; + ss << result << " " << unit; + return ss.str(); + } + + /// @brief Gets time difference in milli/micro second depending on timestampUnit + static inline unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime, base::TimestampUnit timestampUnit) { + if (timestampUnit == base::TimestampUnit::Microsecond) { + return static_cast(static_cast(1000000 * endTime.tv_sec + endTime.tv_usec) - + static_cast(1000000 * startTime.tv_sec + startTime.tv_usec)); + } else { + return static_cast((((endTime.tv_sec - startTime.tv_sec) * 1000000) + (endTime.tv_usec - startTime.tv_usec)) / 1000); + } + } + + private: + static inline struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo) { +#if ELPP_OS_UNIX + time_t rawTime = currTime->tv_sec; + ::localtime_r(&rawTime, timeInfo); + return timeInfo; +#else +# if ELPP_COMPILER_MSVC + ELPP_UNUSED(currTime); + time_t t; + _time64(&t); + localtime_s(timeInfo, &t); + return timeInfo; +# else + // For any other compilers that don't have CRT warnings issue e.g, MinGW or TDM GCC- we use different method + time_t rawTime = currTime->tv_sec; + struct tm* tmInf = localtime(&rawTime); + *timeInfo = *tmInf; + return timeInfo; +# endif // ELPP_COMPILER_MSVC +#endif // ELPP_OS_UNIX + } + static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo, + std::size_t msec, const base::MillisecondsWidth* msWidth) { + const char* bufLim = buf + bufSz; + for (; *format; ++format) { + if (*format == base::consts::kFormatSpecifierChar) { + switch (*++format) { + case base::consts::kFormatSpecifierChar: // Escape + break; + case '\0': // End + --format; + break; + case 'd': // Day + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, bufLim); + continue; + case 'a': // Day of week (short) + buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim); + continue; + case 'A': // Day of week (long) + buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim); + continue; + case 'M': // month + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, bufLim); + continue; + case 'b': // month (short) + buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim); + continue; + case 'B': // month (long) + buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim); + continue; + case 'y': // year (two digits) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim); + continue; + case 'Y': // year (four digits) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim); + continue; + case 'h': // hour (12-hour) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim); + continue; + case 'H': // hour (24-hour) + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, bufLim); + continue; + case 'm': // minute + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, bufLim); + continue; + case 's': // second + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, bufLim); + continue; + case 'z': // milliseconds + case 'g': + buf = base::utils::Str::convertAndAddToBuff(msec, msWidth->m_width, buf, bufLim); + continue; + case 'F': // AM/PM + buf = base::utils::Str::addToBuff((tInfo->tm_hour >= 12) ? base::consts::kPm : base::consts::kAm, buf, bufLim); + continue; + default: + continue; + } + } + if (buf == bufLim) break; + *buf++ = *format; + } + return buf; + } + }; + /// @brief Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGINGPP(..) + class CommandLineArgs { + public: + CommandLineArgs(void) { + setArgs(0, static_cast(nullptr)); + } + CommandLineArgs(int argc, const char** argv) { + setArgs(argc, argv); + } + CommandLineArgs(int argc, char** argv) { + setArgs(argc, argv); + } + virtual ~CommandLineArgs(void) {} + /// @brief Sets arguments and parses them + inline void setArgs(int argc, const char** argv) { + setArgs(argc, const_cast(argv)); + } + /// @brief Sets arguments and parses them + inline void setArgs(int argc, char** argv) { + m_params.clear(); + m_paramsWithValue.clear(); + if (argc == 0 || argv == nullptr) { + return; + } + m_argc = argc; + m_argv = argv; + for (int i = 1; i < m_argc; ++i) { + const char* v = (strstr(m_argv[i], "=")); + if (v != nullptr && strlen(v) > 0) { + std::string key = std::string(m_argv[i]); + key = key.substr(0, key.find_first_of('=')); + if (hasParamWithValue(key.c_str())) { + ELPP_INTERNAL_INFO(1, "Skipping [" << key << "] arg since it already has value [" + << getParamValue(key.c_str()) << "]"); + } else { + m_paramsWithValue.insert(std::make_pair(key, std::string(v + 1))); + } + } + if (v == nullptr) { + if (hasParam(m_argv[i])) { + ELPP_INTERNAL_INFO(1, "Skipping [" << m_argv[i] << "] arg since it already exists"); + } else { + m_params.push_back(std::string(m_argv[i])); + } + } + } + } + /// @brief Returns true if arguments contain paramKey with a value (seperated by '=') + inline bool hasParamWithValue(const char* paramKey) const { + return m_paramsWithValue.find(std::string(paramKey)) != m_paramsWithValue.end(); + } + /// @brief Returns value of arguments + /// @see hasParamWithValue(const char*) + inline const char* getParamValue(const char* paramKey) const { + return m_paramsWithValue.find(std::string(paramKey))->second.c_str(); + } + /// @brief Return true if arguments has a param (not having a value) i,e without '=' + inline bool hasParam(const char* paramKey) const { + return std::find(m_params.begin(), m_params.end(), std::string(paramKey)) != m_params.end(); + } + /// @brief Returns true if no params available. This exclude argv[0] + inline bool empty(void) const { + return m_params.empty() && m_paramsWithValue.empty(); + } + /// @brief Returns total number of arguments. This exclude argv[0] + inline std::size_t size(void) const { + return m_params.size() + m_paramsWithValue.size(); + } + inline friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c) { + for (int i = 1; i < c.m_argc; ++i) { + os << ELPP_LITERAL("[") << c.m_argv[i] << ELPP_LITERAL("]"); + if (i < c.m_argc - 1) { + os << ELPP_LITERAL(" "); + } + } + return os; + } + + private: + int m_argc; + char** m_argv; + std::map m_paramsWithValue; + std::vector m_params; + }; + /// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type. + /// + /// @detail Most of the functions are virtual final methods but anything implementing this abstract class should implement + /// unregisterAll() and deepCopy(const AbstractRegistry&) and write registerNew() method according to container + /// and few more methods; get() to find element, unregister() to unregister single entry. + /// Please note that this is thread-unsafe and should also implement thread-safety mechanisms in implementation. + template + class AbstractRegistry : public base::threading::ThreadSafe { + public: + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + + /// @brief Default constructor + AbstractRegistry(void) {} + + /// @brief Move constructor that is useful for base classes + AbstractRegistry(AbstractRegistry&& sr) { + if (this == &sr) { + return; + } + unregisterAll(); + m_list = std::move(sr.m_list); + } + + bool operator==(const AbstractRegistry& other) { + if (size() != other.size()) { + return false; + } + for (std::size_t i = 0; i < m_list.size(); ++i) { + if (m_list.at(i) != other.m_list.at(i)) { + return false; + } + } + return true; + } + + bool operator!=(const AbstractRegistry& other) { + if (size() != other.size()) { + return true; + } + for (std::size_t i = 0; i < m_list.size(); ++i) { + if (m_list.at(i) != other.m_list.at(i)) { + return true; + } + } + return false; + } + + /// @brief Assignment move operator + AbstractRegistry& operator=(AbstractRegistry&& sr) { + if (this == &sr) { + return *this; + } + unregisterAll(); + m_list = std::move(sr.m_list); + return *this; + } + + virtual ~AbstractRegistry(void) { + } + + /// @return Iterator pointer from start of repository + virtual inline iterator begin(void) ELPP_FINAL { + return m_list.begin(); + } + + /// @return Iterator pointer from end of repository + virtual inline iterator end(void) ELPP_FINAL { + return m_list.end(); + } + + + /// @return Constant iterator pointer from start of repository + virtual inline const_iterator cbegin(void) const ELPP_FINAL { + return m_list.cbegin(); + } + + /// @return End of repository + virtual inline const_iterator cend(void) const ELPP_FINAL { + return m_list.cend(); + } + + /// @return Whether or not repository is empty + virtual inline bool empty(void) const ELPP_FINAL { + return m_list.empty(); + } + + /// @return Size of repository + virtual inline std::size_t size(void) const ELPP_FINAL { + return m_list.size(); + } + + /// @brief Returns underlying container by reference + virtual inline Container& list(void) ELPP_FINAL { + return m_list; + } + + /// @brief Returns underlying container by constant reference. + virtual inline const Container& list(void) const ELPP_FINAL { + return m_list; + } + + /// @brief Unregisters all the pointers from current repository. + virtual void unregisterAll(void) = 0; + +protected: + virtual void deepCopy(const AbstractRegistry&) = 0; + void reinitDeepCopy(const AbstractRegistry& sr) { + unregisterAll(); + deepCopy(sr); + } + +private: + Container m_list; +}; + +/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate version) +/// +/// @detail NOTE: This is thread-unsafe implementation (although it contains lock function, it does not use these functions) +/// of AbstractRegistry. Any implementation of this class should be +/// explicitly (by using lock functions) +template +class Registry : public AbstractRegistry> { +public: + typedef typename Registry::iterator iterator; + typedef typename Registry::const_iterator const_iterator; + + Registry(void) {} + + /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. + Registry(const Registry& sr) : AbstractRegistry>() { + if (this == &sr) { + return; + } + this->reinitDeepCopy(sr); + } + + /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element + /// @see unregisterAll() + /// @see deepCopy(const AbstractRegistry&) + Registry& operator=(const Registry& sr) { + if (this == &sr) { + return *this; + } + this->reinitDeepCopy(sr); + return *this; + } + + virtual ~Registry(void) { + unregisterAll(); + } + +protected: + virtual inline void unregisterAll(void) ELPP_FINAL { + if (!this->empty()) { + for (auto&& curr : this->list()) { + base::utils::safeDelete(curr.second); + } + this->list().clear(); + } +} + +/// @brief Registers new registry to repository. +virtual inline void registerNew(const T_Key& uniqKey, T_Ptr* ptr) ELPP_FINAL { +unregister(uniqKey); +this->list().insert(std::make_pair(uniqKey, ptr)); +} + +/// @brief Unregisters single entry mapped to specified unique key +inline void unregister(const T_Key& uniqKey) { + T_Ptr* existing = get(uniqKey); + if (existing != nullptr) { + base::utils::safeDelete(existing); + this->list().erase(uniqKey); + } +} + +/// @brief Gets pointer from repository. If none found, nullptr is returned. +inline T_Ptr* get(const T_Key& uniqKey) { + iterator it = this->list().find(uniqKey); + return it == this->list().end() + ? nullptr + : it->second; +} + +private: +virtual inline void deepCopy(const AbstractRegistry>& sr) ELPP_FINAL { +for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) { + registerNew(it->first, new T_Ptr(*it->second)); +} +} +}; + +/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (predicate version) +/// +/// @detail NOTE: This is thread-unsafe implementation of AbstractRegistry. Any implementation of this class +/// should be made thread-safe explicitly +template +class RegistryWithPred : public AbstractRegistry> { +public: + typedef typename RegistryWithPred::iterator iterator; + typedef typename RegistryWithPred::const_iterator const_iterator; + + RegistryWithPred(void) { + } + + virtual ~RegistryWithPred(void) { + unregisterAll(); + } + + /// @brief Copy constructor that is useful for base classes. Try to avoid this constructor, use move constructor. + RegistryWithPred(const RegistryWithPred& sr) : AbstractRegistry>() { + if (this == &sr) { + return; + } + this->reinitDeepCopy(sr); + } + + /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element + /// @see unregisterAll() + /// @see deepCopy(const AbstractRegistry&) + RegistryWithPred& operator=(const RegistryWithPred& sr) { + if (this == &sr) { + return *this; + } + this->reinitDeepCopy(sr); + return *this; + } + + friend inline base::type::ostream_t& operator<<(base::type::ostream_t& os, const RegistryWithPred& sr) { + for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { + os << ELPP_LITERAL(" ") << **it << ELPP_LITERAL("\n"); + } + return os; + } + +protected: + virtual inline void unregisterAll(void) ELPP_FINAL { + if (!this->empty()) { + for (auto&& curr : this->list()) { + base::utils::safeDelete(curr); + } + this->list().clear(); + } +} + +virtual void unregister(T_Ptr*& ptr) ELPP_FINAL { +if (ptr) { + iterator iter = this->begin(); + for (; iter != this->end(); ++iter) { + if (ptr == *iter) { + break; + } + } + if (iter != this->end() && *iter != nullptr) { + this->list().erase(iter); + base::utils::safeDelete(*iter); + } +} +} + +virtual inline void registerNew(T_Ptr* ptr) ELPP_FINAL { +this->list().push_back(ptr); +} + +/// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate +/// in order to validate pointer. +template +inline T_Ptr* get(const T& arg1, const T2 arg2) { + iterator iter = std::find_if(this->list().begin(), this->list().end(), Pred(arg1, arg2)); + if (iter != this->list().end() && *iter != nullptr) { + return *iter; + } + return nullptr; +} + +private: +virtual inline void deepCopy(const AbstractRegistry>& sr) { + for (const_iterator it = sr.list().begin(); it != sr.list().end(); ++it) { + registerNew(new T_Ptr(**it)); + } +} +}; + +} // namespace utils +} // namespace base +/// @brief Base of Easylogging++ friendly class +/// +/// @detail After inheriting this class publicly, implement pure-virtual function `void log(std::ostream&) const` +class Loggable { +public: + virtual ~Loggable(void) {} + virtual void log(el::base::type::ostream_t&) const = 0; +private: + friend inline el::base::type::ostream_t& operator<<(el::base::type::ostream_t& os, const Loggable& loggable) { + loggable.log(os); + return os; + } +}; +namespace base { + /// @brief Represents log format containing flags and date format. This is used internally to start initial log + class LogFormat : public Loggable { + public: + LogFormat(void) : + m_level(Level::Unknown), + m_userFormat(base::type::string_t()), + m_format(base::type::string_t()), + m_dateTimeFormat(std::string()), + m_flags(0x0) { + } + + LogFormat(Level level, const base::type::string_t& format) + : m_level(level), m_userFormat(format) { + parseFromFormat(m_userFormat); + } + + LogFormat(const LogFormat& logFormat) { + m_level = logFormat.m_level; + m_userFormat = logFormat.m_userFormat; + m_format = logFormat.m_format; + m_dateTimeFormat = logFormat.m_dateTimeFormat; + m_flags = logFormat.m_flags; + } + + LogFormat(LogFormat&& logFormat) { + m_level = std::move(logFormat.m_level); + m_userFormat = std::move(logFormat.m_userFormat); + m_format = std::move(logFormat.m_format); + m_dateTimeFormat = std::move(logFormat.m_dateTimeFormat); + m_flags = std::move(logFormat.m_flags); + } + + LogFormat& operator=(const LogFormat& logFormat) { + m_level = logFormat.m_level; + m_userFormat = logFormat.m_userFormat; + m_dateTimeFormat = logFormat.m_dateTimeFormat; + m_flags = logFormat.m_flags; + return *this; + } + + virtual ~LogFormat(void) { + } + + inline bool operator==(const LogFormat& other) { + return m_level == other.m_level && m_userFormat == other.m_userFormat && m_format == other.m_format && + m_dateTimeFormat == other.m_dateTimeFormat && m_flags == other.m_flags; + } + + /// @brief Updates format to be used while logging. + /// @param userFormat User provided format + void parseFromFormat(const base::type::string_t& userFormat) { + // We make copy because we will be changing the format + // i.e, removing user provided date format from original format + // and then storing it. + base::type::string_t formatCopy = userFormat; + m_flags = 0x0; + auto conditionalAddFlag = [&](const base::type::char_t* specifier, base::FormatFlags flag) { + std::size_t foundAt = base::type::string_t::npos; + while ((foundAt = formatCopy.find(specifier, foundAt + 1)) != base::type::string_t::npos){ + if (foundAt > 0 && formatCopy[foundAt - 1] == base::consts::kFormatSpecifierChar) { + if (hasFlag(flag)) { + // If we already have flag we remove the escape chars so that '%%' is turned to '%' + // even after specifier resolution - this is because we only replaceFirst specifier + formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1); + ++foundAt; + } + } else { + if (!hasFlag(flag)) addFlag(flag); + } + } + }; + conditionalAddFlag(base::consts::kAppNameFormatSpecifier, base::FormatFlags::AppName); + conditionalAddFlag(base::consts::kSeverityLevelFormatSpecifier, base::FormatFlags::Level); + conditionalAddFlag(base::consts::kSeverityLevelShortFormatSpecifier, base::FormatFlags::LevelShort); + conditionalAddFlag(base::consts::kLoggerIdFormatSpecifier, base::FormatFlags::LoggerId); + conditionalAddFlag(base::consts::kThreadIdFormatSpecifier, base::FormatFlags::ThreadId); + conditionalAddFlag(base::consts::kLogFileFormatSpecifier, base::FormatFlags::File); + conditionalAddFlag(base::consts::kLogFileBaseFormatSpecifier, base::FormatFlags::FileBase); + conditionalAddFlag(base::consts::kLogLineFormatSpecifier, base::FormatFlags::Line); + conditionalAddFlag(base::consts::kLogLocationFormatSpecifier, base::FormatFlags::Location); + conditionalAddFlag(base::consts::kLogFunctionFormatSpecifier, base::FormatFlags::Function); + conditionalAddFlag(base::consts::kCurrentUserFormatSpecifier, base::FormatFlags::User); + conditionalAddFlag(base::consts::kCurrentHostFormatSpecifier, base::FormatFlags::Host); + conditionalAddFlag(base::consts::kMessageFormatSpecifier, base::FormatFlags::LogMessage); + conditionalAddFlag(base::consts::kVerboseLevelFormatSpecifier, base::FormatFlags::VerboseLevel); + // For date/time we need to extract user's date format first + std::size_t dateIndex = std::string::npos; + if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) { + while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) { + dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1); + } + if (dateIndex != std::string::npos) { + addFlag(base::FormatFlags::DateTime); + updateDateFormat(dateIndex, formatCopy); + } + } + m_format = formatCopy; + updateFormatSpec(); + } + + inline Level level(void) const { + return m_level; + } + + inline const base::type::string_t& userFormat(void) const { + return m_userFormat; + } + + inline const base::type::string_t& format(void) const { + return m_format; + } + + inline const std::string& dateTimeFormat(void) const { + return m_dateTimeFormat; + } + + inline base::type::EnumType flags(void) const { + return m_flags; + } + + inline bool hasFlag(base::FormatFlags flag) const { + return base::utils::hasFlag(flag, m_flags); + } + + virtual void log(el::base::type::ostream_t& os) const { + os << m_format; + } + + protected: + /// @brief Updates date time format if available in currFormat. + /// @param index Index where %datetime, %date or %time was found + /// @param [in,out] currFormat current format that is being used to format + virtual void updateDateFormat(std::size_t index, base::type::string_t& currFormat) ELPP_FINAL { + if (hasFlag(base::FormatFlags::DateTime)) { + index += ELPP_STRLEN(base::consts::kDateTimeFormatSpecifier); + } + const base::type::char_t* ptr = currFormat.c_str() + index; + if ((currFormat.size() > index) && (ptr[0] == '{')) { + // User has provided format for date/time + ++ptr; + int count = 1; // Start by 1 in order to remove starting brace + std::stringstream ss; + for (; *ptr; ++ptr, ++count) { + if (*ptr == '}') { + ++count; // In order to remove ending brace + break; + } + ss << *ptr; + } + currFormat.erase(index, count); + m_dateTimeFormat = ss.str(); + } else { + // No format provided, use default + if (hasFlag(base::FormatFlags::DateTime)) { + m_dateTimeFormat = std::string(base::consts::kDefaultDateTimeFormat); + } + } + } + + /// @brief Updates %level from format. This is so that we dont have to do it at log-writing-time. It uses m_format and m_level + virtual void updateFormatSpec(void) ELPP_FINAL { + // Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet. + if (m_level == Level::Debug) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kDebugLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kDebugLevelShortLogValue); + } else if (m_level == Level::Info) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kInfoLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kInfoLevelShortLogValue); + } else if (m_level == Level::Warning) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kWarningLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kWarningLevelShortLogValue); + } else if (m_level == Level::Error) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kErrorLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kErrorLevelShortLogValue); + } else if (m_level == Level::Fatal) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kFatalLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kFatalLevelShortLogValue); + } else if (m_level == Level::Verbose) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kVerboseLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kVerboseLevelShortLogValue); + } else if (m_level == Level::Trace) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelFormatSpecifier, + base::consts::kTraceLevelLogValue); + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kSeverityLevelShortFormatSpecifier, + base::consts::kTraceLevelShortLogValue); + } + if (hasFlag(base::FormatFlags::User)) { + std::string s = base::utils::s_currentUser; + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentUserFormatSpecifier, + base::utils::s_currentUser); + } + if (hasFlag(base::FormatFlags::Host)) { + base::utils::Str::replaceFirstWithEscape(m_format, base::consts::kCurrentHostFormatSpecifier, + base::utils::s_currentHost); + } + // Ignore Level::Global and Level::Unknown + } + + inline void addFlag(base::FormatFlags flag) { + base::utils::addFlag(flag, &m_flags); + } + + private: + Level m_level; + base::type::string_t m_userFormat; + base::type::string_t m_format; + std::string m_dateTimeFormat; + base::type::EnumType m_flags; + friend class el::Logger; // To resolve loggerId format specifier easily + }; +} // namespace base +/// @brief Resolving function for format specifier +typedef std::function FormatSpecifierValueResolver; +/// @brief User-provided custom format specifier +/// @see el::Helpers::installCustomFormatSpecifier +/// @see FormatSpecifierValueResolver +class CustomFormatSpecifier { +public: + CustomFormatSpecifier(const char* formatSpecifier, const FormatSpecifierValueResolver& resolver) : + m_formatSpecifier(formatSpecifier), m_resolver(resolver) {} + inline const char* formatSpecifier(void) const { return m_formatSpecifier; } + inline const FormatSpecifierValueResolver& resolver(void) const { return m_resolver; } + inline bool operator==(const char* formatSpecifier) { + return strcmp(m_formatSpecifier, formatSpecifier) == 0; + } + +private: + const char* m_formatSpecifier; + FormatSpecifierValueResolver m_resolver; +}; +/// @brief Represents single configuration that has representing level, configuration type and a string based value. +/// +/// @detail String based value means any value either its boolean, integer or string itself, it will be embedded inside quotes +/// and will be parsed later. +/// +/// Consider some examples below: +/// * el::Configuration confEnabledInfo(el::Level::Info, el::ConfigurationType::Enabled, "true"); +/// * el::Configuration confMaxLogFileSizeInfo(el::Level::Info, el::ConfigurationType::MaxLogFileSize, "2048"); +/// * el::Configuration confFilenameInfo(el::Level::Info, el::ConfigurationType::Filename, "/var/log/my.log"); +class Configuration : public Loggable { +public: + Configuration(const Configuration& c) : + m_level(c.m_level), + m_configurationType(c.m_configurationType), + m_value(c.m_value) { + } + + Configuration& operator=(const Configuration& c) { + m_level = c.m_level; + m_configurationType = c.m_configurationType; + m_value = c.m_value; + return *this; + } + + virtual ~Configuration(void) { + } + + /// @brief Full constructor used to sets value of configuration + Configuration(Level level, ConfigurationType configurationType, const std::string& value) : + m_level(level), + m_configurationType(configurationType), + m_value(value) { + } + + /// @brief Gets level of current configuration + inline Level level(void) const { + return m_level; + } + + /// @brief Gets configuration type of current configuration + inline ConfigurationType configurationType(void) const { + return m_configurationType; + } + + /// @brief Gets string based configuration value + inline const std::string& value(void) const { + return m_value; + } + + /// @brief Set string based configuration value + /// @param value Value to set. Values have to be std::string; For boolean values use "true", "false", for any integral values + /// use them in quotes. They will be parsed when configuring + inline void setValue(const std::string& value) { + m_value = value; + } + + virtual inline void log(el::base::type::ostream_t& os) const { + os << LevelHelper::convertToString(m_level) + << ELPP_LITERAL(" ") << ConfigurationTypeHelper::convertToString(m_configurationType) + << ELPP_LITERAL(" = ") << m_value.c_str(); + } + + /// @brief Used to find configuration from configuration (pointers) repository. Avoid using it. + class Predicate { + public: + Predicate(Level level, ConfigurationType configurationType) : + m_level(level), + m_configurationType(configurationType) { + } + + inline bool operator()(const Configuration* conf) const { + return ((conf != nullptr) && (conf->level() == m_level) && (conf->configurationType() == m_configurationType)); + } + + private: + Level m_level; + ConfigurationType m_configurationType; + }; + +private: + Level m_level; + ConfigurationType m_configurationType; + std::string m_value; +}; + +/// @brief Thread-safe Configuration repository +/// +/// @detail This repository represents configurations for all the levels and configuration type mapped to a value. +class Configurations : public base::utils::RegistryWithPred { +public: + /// @brief Default constructor with empty repository + Configurations(void) : + m_configurationFile(std::string()), + m_isFromFile(false) { + } + + /// @brief Constructor used to set configurations using configuration file. + /// @param configurationFile Full path to configuration file + /// @param useDefaultsForRemaining Lets you set the remaining configurations to default. + /// @param base If provided, this configuration will be based off existing repository that this argument is pointing to. + /// @see parseFromFile(const std::string&, Configurations* base) + /// @see setRemainingToDefault() + Configurations(const std::string& configurationFile, bool useDefaultsForRemaining = true, Configurations* base = nullptr) : + m_configurationFile(configurationFile), + m_isFromFile(false) { + parseFromFile(configurationFile, base); + if (useDefaultsForRemaining) { + setRemainingToDefault(); + } + } + + virtual ~Configurations(void) { + } + + /// @brief Parses configuration from file. + /// @param configurationFile Full path to configuration file + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration file. + /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you + /// do not proceed without successful parse. + inline bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr) { + // We initial assertion with true because if we have assertion diabled, we want to pass this + // check and if assertion is enabled we will have values re-assigned any way. + bool assertionPassed = true; + ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)), + "Configuration file [" << configurationFile << "] does not exist!"); + if (!assertionPassed) { + return false; + } + bool success = Parser::parseFromFile(configurationFile, this, base); + m_isFromFile = success; + return success; + } + + /// @brief Parse configurations from configuration string. + /// + /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary + /// new line characters are provided. + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration text. + /// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you + /// do not proceed without successful parse. + inline bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr) { + bool success = Parser::parseFromText(configurationsString, this, base); + if (success) { + m_isFromFile = false; + } + return success; + } + + /// @brief Sets configuration based-off an existing configurations. + /// @param base Pointer to existing configurations. + inline void setFromBase(Configurations* base) { + if (base == nullptr || base == this) { + return; + } + base::threading::ScopedLock scopedLock(base->lock()); + for (Configuration*& conf : base->list()) { + set(conf); + } + } + + /// @brief Determines whether or not specified configuration type exists in the repository. + /// + /// @detail Returns as soon as first level is found. + /// @param configurationType Type of configuration to check existence for. + bool hasConfiguration(ConfigurationType configurationType) { + base::type::EnumType lIndex = LevelHelper::kMinValid; + bool result = false; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + if (hasConfiguration(LevelHelper::castFromInt(lIndex), configurationType)) { + result = true; + } + return result; + }); + return result; + } + + /// @brief Determines whether or not specified configuration type exists for specified level + /// @param level Level to check + /// @param configurationType Type of configuration to check existence for. + inline bool hasConfiguration(Level level, ConfigurationType configurationType) { + base::threading::ScopedLock scopedLock(lock()); +#if ELPP_COMPILER_INTEL + // We cant specify template types here, Intel C++ throws compilation error + // "error: type name is not allowed" + return RegistryWithPred::get(level, configurationType) != nullptr; +#else + return RegistryWithPred::get(level, configurationType) != nullptr; +#endif // ELPP_COMPILER_INTEL + } + + /// @brief Sets value of configuration for specified level. + /// + /// @detail Any existing configuration for specified level will be replaced. Also note that configuration types + /// ConfigurationType::MillisecondsWidth and ConfigurationType::PerformanceTracking will be ignored if not set for + /// Level::Global because these configurations are not dependant on level. + /// @param level Level to set configuration for (el::Level). + /// @param configurationType Type of configuration (el::ConfigurationType) + /// @param value A string based value. Regardless of what the data type of configuration is, it will always be string + /// from users' point of view. This is then parsed later to be used internally. + /// @see Configuration::setValue(const std::string& value) + /// @see el::Level + /// @see el::ConfigurationType + inline void set(Level level, ConfigurationType configurationType, const std::string& value) { + base::threading::ScopedLock scopedLock(lock()); + unsafeSet(level, configurationType, value); // This is not unsafe anymore as we have locked mutex + if (level == Level::Global) { + unsafeSetGlobally(configurationType, value, false); // Again this is not unsafe either + } + } + + /// @brief Sets single configuration based on other single configuration. + /// @see set(Level level, ConfigurationType configurationType, const std::string& value) + inline void set(Configuration* conf) { + if (conf == nullptr) { + return; + } + set(conf->level(), conf->configurationType(), conf->value()); + } + + inline Configuration* get(Level level, ConfigurationType configurationType) { + base::threading::ScopedLock scopedLock(lock()); + return RegistryWithPred::get(level, configurationType); + } + + /// @brief Sets configuration for all levels. + /// @param configurationType Type of configuration + /// @param value String based value + /// @see Configurations::set(Level level, ConfigurationType configurationType, const std::string& value) + inline void setGlobally(ConfigurationType configurationType, const std::string& value) { + setGlobally(configurationType, value, false); + } + + /// @brief Clears repository so that all the configurations are unset + inline void clear(void) { + base::threading::ScopedLock scopedLock(lock()); + unregisterAll(); + } + + /// @brief Gets configuration file used in parsing this configurations. + /// + /// @detail If this repository was set manually or by text this returns empty string. + inline const std::string& configurationFile(void) const { + return m_configurationFile; + } + + /// @brief Sets configurations to "factory based" configurations. + void setToDefault(void) { + setGlobally(ConfigurationType::Enabled, std::string("true"), true); +#if !defined(ELPP_NO_DEFAULT_LOG_FILE) + setGlobally(ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile), true); +#else + ELPP_UNUSED(base::consts::kDefaultLogFile); +#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) + setGlobally(ConfigurationType::ToFile, std::string("true"), true); + setGlobally(ConfigurationType::ToStandardOutput, std::string("true"), true); + setGlobally(ConfigurationType::MillisecondsWidth, std::string("3"), true); + setGlobally(ConfigurationType::PerformanceTracking, std::string("true"), true); + setGlobally(ConfigurationType::MaxLogFileSize, std::string("0"), true); + setGlobally(ConfigurationType::LogFlushThreshold, std::string("0"), true); + + setGlobally(ConfigurationType::Format, std::string("%datetime %level [%logger] %msg"), true); + set(Level::Debug, ConfigurationType::Format, std::string("%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg")); + // INFO and WARNING are set to default by Level::Global + set(Level::Error, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + set(Level::Fatal, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + set(Level::Verbose, ConfigurationType::Format, std::string("%datetime %level-%vlevel [%logger] %msg")); + set(Level::Trace, ConfigurationType::Format, std::string("%datetime %level [%logger] [%func] [%loc] %msg")); + } + + /// @brief Lets you set the remaining configurations to default. + /// + /// @detail By remaining, it means that the level/type a configuration does not exist for. + /// This function is useful when you want to minimize chances of failures, e.g, if you have a configuration file that sets + /// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is set to default i.e, + /// true. If you dont do this explicitley (either by calling this function or by using second param in Constructor + /// and try to access a value, an error is thrown + void setRemainingToDefault(void) { + base::threading::ScopedLock scopedLock(lock()); + unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string("true")); +#if !defined(ELPP_NO_DEFAULT_LOG_FILE) + unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile)); +#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) + unsafeSetIfNotExist(Level::Global, ConfigurationType::ToFile, std::string("true")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, std::string("true")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::MillisecondsWidth, std::string("3")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, std::string("true")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::MaxLogFileSize, std::string("0")); + unsafeSetIfNotExist(Level::Global, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + unsafeSetIfNotExist(Level::Debug, ConfigurationType::Format, + std::string("%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg")); + // INFO and WARNING are set to default by Level::Global + unsafeSetIfNotExist(Level::Error, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + unsafeSetIfNotExist(Level::Fatal, ConfigurationType::Format, std::string("%datetime %level [%logger] %msg")); + unsafeSetIfNotExist(Level::Verbose, ConfigurationType::Format, std::string("%datetime %level-%vlevel [%logger] %msg")); + unsafeSetIfNotExist(Level::Trace, ConfigurationType::Format, std::string("%datetime %level [%logger] [%func] [%loc] %msg")); + } + + /// @brief Parser used internally to parse configurations from file or text. + /// + /// @detail This class makes use of base::utils::Str. + /// You should not need this unless you are working on some tool for Easylogging++ + class Parser : base::StaticClass { + public: + /// @brief Parses configuration from file. + /// @param configurationFile Full path to configuration file + /// @param sender Sender configurations pointer. Usually 'this' is used from calling class + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration file. + /// @return True if successfully parsed, false otherwise. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you + /// do not proceed without successful parse. + static bool parseFromFile(const std::string& configurationFile, Configurations* sender, Configurations* base = nullptr) { + sender->setFromBase(base); + std::ifstream fileStream_(configurationFile.c_str(), std::ifstream::in); + ELPP_ASSERT(fileStream_.is_open(), "Unable to open configuration file [" << configurationFile << "] for parsing."); + bool parsedSuccessfully = false; + std::string line = std::string(); + Level currLevel = Level::Unknown; + std::string currConfigStr = std::string(); + std::string currLevelStr = std::string(); + while (fileStream_.good()) { + std::getline(fileStream_, line); + parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender); + ELPP_ASSERT(parsedSuccessfully, "Unable to parse configuration line: " << line); + } + return parsedSuccessfully; + } + + /// @brief Parse configurations from configuration string. + /// + /// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary + /// new line characters are provided. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you + /// do not proceed without successful parse (This is recommended) + /// @param configurationsString + /// @param sender Sender configurations pointer. Usually 'this' is used from calling class + /// @param base Configurations to base new configuration repository off. This value is used when you want to use + /// existing Configurations to base all the values and then set rest of configuration via configuration text. + /// @return True if successfully parsed, false otherwise. + static bool parseFromText(const std::string& configurationsString, Configurations* sender, Configurations* base = nullptr) { + sender->setFromBase(base); + bool parsedSuccessfully = false; + std::stringstream ss(configurationsString); + std::string line = std::string(); + Level currLevel = Level::Unknown; + std::string currConfigStr = std::string(); + std::string currLevelStr = std::string(); + while (std::getline(ss, line)) { + parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender); + ELPP_ASSERT(parsedSuccessfully, "Unable to parse configuration line: " << line); + } + return parsedSuccessfully; + } + + private: + friend class el::Loggers; + static void ignoreComments(std::string* line) { + std::size_t foundAt = 0; + std::size_t quotesStart = line->find("\""); + std::size_t quotesEnd = std::string::npos; + if (quotesStart != std::string::npos) { + quotesEnd = line->find("\"", quotesStart + 1); + while (quotesEnd != std::string::npos && line->at(quotesEnd - 1) == '\\') { + // Do not erase slash yet - we will erase it in parseLine(..) while loop + quotesEnd = line->find("\"", quotesEnd + 2); + } + } + if ((foundAt = line->find(base::consts::kConfigurationComment)) != std::string::npos) { + if (foundAt < quotesEnd) { + foundAt = line->find(base::consts::kConfigurationComment, quotesEnd + 1); + } + *line = line->substr(0, foundAt); + } + } + static inline bool isLevel(const std::string& line) { + return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLevel)); + } + + static inline bool isComment(const std::string& line) { + return base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationComment)); + } + + static inline bool isConfig(const std::string& line) { + std::size_t assignment = line.find('='); + return line != "" && + ((line[0] >= 65 && line[0] <= 90) || (line[0] >= 97 && line[0] <= 122)) && + (assignment != std::string::npos) && + (line.size() > assignment); + } + + static bool parseLine(std::string* line, std::string* currConfigStr, std::string* currLevelStr, Level* currLevel, Configurations* conf) { + ConfigurationType currConfig = ConfigurationType::Unknown; + std::string currValue = std::string(); + *line = base::utils::Str::trim(*line); + if (isComment(*line)) return true; + ignoreComments(line); + *line = base::utils::Str::trim(*line); + if (line->empty()) { + // Comment ignored + return true; + } + if (isLevel(*line)) { + if (line->size() <= 2) { + return true; + } + *currLevelStr = line->substr(1, line->size() - 2); + *currLevelStr = base::utils::Str::toUpper(*currLevelStr); + *currLevelStr = base::utils::Str::trim(*currLevelStr); + *currLevel = LevelHelper::convertFromString(currLevelStr->c_str()); + return true; + } + if (isConfig(*line)) { + std::size_t assignment = line->find('='); + *currConfigStr = line->substr(0, assignment); + *currConfigStr = base::utils::Str::toUpper(*currConfigStr); + *currConfigStr = base::utils::Str::trim(*currConfigStr); + currConfig = ConfigurationTypeHelper::convertFromString(currConfigStr->c_str()); + currValue = line->substr(assignment + 1); + currValue = base::utils::Str::trim(currValue); + std::size_t quotesStart = currValue.find("\"", 0); + std::size_t quotesEnd = std::string::npos; + if (quotesStart != std::string::npos) { + quotesEnd = currValue.find("\"", quotesStart + 1); + while (quotesEnd != std::string::npos && currValue.at(quotesEnd - 1) == '\\') { + currValue = currValue.erase(quotesEnd - 1, 1); + quotesEnd = currValue.find("\"", quotesEnd + 2); + } + } + if (quotesStart != std::string::npos && quotesEnd != std::string::npos) { + // Quote provided - check and strip if valid + ELPP_ASSERT((quotesStart < quotesEnd), "Configuration error - No ending quote found in [" + << currConfigStr << "]"); + ELPP_ASSERT((quotesStart + 1 != quotesEnd), "Empty configuration value for [" << currConfigStr << "]"); + if ((quotesStart != quotesEnd) && (quotesStart + 1 != quotesEnd)) { + // Explicit check in case if assertion is disabled + currValue = currValue.substr(quotesStart + 1, quotesEnd - 1); + } + } + } + ELPP_ASSERT(*currLevel != Level::Unknown, "Unrecognized severity level [" << *currLevelStr << "]"); + ELPP_ASSERT(currConfig != ConfigurationType::Unknown, "Unrecognized configuration [" << *currConfigStr << "]"); + if (*currLevel == Level::Unknown || currConfig == ConfigurationType::Unknown) { + return false; // unrecognizable level or config + } + conf->set(*currLevel, currConfig, currValue); + return true; + } + }; + +private: + std::string m_configurationFile; + bool m_isFromFile; + friend class el::Loggers; + + /// @brief Unsafely sets configuration if does not already exist + void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value) { + Configuration* conf = RegistryWithPred::get(level, configurationType); + if (conf == nullptr) { + unsafeSet(level, configurationType, value); + } + } + + /// @brief Thread unsafe set + void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value) { + Configuration* conf = RegistryWithPred::get(level, configurationType); + if (conf == nullptr) { + registerNew(new Configuration(level, configurationType, value)); + } else { + conf->setValue(value); + } + if (level == Level::Global) { + unsafeSetGlobally(configurationType, value, false); + } + } + + /// @brief Sets configurations for all levels including Level::Global if includeGlobalLevel is true + /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) + void setGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel) { + if (includeGlobalLevel) { + set(Level::Global, configurationType, value); + } + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + set(LevelHelper::castFromInt(lIndex), configurationType, value); + return false; // Do not break lambda function yet as we need to set all levels regardless + }); + } + + /// @brief Sets configurations (Unsafely) for all levels including Level::Global if includeGlobalLevel is true + /// @see Configurations::setGlobally(ConfigurationType configurationType, const std::string& value) + void unsafeSetGlobally(ConfigurationType configurationType, const std::string& value, bool includeGlobalLevel) { + if (includeGlobalLevel) { + unsafeSet(Level::Global, configurationType, value); + } + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + unsafeSet(LevelHelper::castFromInt(lIndex), configurationType, value); + return false; // Do not break lambda function yet as we need to set all levels regardless + }); + } +}; + +namespace base { + typedef std::shared_ptr FileStreamPtr; + typedef std::map LogStreamsReferenceMap; + /// @brief Configurations with data types. + /// + /// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations. + /// This is to perform faster while writing logs using correct configurations. + /// + /// This is thread safe and final class containing non-virtual destructor (means nothing should inherit this class) + class TypedConfigurations : public base::threading::ThreadSafe { + public: + /// @brief Constructor to initialize (construct) the object off el::Configurations + /// @param configurations Configurations pointer/reference to base this typed configurations off. + /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference() + TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference) { + m_configurations = configurations; + m_logStreamsReference = logStreamsReference; + build(m_configurations); + } + + TypedConfigurations(const TypedConfigurations& other) { + this->m_configurations = other.m_configurations; + this->m_logStreamsReference = other.m_logStreamsReference; + build(m_configurations); + } + + virtual ~TypedConfigurations(void) { + } + + const Configurations* configurations(void) const { + return m_configurations; + } + + inline bool enabled(Level level) { + return getConfigByVal(level, &m_enabledMap, "enabled"); + } + + inline bool toFile(Level level) { + return getConfigByVal(level, &m_toFileMap, "toFile"); + } + + inline const std::string& filename(Level level) { + return getConfigByRef(level, &m_filenameMap, "filename"); + } + + inline bool toStandardOutput(Level level) { + return getConfigByVal(level, &m_toStandardOutputMap, "toStandardOutput"); + } + + inline const base::LogFormat& logFormat(Level level) { + return getConfigByRef(level, &m_logFormatMap, "logFormat"); + } + + inline const base::MillisecondsWidth& millisecondsWidth(Level level = Level::Global) { + return getConfigByRef(level, &m_millisecondsWidthMap, "millisecondsWidth"); + } + + inline bool performanceTracking(Level level = Level::Global) { + return getConfigByVal(level, &m_performanceTrackingMap, "performanceTracking"); + } + + inline base::type::fstream_t* fileStream(Level level) { + return getConfigByRef(level, &m_fileStreamMap, "fileStream").get(); + } + + inline std::size_t maxLogFileSize(Level level) { + return getConfigByVal(level, &m_maxLogFileSizeMap, "maxLogFileSize"); + } + + inline std::size_t logFlushThreshold(Level level) { + return getConfigByVal(level, &m_logFlushThresholdMap, "logFlushThreshold"); + } + + private: + Configurations* m_configurations; + std::map m_enabledMap; + std::map m_toFileMap; + std::map m_filenameMap; + std::map m_toStandardOutputMap; + std::map m_logFormatMap; + std::map m_millisecondsWidthMap; + std::map m_performanceTrackingMap; + std::map m_fileStreamMap; + std::map m_maxLogFileSizeMap; + std::map m_logFlushThresholdMap; + base::LogStreamsReferenceMap* m_logStreamsReference; + + friend class el::Helpers; + friend class el::base::MessageBuilder; + friend class el::base::Writer; + friend class el::base::DefaultLogDispatchCallback; + friend class el::base::LogDispatcher; + + template + inline Conf_T getConfigByVal(Level level, const std::map* confMap, const char* confName) { + base::threading::ScopedLock scopedLock(lock()); + return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope + } + + template + inline Conf_T& getConfigByRef(Level level, std::map* confMap, const char* confName) { + base::threading::ScopedLock scopedLock(lock()); + return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope + } + + template + inline Conf_T unsafeGetConfigByVal(Level level, const std::map* confMap, const char* confName) { + ELPP_UNUSED(confName); + typename std::map::const_iterator it = confMap->find(level); + if (it == confMap->end()) { + try { + return confMap->at(Level::Global); + } catch (...) { + ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" + << LevelHelper::convertToString(level) << "]" + << std::endl << "Please ensure you have properly configured logger.", false); + return Conf_T(); + } + } + return it->second; + } + + template + inline Conf_T& unsafeGetConfigByRef(Level level, std::map* confMap, const char* confName) { + ELPP_UNUSED(confName); + typename std::map::iterator it = confMap->find(level); + if (it == confMap->end()) { + try { + return confMap->at(Level::Global); + } catch (...) { + ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" + << LevelHelper::convertToString(level) << "]" + << std::endl << "Please ensure you have properly configured logger.", false); + } + } + return it->second; + } + + template + void setValue(Level level, const Conf_T& value, std::map* confMap, bool includeGlobalLevel = true) { + // If map is empty and we are allowed to add into generic level (Level::Global), do it! + if (confMap->empty() && includeGlobalLevel) { + confMap->insert(std::make_pair(Level::Global, value)); + return; + } + // If same value exist in generic level already, dont add it to explicit level + typename std::map::iterator it = confMap->find(Level::Global); + if (it != confMap->end() && it->second == value) { + return; + } + // Now make sure we dont double up values if we really need to add it to explicit level + it = confMap->find(level); + if (it == confMap->end()) { + // Value not found for level, add new + confMap->insert(std::make_pair(level, value)); + } else { + // Value found, just update value + confMap->at(level) = value; + } + } + + void build(Configurations* configurations) { + base::threading::ScopedLock scopedLock(lock()); + auto getBool = [] (std::string boolStr) -> bool { // Pass by value for trimming + base::utils::Str::trim(boolStr); + return (boolStr == "TRUE" || boolStr == "true" || boolStr == "1"); + }; + std::vector withFileSizeLimit; + for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) { + Configuration* conf = *it; + // We cannot use switch on strong enums because Intel C++ dont support them yet + if (conf->configurationType() == ConfigurationType::Enabled) { + setValue(conf->level(), getBool(conf->value()), &m_enabledMap); + } else if (conf->configurationType() == ConfigurationType::ToFile) { + setValue(conf->level(), getBool(conf->value()), &m_toFileMap); + } else if (conf->configurationType() == ConfigurationType::ToStandardOutput) { + setValue(conf->level(), getBool(conf->value()), &m_toStandardOutputMap); + } else if (conf->configurationType() == ConfigurationType::Filename) { + // We do not yet configure filename but we will configure in another + // loop. This is because if file cannot be created, we will force ToFile + // to be false. Because configuring logger is not necessarily performance + // sensative operation, we can live with another loop; (by the way this loop + // is not very heavy either) + } else if (conf->configurationType() == ConfigurationType::Format) { + setValue(conf->level(), base::LogFormat(conf->level(), + base::type::string_t(conf->value().begin(), conf->value().end())), &m_logFormatMap); + } else if (conf->configurationType() == ConfigurationType::MillisecondsWidth) { + setValue(Level::Global, + base::MillisecondsWidth(static_cast(getULong(conf->value()))), &m_millisecondsWidthMap); + } else if (conf->configurationType() == ConfigurationType::PerformanceTracking) { + setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap); + } else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) { + setValue(conf->level(), static_cast(getULong(conf->value())), &m_maxLogFileSizeMap); +#if !defined(ELPP_NO_DEFAULT_LOG_FILE) + withFileSizeLimit.push_back(conf); +#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) + } else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) { + setValue(conf->level(), static_cast(getULong(conf->value())), &m_logFlushThresholdMap); + } + } + // As mentioned early, we will now set filename configuration in separate loop to deal with non-existent files + for (Configurations::const_iterator it = configurations->begin(); it != configurations->end(); ++it) { + Configuration* conf = *it; + if (conf->configurationType() == ConfigurationType::Filename) { + insertFile(conf->level(), conf->value()); + } + } + for (std::vector::iterator conf = withFileSizeLimit.begin(); + conf != withFileSizeLimit.end(); ++conf) { + // This is not unsafe as mutex is locked in currect scope + unsafeValidateFileRolling((*conf)->level(), base::defaultPreRollOutCallback); + } + } + + unsigned long getULong(std::string confVal) { + bool valid = true; + base::utils::Str::trim(confVal); + valid = !confVal.empty() && std::find_if(confVal.begin(), confVal.end(), + [](char c) { return !base::utils::Str::isDigit(c); }) == confVal.end(); + if (!valid) { + valid = false; + ELPP_ASSERT(valid, "Configuration value not a valid integer [" << confVal << "]"); + return 0; + } + return atol(confVal.c_str()); + } + + std::string resolveFilename(const std::string& filename) { + std::string resultingFilename = filename; + std::size_t dateIndex = std::string::npos; + std::string dateTimeFormatSpecifierStr = std::string(base::consts::kDateTimeFormatSpecifierForFilename); + if ((dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str())) != std::string::npos) { + while (dateIndex > 0 && resultingFilename[dateIndex - 1] == base::consts::kFormatSpecifierChar) { + dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), dateIndex + 1); + } + if (dateIndex != std::string::npos) { + const char* ptr = resultingFilename.c_str() + dateIndex; + // Goto end of specifier + ptr += dateTimeFormatSpecifierStr.size(); + std::string fmt; + if ((resultingFilename.size() > dateIndex) && (ptr[0] == '{')) { + // User has provided format for date/time + ++ptr; + int count = 1; // Start by 1 in order to remove starting brace + std::stringstream ss; + for (; *ptr; ++ptr, ++count) { + if (*ptr == '}') { + ++count; // In order to remove ending brace + break; + } + ss << *ptr; + } + resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count); + fmt = ss.str(); + } else { + fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename); + } + base::MillisecondsWidth msWidth(3); + std::string now = base::utils::DateTime::getDateTime(fmt.c_str(), &msWidth); + base::utils::Str::replaceAll(now, '/', '-'); // Replace path element since we are dealing with filename + base::utils::Str::replaceAll(resultingFilename, dateTimeFormatSpecifierStr, now); + } + } + return resultingFilename; + } + + void insertFile(Level level, const std::string& fullFilename) { + std::string resolvedFilename = resolveFilename(fullFilename); + if (resolvedFilename.empty()) { + std::cerr << "Could not load empty file for logging, please re-check your configurations for level [" + << LevelHelper::convertToString(level) << "]"; + } + std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator); + if (filePath.size() < resolvedFilename.size()) { + base::utils::File::createPath(filePath); + } + auto create = [&](Level level) { + base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename); + base::type::fstream_t* fs = nullptr; + if (filestreamIter == m_logStreamsReference->end()) { + // We need a completely new stream, nothing to share with + fs = base::utils::File::newFileStream(resolvedFilename); + m_filenameMap.insert(std::make_pair(level, resolvedFilename)); + m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(fs))); + m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level)))); + } else { + // Woops! we have an existing one, share it! + m_filenameMap.insert(std::make_pair(level, filestreamIter->first)); + m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(filestreamIter->second))); + fs = filestreamIter->second.get(); + } + if (fs == nullptr) { + // We display bad file error from newFileStream() + ELPP_INTERNAL_ERROR("Setting [TO_FILE] of [" + << LevelHelper::convertToString(level) << "] to FALSE", false); + setValue(level, false, &m_toFileMap); + } + }; + // If we dont have file conf for any level, create it for Level::Global first + // otherwise create for specified level + create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level); + } + + bool unsafeValidateFileRolling(Level level, const PreRollOutCallback& PreRollOutCallback) { + base::type::fstream_t* fs = unsafeGetConfigByRef(level, &m_fileStreamMap, "fileStream").get(); + if (fs == nullptr) { + return true; + } + std::size_t maxLogFileSize = unsafeGetConfigByVal(level, &m_maxLogFileSizeMap, "maxLogFileSize"); + std::size_t currFileSize = base::utils::File::getSizeOfFile(fs); + if (maxLogFileSize != 0 && currFileSize >= maxLogFileSize) { + std::string fname = unsafeGetConfigByRef(level, &m_filenameMap, "filename"); + ELPP_INTERNAL_INFO(1, "Truncating log file [" << fname << "] as a result of configurations for level [" + << LevelHelper::convertToString(level) << "]"); + fs->close(); + PreRollOutCallback(fname.c_str(), currFileSize); + fs->open(fname, std::fstream::out | std::fstream::trunc); + return true; + } + return false; + } + + bool validateFileRolling(Level level, const PreRollOutCallback& PreRollOutCallback) { + base::threading::ScopedLock scopedLock(lock()); + return unsafeValidateFileRolling(level, PreRollOutCallback); + } + }; + /// @brief Class that keeps record of current line hit for occasional logging + class HitCounter { + public: + HitCounter(void) : + m_filename(""), + m_lineNumber(0), + m_hitCounts(0) { + } + + HitCounter(const char* filename, unsigned long int lineNumber) : + m_filename(filename), + m_lineNumber(lineNumber), + m_hitCounts(0) { + } + + HitCounter(const HitCounter& hitCounter) : + m_filename(hitCounter.m_filename), + m_lineNumber(hitCounter.m_lineNumber), + m_hitCounts(hitCounter.m_hitCounts) { + } + + HitCounter& operator=(const HitCounter& hitCounter) { + m_filename = hitCounter.m_filename; + m_lineNumber = hitCounter.m_lineNumber; + m_hitCounts = hitCounter.m_hitCounts; + return *this; + } + + virtual ~HitCounter(void) { + } + + /// @brief Resets location of current hit counter + inline void resetLocation(const char* filename, unsigned long int lineNumber) { + m_filename = filename; + m_lineNumber = lineNumber; + } + + /// @brief Validates hit counts and resets it if necessary + inline void validateHitCounts(std::size_t n) { + if (m_hitCounts >= base::consts::kMaxLogPerCounter) { + m_hitCounts = (n >= 1 ? base::consts::kMaxLogPerCounter % n : 0); + } + ++m_hitCounts; + } + + inline const char* filename(void) const { + return m_filename; + } + + inline unsigned long int lineNumber(void) const { + return m_lineNumber; + } + + inline std::size_t hitCounts(void) const { + return m_hitCounts; + } + + inline void increment(void) { + ++m_hitCounts; + } + + class Predicate { + public: + Predicate(const char* filename, unsigned long int lineNumber) + : m_filename(filename), + m_lineNumber(lineNumber) { + } + inline bool operator()(const HitCounter* counter) { + return ((counter != nullptr) && + (strcmp(counter->m_filename, m_filename) == 0) && + (counter->m_lineNumber == m_lineNumber)); + } + + private: + const char* m_filename; + unsigned long int m_lineNumber; + }; + + private: + const char* m_filename; + unsigned long int m_lineNumber; + std::size_t m_hitCounts; + }; + /// @brief Repository for hit counters used across the application + class RegisteredHitCounters : public base::utils::RegistryWithPred { + public: + /// @brief Validates counter for every N, i.e, registers new if does not exist otherwise updates original one + /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned + bool validateEveryN(const char* filename, unsigned long int lineNumber, std::size_t n) { + base::threading::ScopedLock scopedLock(lock()); + base::HitCounter* counter = get(filename, lineNumber); + if (counter == nullptr) { + registerNew(counter = new base::HitCounter(filename, lineNumber)); + } + counter->validateHitCounts(n); + bool result = (n >= 1 && counter->hitCounts() != 0 && counter->hitCounts() % n == 0); + return result; + } + + /// @brief Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one + /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned + bool validateAfterN(const char* filename, unsigned long int lineNumber, std::size_t n) { + base::threading::ScopedLock scopedLock(lock()); + base::HitCounter* counter = get(filename, lineNumber); + if (counter == nullptr) { + registerNew(counter = new base::HitCounter(filename, lineNumber)); + } + // Do not use validateHitCounts here since we do not want to reset counter here + // Note the >= instead of > because we are incrementing + // after this check + if (counter->hitCounts() >= n) + return true; + counter->increment(); + return false; + } + + /// @brief Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original one + /// @return True if validation resulted in triggering hit. Meaning logs should be written everytime true is returned + bool validateNTimes(const char* filename, unsigned long int lineNumber, std::size_t n) { + base::threading::ScopedLock scopedLock(lock()); + base::HitCounter* counter = get(filename, lineNumber); + if (counter == nullptr) { + registerNew(counter = new base::HitCounter(filename, lineNumber)); + } + counter->increment(); + // Do not use validateHitCounts here since we do not want to reset counter here + if (counter->hitCounts() <= n) + return true; + return false; + } + + /// @brief Gets hit counter registered at specified position + inline const base::HitCounter* getCounter(const char* filename, unsigned long int lineNumber) { + base::threading::ScopedLock scopedLock(lock()); + return get(filename, lineNumber); + } + }; + /// @brief Action to be taken for dispatching + enum class DispatchAction : base::type::EnumType { + None = 1, NormalLog = 2, SysLog = 4 + }; + } // namespace base + template + class Callback : protected base::threading::ThreadSafe { + public: + Callback(void) : m_enabled(true) {} + inline bool enabled(void) const { return m_enabled; } + inline void setEnabled(bool enabled) { + base::threading::ScopedLock scopedLock(lock()); + m_enabled = enabled; + } + protected: + virtual void handle(const T* handlePtr) = 0; + private: + bool m_enabled; + }; + class LogDispatchData { + public: + LogDispatchData() : m_logMessage(nullptr), m_dispatchAction(base::DispatchAction::None) {} + inline const LogMessage* logMessage(void) const { return m_logMessage; } + inline base::DispatchAction dispatchAction(void) const { return m_dispatchAction; } + private: + LogMessage* m_logMessage; + base::DispatchAction m_dispatchAction; + friend class base::LogDispatcher; + + inline void setLogMessage(LogMessage* logMessage) { m_logMessage = logMessage; } + inline void setDispatchAction(base::DispatchAction dispatchAction) { m_dispatchAction = dispatchAction; } + }; + class LogDispatchCallback : public Callback { + private: + friend class base::LogDispatcher; + }; + class PerformanceTrackingCallback : public Callback { + private: + friend class base::PerformanceTracker; + }; + class LogBuilder : base::NoCopy { + public: + virtual ~LogBuilder(void) { ELPP_INTERNAL_INFO(3, "Destroying log builder...")} + virtual base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const = 0; + void convertToColoredOutput(base::type::string_t* logLine, Level level) { + if (!base::utils::s_termSupportsColor) return; + const base::type::char_t* resetColor = ELPP_LITERAL("\x1b[0m"); + if (level == Level::Error || level == Level::Fatal) + *logLine = ELPP_LITERAL("\x1b[31m") + *logLine + resetColor; + else if (level == Level::Warning) + *logLine = ELPP_LITERAL("\x1b[33m") + *logLine + resetColor; + else if (level == Level::Debug) + *logLine = ELPP_LITERAL("\x1b[32m") + *logLine + resetColor; + else if (level == Level::Info) + *logLine = ELPP_LITERAL("\x1b[36m") + *logLine + resetColor; + else if (level == Level::Trace) + *logLine = ELPP_LITERAL("\x1b[35m") + *logLine + resetColor; + } + private: + friend class el::base::DefaultLogDispatchCallback; + }; + typedef std::shared_ptr LogBuilderPtr; + /// @brief Represents a logger holding ID and configurations we need to write logs + /// + /// @detail This class does not write logs itself instead its used by writer to read configuations from. + class Logger : public base::threading::ThreadSafe, public Loggable { + public: + Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference) : + m_id(id), + m_typedConfigurations(nullptr), + m_parentApplicationName(std::string()), + m_isConfigured(false), + m_logStreamsReference(logStreamsReference) { + initUnflushedCount(); + } + + Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference) : + m_id(id), + m_typedConfigurations(nullptr), + m_parentApplicationName(std::string()), + m_isConfigured(false), + m_logStreamsReference(logStreamsReference) { + initUnflushedCount(); + configure(configurations); + } + + Logger(const Logger& logger) { + base::utils::safeDelete(m_typedConfigurations); + m_id = logger.m_id; + m_typedConfigurations = logger.m_typedConfigurations; + m_parentApplicationName = logger.m_parentApplicationName; + m_isConfigured = logger.m_isConfigured; + m_configurations = logger.m_configurations; + m_unflushedCount = logger.m_unflushedCount; + m_logStreamsReference = logger.m_logStreamsReference; + } + + Logger& operator=(const Logger& logger) { + base::utils::safeDelete(m_typedConfigurations); + m_id = logger.m_id; + m_typedConfigurations = logger.m_typedConfigurations; + m_parentApplicationName = logger.m_parentApplicationName; + m_isConfigured = logger.m_isConfigured; + m_configurations = logger.m_configurations; + m_unflushedCount = logger.m_unflushedCount; + m_logStreamsReference = logger.m_logStreamsReference; + return *this; + } + + virtual ~Logger(void) { + base::utils::safeDelete(m_typedConfigurations); + } + + virtual inline void log(el::base::type::ostream_t& os) const { + os << m_id.c_str(); + } + + /// @brief Configures the logger using specified configurations. + void configure(const Configurations& configurations) { + m_isConfigured = false; // we set it to false in case if we fail + initUnflushedCount(); + if (m_typedConfigurations != nullptr) { + Configurations* c = const_cast(m_typedConfigurations->configurations()); + if (c->hasConfiguration(Level::Global, ConfigurationType::Filename)) { + // This check is definitely needed for cases like ELPP_NO_DEFAULT_LOG_FILE + flush(); + } + } + base::threading::ScopedLock scopedLock(lock()); + if (m_configurations != configurations) { + m_configurations.setFromBase(const_cast(&configurations)); + } + base::utils::safeDelete(m_typedConfigurations); + m_typedConfigurations = new base::TypedConfigurations(&m_configurations, m_logStreamsReference); + resolveLoggerFormatSpec(); + m_isConfigured = true; + } + + /// @brief Reconfigures logger using existing configurations + inline void reconfigure(void) { + ELPP_INTERNAL_INFO(1, "Reconfiguring logger [" << m_id << "]"); + configure(m_configurations); + } + + inline const std::string& id(void) const { + return m_id; + } + + inline const std::string& parentApplicationName(void) const { + return m_parentApplicationName; + } + + inline void setParentApplicationName(const std::string& parentApplicationName) { + m_parentApplicationName = parentApplicationName; + } + + inline Configurations* configurations(void) { + return &m_configurations; + } + + inline base::TypedConfigurations* typedConfigurations(void) { + return m_typedConfigurations; + } + + static inline bool isValidId(const std::string& id) { + for (std::string::const_iterator it = id.begin(); it != id.end(); ++it) { + if (!base::utils::Str::contains(base::consts::kValidLoggerIdSymbols, *it)) { + return false; + } + } + return true; + } + /// @brief Flushes logger to sync all log files for all levels + inline void flush(void) { + ELPP_INTERNAL_INFO(3, "Flushing logger [" << m_id << "] all levels"); + base::threading::ScopedLock scopedLock(lock()); + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + flush(LevelHelper::castFromInt(lIndex), nullptr); + return false; + }); + } + + inline void flush(Level level, base::type::fstream_t* fs) { + if (fs == nullptr && m_typedConfigurations->toFile(level)) { + fs = m_typedConfigurations->fileStream(level); + } + if (fs != nullptr) { + fs->flush(); + m_unflushedCount.find(level)->second = 0; + } + } + + inline bool isFlushNeeded(Level level) { + return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level); + } + + inline LogBuilder* logBuilder(void) const { + return m_logBuilder.get(); + } + + inline void setLogBuilder(const LogBuilderPtr& logBuilder) { + m_logBuilder = logBuilder; + } + + inline bool enabled(Level level) const { + return m_typedConfigurations->enabled(level); + } + +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED +# define LOGGER_LEVEL_WRITERS_SIGNATURES(FUNCTION_NAME)\ +template \ +inline void FUNCTION_NAME(const char*, const T&, const Args&...);\ +template \ +inline void FUNCTION_NAME(const T&); + + template + inline void verbose(int, const char*, const T&, const Args&...); + + template + inline void verbose(int, const T&); + + LOGGER_LEVEL_WRITERS_SIGNATURES(info) + LOGGER_LEVEL_WRITERS_SIGNATURES(debug) + LOGGER_LEVEL_WRITERS_SIGNATURES(warn) + LOGGER_LEVEL_WRITERS_SIGNATURES(error) + LOGGER_LEVEL_WRITERS_SIGNATURES(fatal) + LOGGER_LEVEL_WRITERS_SIGNATURES(trace) +# undef LOGGER_LEVEL_WRITERS_SIGNATURES +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED + private: + std::string m_id; + base::TypedConfigurations* m_typedConfigurations; + base::type::stringstream_t m_stream; + std::string m_parentApplicationName; + bool m_isConfigured; + Configurations m_configurations; + std::map m_unflushedCount; + base::LogStreamsReferenceMap* m_logStreamsReference; + LogBuilderPtr m_logBuilder; + + friend class el::LogMessage; + friend class el::Loggers; + friend class el::Helpers; + friend class el::base::RegisteredLoggers; + friend class el::base::DefaultLogDispatchCallback; + friend class el::base::MessageBuilder; + friend class el::base::Writer; + friend class el::base::PErrorWriter; + friend class el::base::Storage; + friend class el::base::PerformanceTracker; + friend class el::base::LogDispatcher; + + Logger(void); + +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED + template + void log_(Level, int, const char*, const T&, const Args&...); + + template + inline void log_(Level, int, const T&); + + template + void log(Level, const char*, const T&, const Args&...); + + template + inline void log(Level, const T&); +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED + + void initUnflushedCount(void) { + m_unflushedCount.clear(); + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + m_unflushedCount.insert(std::make_pair(LevelHelper::castFromInt(lIndex), 0)); + return false; + }); + } + + inline base::type::stringstream_t& stream(void) { + return m_stream; + } + + void resolveLoggerFormatSpec(void) const { + base::type::EnumType lIndex = LevelHelper::kMinValid; + LevelHelper::forEachLevel(&lIndex, [&](void) -> bool { + base::LogFormat* logFormat = + const_cast(&m_typedConfigurations->logFormat(LevelHelper::castFromInt(lIndex))); + base::utils::Str::replaceFirstWithEscape(logFormat->m_format, base::consts::kLoggerIdFormatSpecifier, m_id); + return false; + }); + } + }; + namespace base { + /// @brief Loggers repository + class RegisteredLoggers : public base::utils::Registry { + public: + explicit RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) : + m_defaultLogBuilder(defaultLogBuilder) { + m_defaultConfigurations.setToDefault(); + } + + virtual ~RegisteredLoggers(void) { + unsafeFlushAll(); + } + + inline void setDefaultConfigurations(const Configurations& configurations) { + base::threading::ScopedLock scopedLock(lock()); + m_defaultConfigurations.setFromBase(const_cast(&configurations)); + } + + inline Configurations* defaultConfigurations(void) { + return &m_defaultConfigurations; + } + + Logger* get(const std::string& id, bool forceCreation = true) { + base::threading::ScopedLock scopedLock(lock()); + Logger* logger_ = base::utils::Registry::get(id); + if (logger_ == nullptr && forceCreation) { + bool validId = Logger::isValidId(id); + if (!validId) { + ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger."); + return nullptr; + } + logger_ = new Logger(id, m_defaultConfigurations, &m_logStreamsReference); + logger_->m_logBuilder = m_defaultLogBuilder; + registerNew(id, logger_); + } + return logger_; + } + + bool remove(const std::string& id) { + if (id == "default") { + return false; + } + Logger* logger = base::utils::Registry::get(id); + if (logger != nullptr) { + unregister(logger); + } + return true; + } + + inline bool has(const std::string& id) { + return get(id, false) != nullptr; + } + + inline void unregister(Logger*& logger) { + base::threading::ScopedLock scopedLock(lock()); + base::utils::Registry::unregister(logger->id()); + } + + inline base::LogStreamsReferenceMap* logStreamsReference(void) { + return &m_logStreamsReference; + } + + inline void flushAll(void) { + base::threading::ScopedLock scopedLock(lock()); + unsafeFlushAll(); + } + + private: + LogBuilderPtr m_defaultLogBuilder; + Configurations m_defaultConfigurations; + base::LogStreamsReferenceMap m_logStreamsReference; + friend class el::base::Storage; + + inline void unsafeFlushAll(void) { + ELPP_INTERNAL_INFO(1, "Flushing all log files"); + for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin(); + it != m_logStreamsReference.end(); ++it) { + if (it->second.get() == nullptr) continue; + it->second->flush(); + } + } + }; + /// @brief Represents registries for verbose logging + class VRegistry : base::NoCopy, public base::threading::ThreadSafe { + public: + explicit VRegistry(base::type::VerboseLevel level, base::type::EnumType* pFlags) : m_level(level), m_pFlags(pFlags) { + } + + /// @brief Sets verbose level. Accepted range is 0-9 + inline void setLevel(base::type::VerboseLevel level) { + base::threading::ScopedLock scopedLock(lock()); + if (level < 0) + m_level = 0; + else if (level > 9) + m_level = base::consts::kMaxVerboseLevel; + else + m_level = level; + } + + inline base::type::VerboseLevel level(void) const { + return m_level; + } + + inline void clearModules(void) { + base::threading::ScopedLock scopedLock(lock()); + m_modules.clear(); + } + + void setModules(const char* modules) { + base::threading::ScopedLock scopedLock(lock()); + auto addSuffix = [](std::stringstream& ss, const char* sfx, const char* prev) { + if (prev != nullptr && base::utils::Str::endsWith(ss.str(), std::string(prev))) { + std::string chr(ss.str().substr(0, ss.str().size() - strlen(prev))); + ss.str(std::string("")); + ss << chr; + } + if (base::utils::Str::endsWith(ss.str(), std::string(sfx))) { + std::string chr(ss.str().substr(0, ss.str().size() - strlen(sfx))); + ss.str(std::string("")); + ss << chr; + } + ss << sfx; + }; + auto insert = [&](std::stringstream& ss, base::type::VerboseLevel level) { + if (!base::utils::hasFlag(LoggingFlag::DisableVModulesExtensions, *m_pFlags)) { + addSuffix(ss, ".h", nullptr); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".c", ".h"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".cpp", ".c"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".cc", ".cpp"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".cxx", ".cc"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".-inl.h", ".cxx"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".hxx", ".-inl.h"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".hpp", ".hxx"); + m_modules.insert(std::make_pair(ss.str(), level)); + addSuffix(ss, ".hh", ".hpp"); + } + m_modules.insert(std::make_pair(ss.str(), level)); + }; + bool isMod = true; + bool isLevel = false; + std::stringstream ss; + int level = -1; + for (; *modules; ++modules) { + switch (*modules) { + case '=': + isLevel = true; + isMod = false; + break; + case ',': + isLevel = false; + isMod = true; + if (!ss.str().empty() && level != -1) { + insert(ss, level); + ss.str(std::string("")); + level = -1; + } + break; + default: + if (isMod) { + ss << *modules; + } else if (isLevel) { + if (isdigit(*modules)) { + level = static_cast(*modules) - 48; + } + } + break; + } + } + if (!ss.str().empty() && level != -1) { + insert(ss, level); + } + } + + bool allowed(base::type::VerboseLevel vlevel, const char* file) { + base::threading::ScopedLock scopedLock(lock()); + if (m_modules.empty() || file == nullptr) { + return vlevel <= m_level; + } else { + std::map::iterator it = m_modules.begin(); + for (; it != m_modules.end(); ++it) { + if (base::utils::Str::wildCardMatch(file, it->first.c_str())) { + return vlevel <= it->second; + } + } + if (base::utils::hasFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified, *m_pFlags)) { + return true; + } + return false; + } + } + + inline const std::map& modules(void) const { + return m_modules; + } + + void setFromArgs(const base::utils::CommandLineArgs* commandLineArgs) { + if (commandLineArgs->hasParam("-v") || commandLineArgs->hasParam("--verbose") || + commandLineArgs->hasParam("-V") || commandLineArgs->hasParam("--VERBOSE")) { + setLevel(base::consts::kMaxVerboseLevel); + } else if (commandLineArgs->hasParamWithValue("--v")) { + setLevel(atoi(commandLineArgs->getParamValue("--v"))); + } else if (commandLineArgs->hasParamWithValue("--V")) { + setLevel(atoi(commandLineArgs->getParamValue("--V"))); + } else if ((commandLineArgs->hasParamWithValue("-vmodule")) && vModulesEnabled()) { + setModules(commandLineArgs->getParamValue("-vmodule")); + } else if (commandLineArgs->hasParamWithValue("-VMODULE") && vModulesEnabled()) { + setModules(commandLineArgs->getParamValue("-VMODULE")); + } + } + + /// @brief Whether or not vModules enabled + inline bool vModulesEnabled(void) { + return !base::utils::hasFlag(LoggingFlag::DisableVModules, *m_pFlags); + } + + private: + base::type::VerboseLevel m_level; + base::type::EnumType* m_pFlags; + std::map m_modules; + }; + } // namespace base + class LogMessage { + public: + LogMessage(Level level, const std::string& file, unsigned long int line, const std::string& func, + base::type::VerboseLevel verboseLevel, Logger* logger) : + m_level(level), m_file(file), m_line(line), m_func(func), + m_verboseLevel(verboseLevel), m_logger(logger), m_message(logger->stream().str()) { + } + inline Level level(void) const { return m_level; } + inline const std::string& file(void) const { return m_file; } + inline unsigned long int line(void) const { return m_line; } // NOLINT + inline const std::string& func(void) const { return m_func; } + inline base::type::VerboseLevel verboseLevel(void) const { return m_verboseLevel; } + inline Logger* logger(void) const { return m_logger; } + inline const base::type::string_t& message(void) const { return m_message; } + private: + Level m_level; + std::string m_file; + unsigned long int m_line; + std::string m_func; + base::type::VerboseLevel m_verboseLevel; + Logger* m_logger; + base::type::string_t m_message; + }; + namespace base { +#if ELPP_ASYNC_LOGGING + class AsyncLogItem { + public: + explicit AsyncLogItem(const LogMessage& logMessage, const LogDispatchData& data, const base::type::string_t& logLine) + : m_logMessage(logMessage), m_dispatchData(data), m_logLine(logLine) {} + virtual ~AsyncLogItem() {} + inline LogMessage* logMessage(void) { return &m_logMessage; } + inline LogDispatchData* data(void) { return &m_dispatchData; } + inline base::type::string_t logLine(void) { return m_logLine; } + private: + LogMessage m_logMessage; + LogDispatchData m_dispatchData; + base::type::string_t m_logLine; + }; + class AsyncLogQueue : public base::threading::ThreadSafe { + public: + virtual ~AsyncLogQueue() { + ELPP_INTERNAL_INFO(6, "~AsyncLogQueue"); + } + + inline AsyncLogItem next(void) { + base::threading::ScopedLock scopedLock(lock()); + AsyncLogItem result = m_queue.front(); + m_queue.pop(); + return result; + } + + inline void push(const AsyncLogItem& item) { + base::threading::ScopedLock scopedLock(lock()); + m_queue.push(item); + } + inline void pop(void) { + base::threading::ScopedLock scopedLock(lock()); + m_queue.pop(); + } + inline AsyncLogItem front(void) { + base::threading::ScopedLock scopedLock(lock()); + return m_queue.front(); + } + inline bool empty(void) { + base::threading::ScopedLock scopedLock(lock()); + return m_queue.empty(); + } + private: + std::queue m_queue; + }; + class IWorker { + public: + virtual ~IWorker() {} + virtual void start() = 0; + }; +#endif // ELPP_ASYNC_LOGGING + /// @brief Easylogging++ management storage + class Storage : base::NoCopy, public base::threading::ThreadSafe { + public: +#if ELPP_ASYNC_LOGGING + Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker) : +#else + explicit Storage(const LogBuilderPtr& defaultLogBuilder) : +#endif // ELPP_ASYNC_LOGGING + m_registeredHitCounters(new base::RegisteredHitCounters()), + m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)), + m_flags(0x0), + m_vRegistry(new base::VRegistry(0, &m_flags)), +#if ELPP_ASYNC_LOGGING + m_asyncLogQueue(new base::AsyncLogQueue()), + m_asyncDispatchWorker(asyncDispatchWorker), +#endif // ELPP_ASYNC_LOGGING + m_preRollOutCallback(base::defaultPreRollOutCallback) { + // Register default logger + m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId)); + // Register performance logger and reconfigure format + Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId)); + performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%datetime %level %msg")); + performanceLogger->reconfigure(); +#if defined(ELPP_SYSLOG) + // Register syslog logger and reconfigure format + Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId)); + sysLogLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%level: %msg")); + sysLogLogger->reconfigure(); +#endif // defined(ELPP_SYSLOG) + addFlag(LoggingFlag::AllowVerboseIfModuleNotSpecified); +#if ELPP_ASYNC_LOGGING + installLogDispatchCallback(std::string("AsyncLogDispatchCallback")); +#else + installLogDispatchCallback(std::string("DefaultLogDispatchCallback")); +#endif // ELPP_ASYNC_LOGGING + installPerformanceTrackingCallback(std::string("DefaultPerformanceTrackingCallback")); + ELPP_INTERNAL_INFO(1, "Easylogging++ has been initialized"); +#if ELPP_ASYNC_LOGGING + m_asyncDispatchWorker->start(); +#endif // ELPP_ASYNC_LOGGING + } + + virtual ~Storage(void) { + ELPP_INTERNAL_INFO(4, "Destroying storage"); +#if ELPP_ASYNC_LOGGING + ELPP_INTERNAL_INFO(5, "Replacing log dispatch callback to synchronous"); + uninstallLogDispatchCallback(std::string("AsyncLogDispatchCallback")); + installLogDispatchCallback(std::string("DefaultLogDispatchCallback")); + ELPP_INTERNAL_INFO(5, "Destroying asyncDispatchWorker"); + base::utils::safeDelete(m_asyncDispatchWorker); + ELPP_INTERNAL_INFO(5, "Destroying asyncLogQueue"); + base::utils::safeDelete(m_asyncLogQueue); +#endif // ELPP_ASYNC_LOGGING + ELPP_INTERNAL_INFO(5, "Destroying registeredHitCounters"); + base::utils::safeDelete(m_registeredHitCounters); + ELPP_INTERNAL_INFO(5, "Destroying registeredLoggers"); + base::utils::safeDelete(m_registeredLoggers); + ELPP_INTERNAL_INFO(5, "Destroying vRegistry"); + base::utils::safeDelete(m_vRegistry); + } + + inline bool validateEveryNCounter(const char* filename, unsigned long int lineNumber, std::size_t occasion) { + return hitCounters()->validateEveryN(filename, lineNumber, occasion); + } + + inline bool validateAfterNCounter(const char* filename, unsigned long int lineNumber, std::size_t n) { // NOLINT + return hitCounters()->validateAfterN(filename, lineNumber, n); + } + + inline bool validateNTimesCounter(const char* filename, unsigned long int lineNumber, std::size_t n) { // NOLINT + return hitCounters()->validateNTimes(filename, lineNumber, n); + } + + inline base::RegisteredHitCounters* hitCounters(void) const { + return m_registeredHitCounters; + } + + inline base::RegisteredLoggers* registeredLoggers(void) const { + return m_registeredLoggers; + } + + inline base::VRegistry* vRegistry(void) const { + return m_vRegistry; + } + +#if ELPP_ASYNC_LOGGING + inline base::AsyncLogQueue* asyncLogQueue(void) const { + return m_asyncLogQueue; + } +#endif // ELPP_ASYNC_LOGGING + + inline const base::utils::CommandLineArgs* commandLineArgs(void) const { + return &m_commandLineArgs; + } + + inline void addFlag(LoggingFlag flag) { + base::utils::addFlag(flag, &m_flags); + } + + inline void removeFlag(LoggingFlag flag) { + base::utils::removeFlag(flag, &m_flags); + } + + inline bool hasFlag(LoggingFlag flag) const { + return base::utils::hasFlag(flag, m_flags); + } + + inline base::type::EnumType flags(void) const { + return m_flags; + } + + inline void setFlags(base::type::EnumType flags) { + m_flags = flags; + } + + inline void setPreRollOutCallback(const PreRollOutCallback& callback) { + m_preRollOutCallback = callback; + } + + inline void unsetPreRollOutCallback(void) { + m_preRollOutCallback = base::defaultPreRollOutCallback; + } + + inline PreRollOutCallback& preRollOutCallback(void) { + return m_preRollOutCallback; + } + + inline bool hasCustomFormatSpecifier(const char* formatSpecifier) { + base::threading::ScopedLock scopedLock(lock()); + return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(), + formatSpecifier) != m_customFormatSpecifiers.end(); + } + + inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) { + if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) { + return; + } + base::threading::ScopedLock scopedLock(lock()); + m_customFormatSpecifiers.push_back(customFormatSpecifier); + } + + inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) { + base::threading::ScopedLock scopedLock(lock()); + std::vector::iterator it = std::find(m_customFormatSpecifiers.begin(), + m_customFormatSpecifiers.end(), formatSpecifier); + if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) { + m_customFormatSpecifiers.erase(it); + return true; + } + return false; + } + + const std::vector* customFormatSpecifiers(void) const { + return &m_customFormatSpecifiers; + } + + inline void setLoggingLevel(Level level) { + m_loggingLevel = level; + } + + template + inline bool installLogDispatchCallback(const std::string& id) { + return installCallback(id, &m_logDispatchCallbacks); + } + + template + inline void uninstallLogDispatchCallback(const std::string& id) { + uninstallCallback(id, &m_logDispatchCallbacks); + } + template + inline T* logDispatchCallback(const std::string& id) { + return callback(id, &m_logDispatchCallbacks); + } + + template + inline bool installPerformanceTrackingCallback(const std::string& id) { + return installCallback(id, &m_performanceTrackingCallbacks); + } + + template + inline void uninstallPerformanceTrackingCallback(const std::string& id) { + uninstallCallback(id, &m_performanceTrackingCallbacks); + } + + template + inline T* performanceTrackingCallback(const std::string& id) { + return callback(id, &m_performanceTrackingCallbacks); + } + private: + base::RegisteredHitCounters* m_registeredHitCounters; + base::RegisteredLoggers* m_registeredLoggers; + base::type::EnumType m_flags; + base::VRegistry* m_vRegistry; +#if ELPP_ASYNC_LOGGING + base::AsyncLogQueue* m_asyncLogQueue; + base::IWorker* m_asyncDispatchWorker; +#endif // ELPP_ASYNC_LOGGING + base::utils::CommandLineArgs m_commandLineArgs; + PreRollOutCallback m_preRollOutCallback; + std::map m_logDispatchCallbacks; + std::map m_performanceTrackingCallbacks; + std::vector m_customFormatSpecifiers; + Level m_loggingLevel; + + friend class el::Helpers; + friend class el::base::DefaultLogDispatchCallback; + friend class el::LogBuilder; + friend class el::base::MessageBuilder; + friend class el::base::Writer; + friend class el::base::PerformanceTracker; + friend class el::base::LogDispatcher; + + void setApplicationArguments(int argc, char** argv) { + m_commandLineArgs.setArgs(argc, argv); + m_vRegistry->setFromArgs(commandLineArgs()); + // default log file +#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) + if (m_commandLineArgs.hasParamWithValue(base::consts::kDefaultLogFileParam)) { + Configurations c; + c.setGlobally(ConfigurationType::Filename, std::string(m_commandLineArgs.getParamValue(base::consts::kDefaultLogFileParam))); + registeredLoggers()->setDefaultConfigurations(c); + for (base::RegisteredLoggers::iterator it = registeredLoggers()->begin(); + it != registeredLoggers()->end(); ++it) { + it->second->configure(c); + } + } +#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) +#if defined(ELPP_LOGGING_FLAGS_FROM_ARG) + if (m_commandLineArgs.hasParamWithValue(base::consts::kLoggingFlagsParam)) { + m_flags = atoi(m_commandLineArgs.getParamValue(base::consts::kLoggingFlagsParam)); + } +#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) + } + + inline void setApplicationArguments(int argc, const char** argv) { + setApplicationArguments(argc, const_cast(argv)); + } + + template + inline bool installCallback(const std::string& id, std::map* mapT) { + if (mapT->find(id) == mapT->end()) { + mapT->insert(std::make_pair(id, TPtr(new T()))); + return true; + } + return false; + } + + template + inline void uninstallCallback(const std::string& id, std::map* mapT) { + if (mapT->find(id) != mapT->end()) { + mapT->erase(id); + } + } + + template + inline T* callback(const std::string& id, std::map* mapT) { + typename std::map::iterator iter = mapT->find(id); + if (iter != mapT->end()) { + return static_cast(iter->second.get()); + } + return nullptr; + } + }; + extern ELPP_EXPORT base::type::StoragePointer elStorage; +#define ELPP el::base::elStorage + class DefaultLogDispatchCallback : public LogDispatchCallback { + protected: + void handle(const LogDispatchData* data) { + m_data = data; + dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(), + m_data->dispatchAction() == base::DispatchAction::NormalLog)); + } + private: + const LogDispatchData* m_data; + void dispatch(base::type::string_t&& logLine) { + if (m_data->dispatchAction() == base::DispatchAction::NormalLog) { + if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) { + base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream(m_data->logMessage()->level()); + if (fs != nullptr) { + fs->write(logLine.c_str(), logLine.size()); + if (fs->fail()) { + ELPP_INTERNAL_ERROR("Unable to write log to file [" + << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) << "].\n" + << "Few possible reasons (could be something else):\n" << " * Permission denied\n" + << " * Disk full\n" << " * Disk is not writable", true); + } else { + if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (m_data->logMessage()->logger()->isFlushNeeded(m_data->logMessage()->level()))) { + m_data->logMessage()->logger()->flush(m_data->logMessage()->level(), fs); + } + } + } else { + ELPP_INTERNAL_ERROR("Log file for [" << LevelHelper::convertToString(m_data->logMessage()->level()) << "] " + << "has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " + << m_data->logMessage()->logger()->id() << "]", false); + } + } + if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) { + if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput)) + m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, m_data->logMessage()->level()); + ELPP_COUT << ELPP_COUT_LINE(logLine); + } + } +#if defined(ELPP_SYSLOG) + else if (m_data->dispatchAction() == base::DispatchAction::SysLog) { + // Determine syslog priority + int sysLogPriority = 0; + if (m_data->logMessage()->level() == Level::Fatal) + sysLogPriority = LOG_EMERG; + else if (m_data->logMessage()->level() == Level::Error) + sysLogPriority = LOG_ERR; + else if (m_data->logMessage()->level() == Level::Warning) + sysLogPriority = LOG_WARNING; + else if (m_data->logMessage()->level() == Level::Info) + sysLogPriority = LOG_INFO; + else if (m_data->logMessage()->level() == Level::Debug) + sysLogPriority = LOG_DEBUG; + else + sysLogPriority = LOG_NOTICE; +# if defined(ELPP_UNICODE) + char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str()); + syslog(sysLogPriority, "%s", line); + free(line); +# else + syslog(sysLogPriority, "%s", logLine.c_str()); +# endif + } +#endif // defined(ELPP_SYSLOG) + } + }; +#if ELPP_ASYNC_LOGGING + class AsyncLogDispatchCallback : public LogDispatchCallback { + protected: + void handle(const LogDispatchData* data) { + base::type::string_t logLine = data->logMessage()->logger()->logBuilder()->build(data->logMessage(), data->dispatchAction() == base::DispatchAction::NormalLog); + if (data->dispatchAction() == base::DispatchAction::NormalLog && data->logMessage()->logger()->typedConfigurations()->toStandardOutput(data->logMessage()->level())) { + if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput)) + data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, data->logMessage()->level()); + ELPP_COUT << ELPP_COUT_LINE(logLine); + } + // Save resources and only queue if we want to write to file otherwise just ignore handler + if (data->logMessage()->logger()->typedConfigurations()->toFile(data->logMessage()->level())) { + ELPP->asyncLogQueue()->push(AsyncLogItem(*(data->logMessage()), *data, logLine)); + } + } + }; + class AsyncDispatchWorker : public base::IWorker, public base::threading::ThreadSafe { + public: + AsyncDispatchWorker() { + setContinueRunning(false); + } + + virtual ~AsyncDispatchWorker() { + setContinueRunning(false); + ELPP_INTERNAL_INFO(6, "Stopping dispatch worker - Cleaning log queue"); + clean(); + ELPP_INTERNAL_INFO(6, "Log queue cleaned"); + } + + inline bool clean(void) { + std::mutex m; + std::unique_lock lk(m); + cv.wait(lk, []{ return !ELPP->asyncLogQueue()->empty(); }); + emptyQueue(); + lk.unlock(); + cv.notify_one(); + return ELPP->asyncLogQueue()->empty(); + } + + inline void emptyQueue(void) { + while (!ELPP->asyncLogQueue()->empty()) { + AsyncLogItem data = ELPP->asyncLogQueue()->next(); + handle(&data); + base::threading::msleep(100); + } + } + + virtual inline void start(void) { + base::threading::msleep(5000); // 5s (why?) + setContinueRunning(true); + std::thread t1(&AsyncDispatchWorker::run, this); + t1.join(); + } + + void handle(AsyncLogItem* logItem) { + LogDispatchData* data = logItem->data(); + LogMessage* logMessage = logItem->logMessage(); + Logger* logger = logMessage->logger(); + base::TypedConfigurations* conf = logger->typedConfigurations(); + base::type::string_t logLine = logItem->logLine(); + if (data->dispatchAction() == base::DispatchAction::NormalLog) { + if (conf->toFile(logMessage->level())) { + base::type::fstream_t* fs = conf->fileStream(logMessage->level()); + if (fs != nullptr) { + fs->write(logLine.c_str(), logLine.size()); + if (fs->fail()) { + ELPP_INTERNAL_ERROR("Unable to write log to file [" + << conf->filename(logMessage->level()) << "].\n" + << "Few possible reasons (could be something else):\n" << " * Permission denied\n" + << " * Disk full\n" << " * Disk is not writable", true); + } else { + if (ELPP->hasFlag(LoggingFlag::ImmediateFlush) || (logger->isFlushNeeded(logMessage->level()))) { + logger->flush(logMessage->level(), fs); + } + } + } else { + ELPP_INTERNAL_ERROR("Log file for [" << LevelHelper::convertToString(logMessage->level()) << "] " + << "has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " << logger->id() << "]", false); + } + } + } +# if defined(ELPP_SYSLOG) + else if (data->dispatchAction() == base::DispatchAction::SysLog) { + // Determine syslog priority + int sysLogPriority = 0; + if (logMessage->level() == Level::Fatal) + sysLogPriority = LOG_EMERG; + else if (logMessage->level() == Level::Error) + sysLogPriority = LOG_ERR; + else if (logMessage->level() == Level::Warning) + sysLogPriority = LOG_WARNING; + else if (logMessage->level() == Level::Info) + sysLogPriority = LOG_INFO; + else if (logMessage->level() == Level::Debug) + sysLogPriority = LOG_DEBUG; + else + sysLogPriority = LOG_NOTICE; +# if defined(ELPP_UNICODE) + char* line = base::utils::Str::wcharPtrToCharPtr(logLine.c_str()); + syslog(sysLogPriority, "%s", line); + free(line); +# else + syslog(sysLogPriority, "%s", logLine.c_str()); +# endif + } +# endif // defined(ELPP_SYSLOG) + } + + void run(void) { + while (continueRunning()) { + emptyQueue(); + base::threading::msleep(10); // 10ms + } + } + + void setContinueRunning(bool value) { + base::threading::ScopedLock scopedLock(m_continueRunningMutex); + m_continueRunning = value; + } + + bool continueRunning(void) const { + return m_continueRunning; + } + private: + std::condition_variable cv; + bool m_continueRunning; + base::threading::Mutex m_continueRunningMutex; + }; +#endif // ELPP_ASYNC_LOGGING + } // namespace base + namespace base { + class DefaultLogBuilder : public LogBuilder { + public: + base::type::string_t build(const LogMessage* logMessage, bool appendNewLine) const { + base::TypedConfigurations* tc = logMessage->logger()->typedConfigurations(); + const base::LogFormat* logFormat = &tc->logFormat(logMessage->level()); + base::type::string_t logLine = logFormat->format(); + char buff[base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength] = ""; + const char* bufLim = buff + sizeof(buff); + if (logFormat->hasFlag(base::FormatFlags::AppName)) { + // App name + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kAppNameFormatSpecifier, + logMessage->logger()->parentApplicationName()); + } + if (logFormat->hasFlag(base::FormatFlags::ThreadId)) { + // Thread ID + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kThreadIdFormatSpecifier, + base::threading::getCurrentThreadId()); + } + if (logFormat->hasFlag(base::FormatFlags::DateTime)) { + // DateTime + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kDateTimeFormatSpecifier, + base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(), + &tc->millisecondsWidth(logMessage->level()))); + } + if (logFormat->hasFlag(base::FormatFlags::Function)) { + // Function + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFunctionFormatSpecifier, logMessage->func()); + } + if (logFormat->hasFlag(base::FormatFlags::File)) { + // File + base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength); + base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::FileBase)) { + // FileBase + base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength); + base::utils::File::buildBaseFilename(logMessage->file(), buff); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogFileBaseFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::Line)) { + // Line + char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceLineMaxLength); + buf = base::utils::Str::convertAndAddToBuff(logMessage->line(), base::consts::kSourceLineMaxLength, buf, bufLim, false); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLineFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::Location)) { + // Location + char* buf = base::utils::Str::clearBuff(buff, base::consts::kSourceFilenameMaxLength + base::consts::kSourceLineMaxLength); + base::utils::File::buildStrippedFilename(logMessage->file().c_str(), buff); + buf = base::utils::Str::addToBuff(buff, buf, bufLim); + buf = base::utils::Str::addToBuff(":", buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(logMessage->line(), base::consts::kSourceLineMaxLength, buf, bufLim, false); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kLogLocationFormatSpecifier, std::string(buff)); + } + if (logMessage->level() == Level::Verbose && logFormat->hasFlag(base::FormatFlags::VerboseLevel)) { + // Verbose level + char* buf = base::utils::Str::clearBuff(buff, 1); + buf = base::utils::Str::convertAndAddToBuff(logMessage->verboseLevel(), 1, buf, bufLim, false); + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kVerboseLevelFormatSpecifier, std::string(buff)); + } + if (logFormat->hasFlag(base::FormatFlags::LogMessage)) { + // Log message + base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message()); + } +#if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) + for (std::vector::const_iterator it = ELPP->customFormatSpecifiers()->begin(); + it != ELPP->customFormatSpecifiers()->end(); ++it) { + std::string fs(it->formatSpecifier()); + base::type::string_t wcsFormatSpecifier(fs.begin(), fs.end()); + base::utils::Str::replaceFirstWithEscape(logLine, wcsFormatSpecifier, std::string(it->resolver()())); + } +#endif // !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) + if (appendNewLine) logLine += ELPP_LITERAL("\n"); + return logLine; + } + }; + /// @brief Dispatches log messages + class LogDispatcher : base::NoCopy { + public: + LogDispatcher(bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) : + m_proceed(proceed), + m_logMessage(std::move(logMessage)), + m_dispatchAction(std::move(dispatchAction)) { + } + + void dispatch(void) { + if (m_proceed && m_dispatchAction == base::DispatchAction::None) { + m_proceed = false; + } + if (!m_proceed) { + return; + } + // We minimize the time of ELPP's lock - this lock is released after log is written + base::threading::ScopedLock scopedLock(ELPP->lock()); + base::TypedConfigurations* tc = m_logMessage.logger()->m_typedConfigurations; + if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) { + tc->validateFileRolling(m_logMessage.level(), ELPP->preRollOutCallback()); + } + LogDispatchCallback* callback = nullptr; + LogDispatchData data; + for (const std::pair& h + : ELPP->m_logDispatchCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + data.setLogMessage(&m_logMessage); + data.setDispatchAction(m_dispatchAction); + callback->acquireLock(); + callback->handle(&data); + callback->releaseLock(); + } + } + } + + private: + bool m_proceed; + LogMessage m_logMessage; + base::DispatchAction m_dispatchAction; + }; +#if defined(ELPP_STL_LOGGING) + /// @brief Workarounds to write some STL logs + /// + /// @detail There is workaround needed to loop through some stl containers. In order to do that, we need iterable containers + /// of same type and provide iterator interface and pass it on to writeIterator(). + /// Remember, this is passed by value in constructor so that we dont change original containers. + /// This operation is as expensive as Big-O(std::min(class_.size(), base::consts::kMaxLogPerContainer)) + namespace workarounds { + /// @brief Abstract IterableContainer template that provides interface for iterable classes of type T + template + class IterableContainer { + public: + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + IterableContainer(void) {} + virtual ~IterableContainer(void) {} + iterator begin(void) { return getContainer().begin(); } + iterator end(void) { return getContainer().end(); } + private: + virtual Container& getContainer(void) = 0; + }; + /// @brief Implements IterableContainer and provides iterable std::priority_queue class + template, typename Comparator = std::less> + class IterablePriorityQueue : public IterableContainer, public std::priority_queue { + public: + IterablePriorityQueue(std::priority_queue queue_) { + std::size_t count_ = 0; + while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { + this->push(queue_.top()); + queue_.pop(); + } + } + private: + inline Container& getContainer(void) { + return this->c; + } + }; + /// @brief Implements IterableContainer and provides iterable std::queue class + template> + class IterableQueue : public IterableContainer, public std::queue { + public: + IterableQueue(std::queue queue_) { + std::size_t count_ = 0; + while (++count_ < base::consts::kMaxLogPerContainer && !queue_.empty()) { + this->push(queue_.front()); + queue_.pop(); + } + } + private: + inline Container& getContainer(void) { + return this->c; + } + }; + /// @brief Implements IterableContainer and provides iterable std::stack class + template> + class IterableStack : public IterableContainer, public std::stack { + public: + IterableStack(std::stack stack_) { + std::size_t count_ = 0; + while (++count_ < base::consts::kMaxLogPerContainer && !stack_.empty()) { + this->push(stack_.top()); + stack_.pop(); + } + } + private: + inline Container& getContainer(void) { + return this->c; + } + }; + } // namespace workarounds +#endif // defined(ELPP_STL_LOGGING) + // Log message builder + class MessageBuilder { + public: + MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {} + void initialize(Logger* logger) { + m_logger = logger; + m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ? + ELPP_LITERAL("\n ") : ELPP_LITERAL(", "); + } + +# define ELPP_SIMPLE_LOG(LOG_TYPE)\ +inline MessageBuilder& operator<<(LOG_TYPE msg) {\ +m_logger->stream() << msg;\ +if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) {\ +m_logger->stream() << " ";\ +}\ +return *this;\ +} + + inline MessageBuilder& operator<<(const std::string& msg) { + return operator<<(msg.c_str()); + } + ELPP_SIMPLE_LOG(char) + ELPP_SIMPLE_LOG(bool) + ELPP_SIMPLE_LOG(signed short) + ELPP_SIMPLE_LOG(unsigned short) + ELPP_SIMPLE_LOG(signed int) + ELPP_SIMPLE_LOG(unsigned int) + ELPP_SIMPLE_LOG(signed long) + ELPP_SIMPLE_LOG(unsigned long) + ELPP_SIMPLE_LOG(float) + ELPP_SIMPLE_LOG(double) + ELPP_SIMPLE_LOG(char*) + ELPP_SIMPLE_LOG(const char*) + ELPP_SIMPLE_LOG(const void*) + ELPP_SIMPLE_LOG(long double) + inline MessageBuilder& operator<<(const std::wstring& msg) { + return operator<<(msg.c_str()); + } + inline MessageBuilder& operator<<(const wchar_t* msg) { + if (msg == nullptr) { + m_logger->stream() << base::consts::kNullPointer; + return *this; + } +# if defined(ELPP_UNICODE) + m_logger->stream() << msg; +# else + char* buff_ = base::utils::Str::wcharPtrToCharPtr(msg); + m_logger->stream() << buff_; + free(buff_); +# endif + if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { + m_logger->stream() << " "; + } + return *this; + } + // ostream manipulators + inline MessageBuilder& operator<<(std::ostream& (*OStreamMani)(std::ostream&)) { + m_logger->stream() << OStreamMani; + return *this; + } +#define ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} +#define ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(temp) \ +template \ +inline MessageBuilder& operator<<(const temp& template_inst) { \ +return writeIterator(template_inst.begin(), template_inst.end(), template_inst.size()); \ +} + +#if defined(ELPP_STL_LOGGING) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::vector) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::list) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(std::deque) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::set) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(std::multiset) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::map) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::multimap) + template + inline MessageBuilder& operator<<(const std::queue& queue_) { + base::workarounds::IterableQueue iterableQueue_ = + static_cast >(queue_); + return writeIterator(iterableQueue_.begin(), iterableQueue_.end(), iterableQueue_.size()); + } + template + inline MessageBuilder& operator<<(const std::stack& stack_) { + base::workarounds::IterableStack iterableStack_ = + static_cast >(stack_); + return writeIterator(iterableStack_.begin(), iterableStack_.end(), iterableStack_.size()); + } + template + inline MessageBuilder& operator<<(const std::priority_queue& priorityQueue_) { + base::workarounds::IterablePriorityQueue iterablePriorityQueue_ = + static_cast >(priorityQueue_); + return writeIterator(iterablePriorityQueue_.begin(), iterablePriorityQueue_.end(), iterablePriorityQueue_.size()); + } + template + inline MessageBuilder& operator<<(const std::pair& pair_) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(pair_.first)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(pair_.second)); + m_logger->stream() << ELPP_LITERAL(")"); + return *this; + } + template + inline MessageBuilder& operator<<(const std::bitset& bitset_) { + m_logger->stream() << ELPP_LITERAL("["); + operator << (bitset_.to_string()); + m_logger->stream() << ELPP_LITERAL("]"); + return *this; + } +# if defined(ELPP_LOG_STD_ARRAY) + template + inline MessageBuilder& operator<<(const std::array& array) { + return writeIterator(array.begin(), array.end(), array.size()); + } +# endif // defined(ELPP_LOG_STD_ARRAY) +# if defined(ELPP_LOG_UNORDERED_MAP) + ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_map) + ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG(std::unordered_multimap) +# endif // defined(ELPP_LOG_UNORDERED_MAP) +# if defined(ELPP_LOG_UNORDERED_SET) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_set) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(std::unordered_multiset) +# endif // defined(ELPP_LOG_UNORDERED_SET) +#endif // defined(ELPP_STL_LOGGING) +#if defined(ELPP_QT_LOGGING) + inline MessageBuilder& operator<<(const QString& msg) { +# if defined(ELPP_UNICODE) + m_logger->stream() << msg.toStdWString(); +# else + m_logger->stream() << msg.toStdString(); +# endif // defined(ELPP_UNICODE) + return *this; + } + inline MessageBuilder& operator<<(const QByteArray& msg) { + return operator << (QString(msg)); + } + inline MessageBuilder& operator<<(const QStringRef& msg) { + return operator<<(msg.toString()); + } + inline MessageBuilder& operator<<(qint64 msg) { +# if defined(ELPP_UNICODE) + m_logger->stream() << QString::number(msg).toStdWString(); +# else + m_logger->stream() << QString::number(msg).toStdString(); +# endif // defined(ELPP_UNICODE) + return *this; + } + inline MessageBuilder& operator<<(quint64 msg) { +# if defined(ELPP_UNICODE) + m_logger->stream() << QString::number(msg).toStdWString(); +# else + m_logger->stream() << QString::number(msg).toStdString(); +# endif // defined(ELPP_UNICODE) + return *this; + } + inline MessageBuilder& operator<<(QChar msg) { + m_logger->stream() << msg.toLatin1(); + return *this; + } + inline MessageBuilder& operator<<(const QLatin1String& msg) { + m_logger->stream() << msg.latin1(); + return *this; + } + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QList) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QVector) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QQueue) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QSet) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QLinkedList) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(QStack) + template + inline MessageBuilder& operator<<(const QPair& pair_) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(pair_.first)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(pair_.second)); + m_logger->stream() << ELPP_LITERAL(")"); + return *this; + } + template + inline MessageBuilder& operator<<(const QMap& map_) { + m_logger->stream() << ELPP_LITERAL("["); + QList keys = map_.keys(); + typename QList::const_iterator begin = keys.begin(); + typename QList::const_iterator end = keys.end(); + int max_ = static_cast(base::consts::kMaxLogPerContainer); // to prevent warning + for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(*begin)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(map_.value(*begin))); + m_logger->stream() << ELPP_LITERAL(")"); + m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); + } + if (begin != end) { + m_logger->stream() << ELPP_LITERAL("..."); + } + m_logger->stream() << ELPP_LITERAL("]"); + return *this; + } + template + inline MessageBuilder& operator<<(const QMultiMap& map_) { + operator << (static_cast>(map_)); + return *this; + } + template + inline MessageBuilder& operator<<(const QHash& hash_) { + m_logger->stream() << ELPP_LITERAL("["); + QList keys = hash_.keys(); + typename QList::const_iterator begin = keys.begin(); + typename QList::const_iterator end = keys.end(); + int max_ = static_cast(base::consts::kMaxLogPerContainer); // prevent type warning + for (int index_ = 0; begin != end && index_ < max_; ++index_, ++begin) { + m_logger->stream() << ELPP_LITERAL("("); + operator << (static_cast(*begin)); + m_logger->stream() << ELPP_LITERAL(", "); + operator << (static_cast(hash_.value(*begin))); + m_logger->stream() << ELPP_LITERAL(")"); + m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); + } + if (begin != end) { + m_logger->stream() << ELPP_LITERAL("..."); + } + m_logger->stream() << ELPP_LITERAL("]"); + return *this; + } + template + inline MessageBuilder& operator<<(const QMultiHash& multiHash_) { + operator << (static_cast>(multiHash_)); + return *this; + } +#endif // defined(ELPP_QT_LOGGING) +#if defined(ELPP_BOOST_LOGGING) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::vector) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::stable_vector) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::list) + ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG(boost::container::deque) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::map) + ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG(boost::container::flat_map) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::set) + ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG(boost::container::flat_set) +#endif // defined(ELPP_BOOST_LOGGING) + + /// @brief Macro used internally that can be used externally to make containers easylogging++ friendly + /// + /// @detail This macro expands to write an ostream& operator<< for container. This container is expected to + /// have begin() and end() methods that return respective iterators + /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets + /// @param SizeMethod Method used to get size of container. + /// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro + /// for an example usage +#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \ +el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\ +const el::base::type::char_t* sep = ELPP->hasFlag(el::LoggingFlag::NewLineForContainer) ? \ +ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");\ +ContainerType::const_iterator elem = container.begin();\ +ContainerType::const_iterator endElem = container.end();\ +std::size_t size_ = container.SizeMethod; \ +ss << ELPP_LITERAL("[");\ +for (std::size_t i = 0; elem != endElem && i < el::base::consts::kMaxLogPerContainer; ++i, ++elem) { \ +ss << ElementInstance;\ +ss << ((i < size_ - 1) ? sep : ELPP_LITERAL(""));\ +}\ +if (elem != endElem) {\ +ss << ELPP_LITERAL("...");\ +}\ +ss << ELPP_LITERAL("]");\ +return ss;\ +} +#if defined(ELPP_WXWIDGETS_LOGGING) + ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG(wxVector) +# define ELPP_WX_PTR_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), *(*elem)) +# define ELPP_WX_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), (*elem)) +# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) MAKE_CONTAINERELPP_FRIENDLY(ContainerType, size(), \ +ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_LITERAL(")") +#else +# define ELPP_WX_PTR_ENABLED(ContainerType) +# define ELPP_WX_ENABLED(ContainerType) +# define ELPP_WX_HASH_MAP_ENABLED(ContainerType) +#endif // defined(ELPP_WXWIDGETS_LOGGING) + // Other classes + template + ELPP_SIMPLE_LOG(const Class&) +#undef ELPP_SIMPLE_LOG +#undef ELPP_ITERATOR_CONTAINER_LOG_ONE_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_TWO_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_THREE_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_FOUR_ARG +#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG + private: + Logger* m_logger; + const base::type::char_t* m_containerLogSeperator; + + template + inline MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) { + m_logger->stream() << ELPP_LITERAL("["); + for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) { + operator << (*begin_); + m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL("")); + } + if (begin_ != end_) { + m_logger->stream() << ELPP_LITERAL("..."); + } + m_logger->stream() << ELPP_LITERAL("]"); + if (ELPP->hasFlag(LoggingFlag::AutoSpacing)) { + m_logger->stream() << " "; + } + return *this; + } + }; + /// @brief Writes nothing - Used when certain log is disabled + class NullWriter : base::NoCopy { + public: + NullWriter(void) {} + + // Null manipulator + inline NullWriter& operator<<(std::ostream& (*)(std::ostream&)) { + return *this; + } + + template + inline NullWriter& operator<<(const T&) { + return *this; + } + }; + /// @brief Main entry point of each logging + class Writer : base::NoCopy { + public: + Writer(Level level, const char* file, unsigned long int line, + const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, + base::type::VerboseLevel verboseLevel = 0) : + m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel), + m_proceed(false), m_dispatchAction(dispatchAction) { + } + + virtual ~Writer(void) { + processDispatch(); + } + + template + inline Writer& operator<<(const T& log) { +#if ELPP_LOGGING_ENABLED + if (m_proceed) { + m_messageBuilder << log; + } +#endif // ELPP_LOGGING_ENABLED + return *this; + } + + inline Writer& operator<<(std::ostream& (*log)(std::ostream&)) { +#if ELPP_LOGGING_ENABLED + if (m_proceed) { + m_messageBuilder << log; + } +#endif // ELPP_LOGGING_ENABLED + return *this; + } + + Writer& construct(Logger* logger, bool needLock = true) { + m_logger = logger; + initializeLogger(logger->id(), false, needLock); + m_messageBuilder.initialize(m_logger); + return *this; + } + + Writer& construct(int count, const char* loggerIds, ...) { + if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { + va_list loggersList; + va_start(loggersList, loggerIds); + const char* id = loggerIds; + for (int i = 0; i < count; ++i) { + m_loggerIds.push_back(std::string(id)); + id = va_arg(loggersList, const char*); + } + va_end(loggersList); + initializeLogger(m_loggerIds.at(0)); + } else { + initializeLogger(std::string(loggerIds)); + } + m_messageBuilder.initialize(m_logger); + return *this; + } + protected: + Level m_level; + const char* m_file; + const unsigned long int m_line; + const char* m_func; + base::type::VerboseLevel m_verboseLevel; + Logger* m_logger; + bool m_proceed; + base::MessageBuilder m_messageBuilder; + base::DispatchAction m_dispatchAction; + std::vector m_loggerIds; + friend class el::Helpers; + + void initializeLogger(const std::string& loggerId, bool lookup = true, bool needLock = true) { + if (lookup) { + m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically)); + } + if (m_logger == nullptr) { + ELPP->acquireLock(); + if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) { + // Somehow default logger has been unregistered. Not good! Register again + ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId)); + } + ELPP->releaseLock(); // Need to unlock it for next writer + Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) + << "Logger [" << loggerId << "] is not registered yet!"; + m_proceed = false; + } else { + if (needLock) { + m_logger->acquireLock(); // This should not be unlocked by checking m_proceed because + // m_proceed can be changed by lines below + } + if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) { + m_proceed = m_level == Level::Verbose ? m_logger->enabled(m_level) : + LevelHelper::castToInt(m_level) >= LevelHelper::castToInt(ELPP->m_loggingLevel); + } else { + m_proceed = m_logger->enabled(m_level); + } + } + } + + void processDispatch() { +#if ELPP_LOGGING_ENABLED + if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { + bool firstDispatched = false; + base::type::string_t logMessage; + std::size_t i = 0; + do { + if (m_proceed) { + if (firstDispatched) { + m_logger->stream() << logMessage; + } else { + firstDispatched = true; + if (m_loggerIds.size() > 1) { + logMessage = m_logger->stream().str(); + } + } + triggerDispatch(); + } else if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + if (i + 1 < m_loggerIds.size()) { + initializeLogger(m_loggerIds.at(i + 1)); + } + } while (++i < m_loggerIds.size()); + } else { + if (m_proceed) { + triggerDispatch(); + } else if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + } +#else + if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } +#endif // ELPP_LOGGING_ENABLED + } + + void triggerDispatch(void) { + if (m_proceed) { + base::LogDispatcher(m_proceed, LogMessage(m_level, m_file, m_line, m_func, m_verboseLevel, + m_logger), m_dispatchAction).dispatch(); + } + if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + if (m_proceed && m_level == Level::Fatal + && !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) { + base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) + << "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]"; + std::stringstream reasonStream; + reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]" + << " If you wish to disable 'abort on fatal log' please use " + << "el::Helpers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)"; + base::utils::abort(1, reasonStream.str()); + } + m_proceed = false; + } + }; + class PErrorWriter : public base::Writer { + public: + PErrorWriter(Level level, const char* file, unsigned long int line, + const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog, + base::type::VerboseLevel verboseLevel = 0) : + base::Writer(level, file, line, func, dispatchAction, verboseLevel) { + } + + virtual ~PErrorWriter(void) { + if (m_proceed) { +#if ELPP_COMPILER_MSVC + char buff[256]; + strerror_s(buff, 256, errno); + m_logger->stream() << ": " << buff << " [" << errno << "]"; +#else + m_logger->stream() << ": " << strerror(errno) << " [" << errno << "]"; +#endif + } + } + }; + } // namespace base + // Logging from Logger class. Why this is here? Because we have Storage and Writer class available +#if ELPP_VARIADIC_TEMPLATES_SUPPORTED + template + void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) { + base::MessageBuilder b; + b.initialize(this); + while (*s) { + if (*s == base::consts::kFormatSpecifierChar) { + if (*(s + 1) == base::consts::kFormatSpecifierChar) { + ++s; + } else { + if (*(s + 1) == base::consts::kFormatSpecifierCharValue) { + ++s; + b << value; + log_(level, vlevel, ++s, args...); + return; + } + } + } + b << *s++; + } + ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false); + } + template + inline void Logger::log_(Level level, int vlevel, const T& log) { + if (level == Level::Verbose) { + if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) { + base::Writer(Level::Verbose, "FILE", 0, "FUNCTION", + base::DispatchAction::NormalLog, vlevel).construct(this, false) << log; + } else { + stream().str(ELPP_LITERAL("")); + } + } else { + base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log; + } + } + template + void Logger::log(Level level, const char* s, const T& value, const Args&... args) { + base::threading::ScopedLock scopedLock(lock()); + log_(level, 0, s, value, args...); + } + template + inline void Logger::log(Level level, const T& log) { + base::threading::ScopedLock scopedLock(lock()); + log_(level, 0, log); + } +# if ELPP_VERBOSE_LOG + template + inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) { + base::threading::ScopedLock scopedLock(lock()); + log_(el::Level::Verbose, vlevel, s, value, args...); + } + template + inline void Logger::verbose(int vlevel, const T& log) { + base::threading::ScopedLock scopedLock(lock()); + log_(el::Level::Verbose, vlevel, log); + } +# else + template + inline void Logger::verbose(int, const char*, const T&, const Args&...) { + return; + } + template + inline void Logger::verbose(int, const T&) { + return; + } +# endif // ELPP_VERBOSE_LOG +# define LOGGER_LEVEL_WRITERS(FUNCTION_NAME, LOG_LEVEL)\ +template \ +inline void Logger::FUNCTION_NAME(const char* s, const T& value, const Args&... args) {\ +log(LOG_LEVEL, s, value, args...);\ +}\ +template \ +inline void Logger::FUNCTION_NAME(const T& value) {\ +log(LOG_LEVEL, value);\ +} +# define LOGGER_LEVEL_WRITERS_DISABLED(FUNCTION_NAME, LOG_LEVEL)\ +template \ +inline void Logger::FUNCTION_NAME(const char*, const T&, const Args&...) {\ +return;\ +}\ +template \ +inline void Logger::FUNCTION_NAME(const T&) {\ +return;\ +} + +# if ELPP_INFO_LOG + LOGGER_LEVEL_WRITERS(info, Level::Info) +# else + LOGGER_LEVEL_WRITERS_DISABLED(info, Level::Info) +# endif // ELPP_INFO_LOG +# if ELPP_DEBUG_LOG + LOGGER_LEVEL_WRITERS(debug, Level::Debug) +# else + LOGGER_LEVEL_WRITERS_DISABLED(debug, Level::Debug) +# endif // ELPP_DEBUG_LOG +# if ELPP_WARNING_LOG + LOGGER_LEVEL_WRITERS(warn, Level::Warning) +# else + LOGGER_LEVEL_WRITERS_DISABLED(warn, Level::Warning) +# endif // ELPP_WARNING_LOG +# if ELPP_ERROR_LOG + LOGGER_LEVEL_WRITERS(error, Level::Error) +# else + LOGGER_LEVEL_WRITERS_DISABLED(error, Level::Error) +# endif // ELPP_ERROR_LOG +# if ELPP_FATAL_LOG + LOGGER_LEVEL_WRITERS(fatal, Level::Fatal) +# else + LOGGER_LEVEL_WRITERS_DISABLED(fatal, Level::Fatal) +# endif // ELPP_FATAL_LOG +# if ELPP_TRACE_LOG + LOGGER_LEVEL_WRITERS(trace, Level::Trace) +# else + LOGGER_LEVEL_WRITERS_DISABLED(trace, Level::Trace) +# endif // ELPP_TRACE_LOG +# undef LOGGER_LEVEL_WRITERS +# undef LOGGER_LEVEL_WRITERS_DISABLED +#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED +#if ELPP_COMPILER_MSVC +# define ELPP_VARIADIC_FUNC_MSVC(variadicFunction, variadicArgs) variadicFunction variadicArgs +# define ELPP_VARIADIC_FUNC_MSVC_RUN(variadicFunction, ...) ELPP_VARIADIC_FUNC_MSVC(variadicFunction, (__VA_ARGS__)) +# define el_getVALength(...) ELPP_VARIADIC_FUNC_MSVC_RUN(el_resolveVALength, 0, ## __VA_ARGS__,\ +10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#else +# if ELPP_COMPILER_CLANG +# define el_getVALength(...) el_resolveVALength(0, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +# else +# define el_getVALength(...) el_resolveVALength(0, ## __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +# endif // ELPP_COMPILER_CLANG +#endif // ELPP_COMPILER_MSVC +#define el_resolveVALength(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N +#define ELPP_WRITE_LOG(writer, level, dispatchAction, ...) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_IF(writer, condition, level, dispatchAction, ...) if (condition) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_EVERY_N(writer, occasion, level, dispatchAction, ...) \ +if (ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion)) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_AFTER_N(writer, n, level, dispatchAction, ...) \ +if (ELPP->validateAfterNCounter(__FILE__, __LINE__, n)) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#define ELPP_WRITE_LOG_N_TIMES(writer, n, level, dispatchAction, ...) \ +if (ELPP->validateNTimesCounter(__FILE__, __LINE__, n)) \ +writer(level, __FILE__, __LINE__, ELPP_FUNC, dispatchAction).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#undef ELPP_CURR_FILE_PERFORMANCE_LOGGER +#if defined(ELPP_PERFORMANCE_LOGGER) +# define ELPP_CURR_FILE_PERFORMANCE_LOGGER ELPP_PERFORMANCE_LOGGER +#else +# define ELPP_CURR_FILE_PERFORMANCE_LOGGER el::base::consts::kPerformanceLoggerId +#endif + class PerformanceTrackingData { + public: + enum class DataType : base::type::EnumType { + Checkpoint = 1, Complete = 2 + }; + // Do not use constructor, will run into multiple definition error, use init(PerformanceTracker*) + explicit PerformanceTrackingData(DataType dataType) : m_performanceTracker(nullptr), + m_dataType(dataType), m_file(""), m_line(0), m_func("") {} + inline const std::string* blockName(void) const; + inline const struct timeval* startTime(void) const; + inline const struct timeval* endTime(void) const; + inline const struct timeval* lastCheckpointTime(void) const; + inline const base::PerformanceTracker* performanceTracker(void) const { return m_performanceTracker; } + inline PerformanceTrackingData::DataType dataType(void) const { return m_dataType; } + inline bool firstCheckpoint(void) const { return m_firstCheckpoint; } + inline std::string checkpointId(void) const { return m_checkpointId; } + inline const char* file(void) const { return m_file; } + inline unsigned long int line(void) const { return m_line; } + inline const char* func(void) const { return m_func; } + inline const base::type::string_t* formattedTimeTaken() const { return &m_formattedTimeTaken; } + inline const std::string& loggerId(void) const; + private: + base::PerformanceTracker* m_performanceTracker; + base::type::string_t m_formattedTimeTaken; + PerformanceTrackingData::DataType m_dataType; + bool m_firstCheckpoint; + std::string m_checkpointId; + const char* m_file; + unsigned long int m_line; + const char* m_func; + inline void init(base::PerformanceTracker* performanceTracker, bool firstCheckpoint = false) { + m_performanceTracker = performanceTracker; + m_firstCheckpoint = firstCheckpoint; + } + + friend class el::base::PerformanceTracker; + }; + namespace base { + /// @brief Represents performanceTracker block of code that conditionally adds performance status to log + /// either when goes outside the scope of when checkpoint() is called + class PerformanceTracker : public base::threading::ThreadSafe, public Loggable { + public: + PerformanceTracker(const std::string& blockName, + base::TimestampUnit timestampUnit = base::TimestampUnit::Millisecond, + const std::string& loggerId = std::string(ELPP_CURR_FILE_PERFORMANCE_LOGGER), + bool scopedLog = true, Level level = base::consts::kPerformanceTrackerDefaultLevel) : + m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog), + m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) { +#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + // We store it locally so that if user happen to change configuration by the end of scope + // or before calling checkpoint, we still depend on state of configuraton at time of construction + el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false); + m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level); + if (m_enabled) { + base::utils::DateTime::gettimeofday(&m_startTime); + } +#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + } + /// @brief Copy constructor + PerformanceTracker(const PerformanceTracker& t) : + m_blockName(t.m_blockName), m_timestampUnit(t.m_timestampUnit), m_loggerId(t.m_loggerId), m_scopedLog(t.m_scopedLog), + m_level(t.m_level), m_hasChecked(t.m_hasChecked), m_lastCheckpointId(t.m_lastCheckpointId), m_enabled(t.m_enabled), + m_startTime(t.m_startTime), m_endTime(t.m_endTime), m_lastCheckpointTime(t.m_lastCheckpointTime) { + } + virtual ~PerformanceTracker(void) { +#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + if (m_enabled) { + base::threading::ScopedLock scopedLock(lock()); + if (m_scopedLog) { + base::utils::DateTime::gettimeofday(&m_endTime); + base::type::string_t formattedTime = getFormattedTimeTaken(); + PerformanceTrackingData data(PerformanceTrackingData::DataType::Complete); + data.init(this); + data.m_formattedTimeTaken = formattedTime; + PerformanceTrackingCallback* callback = nullptr; + for (const std::pair& h + : ELPP->m_performanceTrackingCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + callback->acquireLock(); + callback->handle(&data); + callback->releaseLock(); + } + } + } + } +#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) + } + /// @brief A checkpoint for current performanceTracker block. + void checkpoint(const std::string& id = std::string(), const char* file = __FILE__, unsigned long int line = __LINE__, const char* func = "") { +#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + if (m_enabled) { + base::threading::ScopedLock scopedLock(lock()); + base::utils::DateTime::gettimeofday(&m_endTime); + base::type::string_t formattedTime = m_hasChecked ? getFormattedTimeTaken(m_lastCheckpointTime) : ELPP_LITERAL(""); + PerformanceTrackingData data(PerformanceTrackingData::DataType::Checkpoint); + data.init(this); + data.m_checkpointId = id; + data.m_file = file; + data.m_line = line; + data.m_func = func; + data.m_formattedTimeTaken = formattedTime; + PerformanceTrackingCallback* callback = nullptr; + for (const std::pair& h + : ELPP->m_performanceTrackingCallbacks) { + callback = h.second.get(); + if (callback != nullptr && callback->enabled()) { + callback->acquireLock(); + callback->handle(&data); + callback->releaseLock(); + } + } + base::utils::DateTime::gettimeofday(&m_lastCheckpointTime); + m_hasChecked = true; + m_lastCheckpointId = id; + } +#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED + ELPP_UNUSED(id); + ELPP_UNUSED(file); + ELPP_UNUSED(line); + ELPP_UNUSED(func); + } + inline Level level(void) const { return m_level; } + private: + std::string m_blockName; + base::TimestampUnit m_timestampUnit; + std::string m_loggerId; + bool m_scopedLog; + Level m_level; + bool m_hasChecked; + std::string m_lastCheckpointId; + bool m_enabled; + struct timeval m_startTime, m_endTime, m_lastCheckpointTime; + + PerformanceTracker(void); + + friend class el::PerformanceTrackingData; + friend class base::DefaultPerformanceTrackingCallback; + + const inline base::type::string_t getFormattedTimeTaken() const { + return getFormattedTimeTaken(m_startTime); + } + + const base::type::string_t getFormattedTimeTaken(struct timeval startTime) const { + if (ELPP->hasFlag(LoggingFlag::FixedTimeFormat)) { + base::type::stringstream_t ss; + ss << base::utils::DateTime::getTimeDifference(m_endTime, + startTime, m_timestampUnit) << " " << base::consts::kTimeFormats[static_cast(m_timestampUnit)].unit; + return ss.str(); + } + return base::utils::DateTime::formatTime(base::utils::DateTime::getTimeDifference(m_endTime, + startTime, m_timestampUnit), m_timestampUnit); + } + + virtual inline void log(el::base::type::ostream_t& os) const { + os << getFormattedTimeTaken(); + } + }; + class DefaultPerformanceTrackingCallback : public PerformanceTrackingCallback { + protected: + void handle(const PerformanceTrackingData* data) { + m_data = data; + base::type::stringstream_t ss; + if (m_data->dataType() == PerformanceTrackingData::DataType::Complete) { + ss << ELPP_LITERAL("Executed [") << m_data->blockName()->c_str() << ELPP_LITERAL("] in [") << *m_data->formattedTimeTaken() << ELPP_LITERAL("]"); + } else { + ss << ELPP_LITERAL("Performance checkpoint"); + if (!m_data->checkpointId().empty()) { + ss << ELPP_LITERAL(" [") << m_data->checkpointId().c_str() << ELPP_LITERAL("]"); + } + ss << ELPP_LITERAL(" for block [") << m_data->blockName()->c_str() << ELPP_LITERAL("] : [") << *m_data->performanceTracker(); + if (!ELPP->hasFlag(LoggingFlag::DisablePerformanceTrackingCheckpointComparison) && m_data->performanceTracker()->m_hasChecked) { + ss << ELPP_LITERAL(" ([") << *m_data->formattedTimeTaken() << ELPP_LITERAL("] from "); + if (m_data->performanceTracker()->m_lastCheckpointId.empty()) { + ss << ELPP_LITERAL("last checkpoint"); + } else { + ss << ELPP_LITERAL("checkpoint '") << m_data->performanceTracker()->m_lastCheckpointId.c_str() << ELPP_LITERAL("'"); + } + ss << ELPP_LITERAL(")]"); + } else { + ss << ELPP_LITERAL("]"); + } + } + el::base::Writer(m_data->performanceTracker()->level(), m_data->file(), m_data->line(), m_data->func()).construct(1, m_data->loggerId().c_str()) << ss.str(); + } + private: + const PerformanceTrackingData* m_data; + }; + } // namespace base + inline const std::string* PerformanceTrackingData::blockName() const { + return const_cast(&m_performanceTracker->m_blockName); + } + inline const struct timeval* PerformanceTrackingData::startTime() const { + return const_cast(&m_performanceTracker->m_startTime); + } + inline const struct timeval* PerformanceTrackingData::endTime() const { + return const_cast(&m_performanceTracker->m_endTime); + } + inline const struct timeval* PerformanceTrackingData::lastCheckpointTime() const { + return const_cast(&m_performanceTracker->m_lastCheckpointTime); + } + inline const std::string& PerformanceTrackingData::loggerId(void) const { return m_performanceTracker->m_loggerId; } + namespace base { + /// @brief Contains some internal debugging tools like crash handler and stack tracer + namespace debug { + class StackTrace : base::NoCopy { + public: + static const std::size_t kMaxStack = 64; + static const std::size_t kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew() + class StackTraceEntry { + public: + StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, const char* addr) { + m_index = index; + m_location = std::string(loc); + m_demangled = std::string(demang); + m_hex = std::string(hex); + m_addr = std::string(addr); + } + StackTraceEntry(std::size_t index, char* loc) { + m_index = index; + m_location = std::string(loc); + } + std::size_t m_index; + std::string m_location; + std::string m_demangled; + std::string m_hex; + std::string m_addr; + friend std::ostream& operator<<(std::ostream& ss, const StackTraceEntry& si) { + ss << "[" << si.m_index << "] " << si.m_location << (si.m_demangled.empty() ? "" : ":") << si.m_demangled + << (si.m_hex.empty() ? "" : "+") << si.m_hex << si.m_addr; + return ss; + } + + private: + StackTraceEntry(void); + }; + + StackTrace(void) { + generateNew(); + } + + virtual ~StackTrace(void) { + } + + inline std::vector& getLatestStack(void) { + return m_stack; + } + + friend inline std::ostream& operator<<(std::ostream& os, const StackTrace& st) { + std::vector::const_iterator it = st.m_stack.begin(); + while (it != st.m_stack.end()) { + os << " " << *it++ << "\n"; + } + return os; + } + + private: + std::vector m_stack; + + void generateNew(void) { +#if ELPP_STACKTRACE + m_stack.clear(); + void* stack[kMaxStack]; + std::size_t size = backtrace(stack, kMaxStack); + char** strings = backtrace_symbols(stack, size); + if (size > kStackStart) { // Skip StackTrace c'tor and generateNew + for (std::size_t i = kStackStart; i < size; ++i) { + char* mangName = nullptr; + char* hex = nullptr; + char* addr = nullptr; + for (char* c = strings[i]; *c; ++c) { + switch (*c) { + case '(': + mangName = c; + break; + case '+': + hex = c; + break; + case ')': + addr = c; + break; + default: + break; + } + } + // Perform demangling if parsed properly + if (mangName != nullptr && hex != nullptr && addr != nullptr && mangName < hex) { + *mangName++ = '\0'; + *hex++ = '\0'; + *addr++ = '\0'; + int status = 0; + char* demangName = abi::__cxa_demangle(mangName, 0, 0, &status); + // if demangling is successful, output the demangled function name + if (status == 0) { + // Success (see http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html) + StackTraceEntry entry(i - 1, strings[i], demangName, hex, addr); + m_stack.push_back(entry); + } else { + // Not successful - we will use mangled name + StackTraceEntry entry(i - 1, strings[i], mangName, hex, addr); + m_stack.push_back(entry); + } + free(demangName); + } else { + StackTraceEntry entry(i - 1, strings[i]); + m_stack.push_back(entry); + } + } + } + free(strings); +#else + ELPP_INTERNAL_INFO(1, "Stacktrace generation not supported for selected compiler"); +#endif // ELPP_STACKTRACE + } + }; + static std::string crashReason(int sig) { + std::stringstream ss; + bool foundReason = false; + for (int i = 0; i < base::consts::kCrashSignalsCount; ++i) { + if (base::consts::kCrashSignals[i].numb == sig) { + ss << "Application has crashed due to [" << base::consts::kCrashSignals[i].name << "] signal"; + if (ELPP->hasFlag(el::LoggingFlag::LogDetailedCrashReason)) { + ss << std::endl << + " " << base::consts::kCrashSignals[i].brief << std::endl << + " " << base::consts::kCrashSignals[i].detail; + } + foundReason = true; + } + } + if (!foundReason) { + ss << "Application has crashed due to unknown signal [" << sig << "]"; + } + return ss.str(); + } + /// @brief Logs reason of crash from sig + static void logCrashReason(int sig, bool stackTraceIfAvailable, Level level, const char* logger) { + std::stringstream ss; + ss << "CRASH HANDLED; "; + ss << crashReason(sig); +#if ELPP_STACKTRACE + if (stackTraceIfAvailable) { + ss << std::endl << " ======= Backtrace: =========" << std::endl << base::debug::StackTrace(); + } +#else + ELPP_UNUSED(stackTraceIfAvailable); +#endif // ELPP_STACKTRACE + ELPP_WRITE_LOG(el::base::Writer, level, base::DispatchAction::NormalLog, logger) << ss.str(); + } + static inline void crashAbort(int sig) { + base::utils::abort(sig); + } + /// @brief Default application crash handler + /// + /// @detail This function writes log using 'default' logger, prints stack trace for GCC based compilers and aborts program. + static inline void defaultCrashHandler(int sig) { + base::debug::logCrashReason(sig, true, Level::Fatal, base::consts::kDefaultLoggerId); + base::debug::crashAbort(sig); + } + /// @brief Handles unexpected crashes + class CrashHandler : base::NoCopy { + public: + typedef void (*Handler)(int); + + explicit CrashHandler(bool useDefault) { + if (useDefault) { + setHandler(defaultCrashHandler); + } + } + explicit CrashHandler(const Handler& cHandler) { + setHandler(cHandler); + } + void setHandler(const Handler& cHandler) { + m_handler = cHandler; +#if defined(ELPP_HANDLE_SIGABRT) + int i = 0; // SIGABRT is at base::consts::kCrashSignals[0] +#else + int i = 1; +#endif // defined(ELPP_HANDLE_SIGABRT) + for (; i < base::consts::kCrashSignalsCount; ++i) { + m_handler = signal(base::consts::kCrashSignals[i].numb, cHandler); + } + } + + private: + Handler m_handler; + }; + } // namespace debug + } // namespace base + extern base::debug::CrashHandler elCrashHandler; +#define MAKE_LOGGABLE(ClassType, ClassInstance, OutputStreamInstance) \ +el::base::type::ostream_t& operator<<(el::base::type::ostream_t& OutputStreamInstance, const ClassType& ClassInstance) + /// @brief Initializes syslog with process ID, options and facility. calls closelog() on d'tor + class SysLogInitializer { + public: + SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) { +#if defined(ELPP_SYSLOG) + openlog(processIdent, options, facility); +#else + ELPP_UNUSED(processIdent); + ELPP_UNUSED(options); + ELPP_UNUSED(facility); +#endif // defined(ELPP_SYSLOG) + } + virtual ~SysLogInitializer(void) { +#if defined(ELPP_SYSLOG) + closelog(); +#endif // defined(ELPP_SYSLOG) + } + }; +#define ELPP_INITIALIZE_SYSLOG(id, opt, fac) el::SysLogInitializer elSyslogInit(id, opt, fac) + /// @brief Static helpers for developers + class Helpers : base::StaticClass { + public: + /// @brief Shares logging repository (base::Storage) + static inline void setStorage(base::type::StoragePointer storage) { + ELPP = storage; + } + /// @return Main storage repository + static inline base::type::StoragePointer storage() { + return ELPP; + } + /// @brief Sets application arguments and figures out whats active for logging and whats not. + static inline void setArgs(int argc, char** argv) { + ELPP->setApplicationArguments(argc, argv); + } + /// @copydoc setArgs(int argc, char** argv) + static inline void setArgs(int argc, const char** argv) { + ELPP->setApplicationArguments(argc, const_cast(argv)); + } + /// @brief Overrides default crash handler and installs custom handler. + /// @param crashHandler A functor with no return type that takes single int argument. + /// Handler is a typedef with specification: void (*Handler)(int) + static inline void setCrashHandler(const el::base::debug::CrashHandler::Handler& crashHandler) { + el::elCrashHandler.setHandler(crashHandler); + } + /// @brief Abort due to crash with signal in parameter + /// @param sig Crash signal + static inline void crashAbort(int sig, const char* sourceFile = "", unsigned int long line = 0) { + std::stringstream ss; + ss << base::debug::crashReason(sig).c_str(); + ss << " - [Called el::Helpers::crashAbort(" << sig << ")]"; + if (sourceFile != nullptr && strlen(sourceFile) > 0) { + ss << " - Source: " << sourceFile; + if (line > 0) + ss << ":" << line; + else + ss << " (line number not specified)"; + } + base::utils::abort(sig, ss.str()); + } + /// @brief Logs reason of crash as per sig + /// @param sig Crash signal + /// @param stackTraceIfAvailable Includes stack trace if available + /// @param level Logging level + /// @param logger Logger to use for logging + static inline void logCrashReason(int sig, bool stackTraceIfAvailable = false, + Level level = Level::Fatal, const char* logger = base::consts::kDefaultLoggerId) { + el::base::debug::logCrashReason(sig, stackTraceIfAvailable, level, logger); + } + /// @brief Installs pre rollout callback, this callback is triggered when log file is about to be rolled out + /// (can be useful for backing up) + static inline void installPreRollOutCallback(const PreRollOutCallback& callback) { + ELPP->setPreRollOutCallback(callback); + } + /// @brief Uninstalls pre rollout callback + static inline void uninstallPreRollOutCallback(void) { + ELPP->unsetPreRollOutCallback(); + } + /// @brief Installs post log dispatch callback, this callback is triggered when log is dispatched + template + static inline bool installLogDispatchCallback(const std::string& id) { + return ELPP->installLogDispatchCallback(id); + } + /// @brief Uninstalls log dispatch callback + template + static inline void uninstallLogDispatchCallback(const std::string& id) { + ELPP->uninstallLogDispatchCallback(id); + } + template + static inline T* logDispatchCallback(const std::string& id) { + return ELPP->logDispatchCallback(id); + } + /// @brief Installs post performance tracking callback, this callback is triggered when performance tracking is finished + template + static inline bool installPerformanceTrackingCallback(const std::string& id) { + return ELPP->installPerformanceTrackingCallback(id); + } + /// @brief Uninstalls post performance tracking handler + template + static inline void uninstallPerformanceTrackingCallback(const std::string& id) { + ELPP->uninstallPerformanceTrackingCallback(id); + } + template + static inline T* performanceTrackingCallback(const std::string& id) { + return ELPP->performanceTrackingCallback(id); + } + /// @brief Converts template to std::string - useful for loggable classes to log containers within log(std::ostream&) const + template + static std::string convertTemplateToStdString(const T& templ) { + el::Logger* logger = + ELPP->registeredLoggers()->get(el::base::consts::kDefaultLoggerId); + if (logger == nullptr) { + return std::string(); + } + base::MessageBuilder b; + b.initialize(logger); + logger->acquireLock(); + b << templ; +#if defined(ELPP_UNICODE) + std::string s = std::string(logger->stream().str().begin(), logger->stream().str().end()); +#else + std::string s = logger->stream().str(); +#endif // defined(ELPP_UNICODE) + logger->stream().str(ELPP_LITERAL("")); + logger->releaseLock(); + return s; + } + /// @brief Returns command line arguments (pointer) provided to easylogging++ + static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) { + return ELPP->commandLineArgs(); + } + /// @brief Installs user defined format specifier and handler + static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) { + ELPP->installCustomFormatSpecifier(customFormatSpecifier); + } + /// @brief Uninstalls user defined format specifier and handler + static inline bool uninstallCustomFormatSpecifier(const char* formatSpecifier) { + return ELPP->uninstallCustomFormatSpecifier(formatSpecifier); + } + /// @brief Returns true if custom format specifier is installed + static inline bool hasCustomFormatSpecifier(const char* formatSpecifier) { + return ELPP->hasCustomFormatSpecifier(formatSpecifier); + } + static inline void validateFileRolling(Logger* logger, Level level) { + if (logger == nullptr) return; + logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback()); + } + }; + /// @brief Static helpers to deal with loggers and their configurations + class Loggers : base::StaticClass { + public: + /// @brief Gets existing or registers new logger + static inline Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true) { + base::threading::ScopedLock scopedLock(ELPP->lock()); + return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable); + } + /// @brief Unregisters logger - use it only when you know what you are doing, you may unregister + /// loggers initialized / used by third-party libs. + static inline bool unregisterLogger(const std::string& identity) { + base::threading::ScopedLock scopedLock(ELPP->lock()); + return ELPP->registeredLoggers()->remove(identity); + } + /// @brief Whether or not logger with id is registered + static inline bool hasLogger(const std::string& identity) { + base::threading::ScopedLock scopedLock(ELPP->lock()); + return ELPP->registeredLoggers()->has(identity); + } + /// @brief Reconfigures specified logger with new configurations + static inline Logger* reconfigureLogger(Logger* logger, const Configurations& configurations) { + if (!logger) return nullptr; + logger->configure(configurations); + return logger; + } + /// @brief Reconfigures logger with new configurations after looking it up using identity + static inline Logger* reconfigureLogger(const std::string& identity, const Configurations& configurations) { + return Loggers::reconfigureLogger(Loggers::getLogger(identity), configurations); + } + /// @brief Reconfigures logger's single configuration + static inline Logger* reconfigureLogger(const std::string& identity, ConfigurationType configurationType, + const std::string& value) { + Logger* logger = Loggers::getLogger(identity); + if (logger == nullptr) { + return nullptr; + } + logger->configurations()->set(Level::Global, configurationType, value); + logger->reconfigure(); + return logger; + } + /// @brief Reconfigures all the existing loggers with new configurations + static inline void reconfigureAllLoggers(const Configurations& configurations) { + for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin(); + it != ELPP->registeredLoggers()->end(); ++it) { + Loggers::reconfigureLogger(it->second, configurations); + } + } + /// @brief Reconfigures single configuration for all the loggers + static inline void reconfigureAllLoggers(ConfigurationType configurationType, const std::string& value) { + reconfigureAllLoggers(Level::Global, configurationType, value); + } + /// @brief Reconfigures single configuration for all the loggers for specified level + static inline void reconfigureAllLoggers(Level level, ConfigurationType configurationType, + const std::string& value) { + for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->begin(); + it != ELPP->registeredLoggers()->end(); ++it) { + Logger* logger = it->second; + logger->configurations()->set(level, configurationType, value); + logger->reconfigure(); + } + } + /// @brief Sets default configurations. This configuration is used for future (and conditionally for existing) loggers + static inline void setDefaultConfigurations(const Configurations& configurations, bool reconfigureExistingLoggers = false) { + ELPP->registeredLoggers()->setDefaultConfigurations(configurations); + if (reconfigureExistingLoggers) { + Loggers::reconfigureAllLoggers(configurations); + } + } + /// @brief Returns current default + static inline const Configurations* defaultConfigurations(void) { + return ELPP->registeredLoggers()->defaultConfigurations(); + } + /// @brief Returns log stream reference pointer if needed by user + static inline const base::LogStreamsReferenceMap* logStreamsReference(void) { + return ELPP->registeredLoggers()->logStreamsReference(); + } + /// @brief Default typed configuration based on existing defaultConf + static base::TypedConfigurations defaultTypedConfigurations(void) { + return base::TypedConfigurations( + ELPP->registeredLoggers()->defaultConfigurations(), + ELPP->registeredLoggers()->logStreamsReference()); + } + /// @brief Populates all logger IDs in current repository. + /// @param [out] targetList List of fill up. + static inline std::vector* populateAllLoggerIds(std::vector* targetList) { + targetList->clear(); + for (base::RegisteredLoggers::iterator it = ELPP->registeredLoggers()->list().begin(); + it != ELPP->registeredLoggers()->list().end(); ++it) { + targetList->push_back(it->first); + } + return targetList; + } + /// @brief Sets configurations from global configuration file. + static void configureFromGlobal(const char* globalConfigurationFilePath) { + std::ifstream gcfStream(globalConfigurationFilePath, std::ifstream::in); + ELPP_ASSERT(gcfStream.is_open(), "Unable to open global configuration file [" << globalConfigurationFilePath + << "] for parsing."); + std::string line = std::string(); + std::stringstream ss; + Logger* logger = nullptr; + auto configure = [&](void) { + ELPP_INTERNAL_INFO(8, "Configuring logger: '" << logger->id() << "' with configurations \n" << ss.str() + << "\n--------------"); + Configurations c; + c.parseFromText(ss.str()); + logger->configure(c); + }; + while (gcfStream.good()) { + std::getline(gcfStream, line); + ELPP_INTERNAL_INFO(1, "Parsing line: " << line); + base::utils::Str::trim(line); + if (Configurations::Parser::isComment(line)) continue; + Configurations::Parser::ignoreComments(&line); + base::utils::Str::trim(line); + if (line.size() > 2 && base::utils::Str::startsWith(line, std::string(base::consts::kConfigurationLoggerId))) { + if (!ss.str().empty() && logger != nullptr) { + configure(); + } + ss.str(std::string("")); + line = line.substr(2); + base::utils::Str::trim(line); + if (line.size() > 1) { + ELPP_INTERNAL_INFO(1, "Getting logger: '" << line << "'"); + logger = getLogger(line); + } + } else { + ss << line << "\n"; + } + } + if (!ss.str().empty() && logger != nullptr) { + configure(); + } + } + /// @brief Configures loggers using command line arg. Ensure you have already set command line args, + /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger. + /// If true is returned that does not mean it has been configured successfully, it only means that it + /// has attempeted to configure logger using configuration file provided in argument + static inline bool configureFromArg(const char* argKey) { +#if defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) + ELPP_UNUSED(argKey); +#else + if (!Helpers::commandLineArgs()->hasParamWithValue(argKey)) { + return false; + } + configureFromGlobal(Helpers::commandLineArgs()->getParamValue(argKey)); +#endif // defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) + return true; + } + /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered + static inline void flushAll(void) { + ELPP->registeredLoggers()->flushAll(); + } + /// @brief Adds logging flag used internally. + static inline void addFlag(LoggingFlag flag) { + ELPP->addFlag(flag); + } + /// @brief Removes logging flag used internally. + static inline void removeFlag(LoggingFlag flag) { + ELPP->removeFlag(flag); + } + /// @brief Determines whether or not certain flag is active + static inline bool hasFlag(LoggingFlag flag) { + return ELPP->hasFlag(flag); + } + /// @brief Adds flag and removes it when scope goes out + class ScopedAddFlag { + public: + ScopedAddFlag(LoggingFlag flag) : m_flag(flag) { Loggers::addFlag(m_flag); } + ~ScopedAddFlag(void) { Loggers::removeFlag(m_flag); } + private: + LoggingFlag m_flag; + }; + /// @brief Removes flag and add it when scope goes out + class ScopedRemoveFlag { + public: + ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) { Loggers::removeFlag(m_flag); } + ~ScopedRemoveFlag(void) { Loggers::addFlag(m_flag); } + private: + LoggingFlag m_flag; + }; + /// @brief Sets hierarchy for logging. Needs to enable logging flag (HierarchicalLogging) + static inline void setLoggingLevel(Level level) { + ELPP->setLoggingLevel(level); + } + /// @brief Sets verbose level on the fly + static inline void setVerboseLevel(base::type::VerboseLevel level) { + ELPP->vRegistry()->setLevel(level); + } + /// @brief Gets current verbose level + static inline base::type::VerboseLevel verboseLevel(void) { + return ELPP->vRegistry()->level(); + } + /// @brief Sets vmodules as specified (on the fly) + static inline void setVModules(const char* modules) { + if (ELPP->vRegistry()->vModulesEnabled()) { + ELPP->vRegistry()->setModules(modules); + } + } + /// @brief Clears vmodules + static inline void clearVModules(void) { + ELPP->vRegistry()->clearModules(); + } + }; + class VersionInfo : base::StaticClass { + public: + /// @brief Current version number + static inline const std::string version(void) { return std::string("9.84"); } + /// @brief Release date of current version + static inline const std::string releaseDate(void) { return std::string("29-07-2016 1221hrs"); } + }; +} // namespace el +#undef VLOG_IS_ON +/// @brief Determines whether verbose logging is on for specified level current file. +#define VLOG_IS_ON(verboseLevel) (ELPP->vRegistry()->allowed(verboseLevel, __FILE__)) +#undef TIMED_BLOCK +#undef TIMED_SCOPE +#undef TIMED_SCOPE_IF +#undef TIMED_FUNC +#undef TIMED_FUNC_IF +#undef ELPP_MIN_UNIT +#if defined(ELPP_PERFORMANCE_MICROSECONDS) +# define ELPP_MIN_UNIT el::base::TimestampUnit::Microsecond +#else +# define ELPP_MIN_UNIT el::base::TimestampUnit::Millisecond +#endif // (defined(ELPP_PERFORMANCE_MICROSECONDS)) +/// @brief Performance tracked scope. Performance gets written when goes out of scope using +/// 'performance' logger. +/// +/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); +/// @see el::base::PerformanceTracker +/// @see el::base::PerformanceTracker::checkpoint +// Note: Do not surround this definition with null macro because of obj instance +#define TIMED_SCOPE_IF(obj, blockname, condition) el::base::type::PerformanceTrackerPtr obj( condition ? new el::base::PerformanceTracker(blockname, ELPP_MIN_UNIT) : nullptr ) +#define TIMED_SCOPE(obj, blockname) TIMED_SCOPE_IF(obj, blockname, true) +#define TIMED_BLOCK(obj, blockName) for (struct { int i; el::base::type::PerformanceTrackerPtr timer; } obj = { 0, \ +new el::base::PerformanceTracker(blockName, ELPP_MIN_UNIT) }; obj.i < 1; ++obj.i) +/// @brief Performance tracked function. Performance gets written when goes out of scope using +/// 'performance' logger. +/// +/// @detail Please note in order to check the performance at a certain time you can use obj->checkpoint(); +/// @see el::base::PerformanceTracker +/// @see el::base::PerformanceTracker::checkpoint +#define TIMED_FUNC(obj) TIMED_SCOPE(obj, ELPP_FUNC) +#define TIMED_FUNC_IF(obj,condition) TIMED_SCOPE_IF(obj, ELPP_FUNC, condition) // MARTIN WAS HERE +#undef PERFORMANCE_CHECKPOINT +#undef PERFORMANCE_CHECKPOINT_WITH_ID +#define PERFORMANCE_CHECKPOINT(obj) obj->checkpoint(std::string(), __FILE__, __LINE__, ELPP_FUNC) +#define PERFORMANCE_CHECKPOINT_WITH_ID(obj, id) obj->checkpoint(id, __FILE__, __LINE__, ELPP_FUNC) +#undef ELPP_COUNTER +#undef ELPP_COUNTER_POS +/// @brief Gets hit counter for file/line +#define ELPP_COUNTER (ELPP->hitCounters()->getCounter(__FILE__, __LINE__)) +/// @brief Gets hit counter position for file/line, -1 if not registered yet +#define ELPP_COUNTER_POS (ELPP_COUNTER == nullptr ? -1 : ELPP_COUNTER->hitCounts()) +// Undef levels to support LOG(LEVEL) +#undef INFO +#undef WARNING +#undef DEBUG +#undef ERROR +#undef FATAL +#undef TRACE +#undef VERBOSE +// Undef existing +#undef CINFO +#undef CWARNING +#undef CDEBUG +#undef CFATAL +#undef CERROR +#undef CTRACE +#undef CVERBOSE +#undef CINFO_IF +#undef CWARNING_IF +#undef CDEBUG_IF +#undef CERROR_IF +#undef CFATAL_IF +#undef CTRACE_IF +#undef CVERBOSE_IF +#undef CINFO_EVERY_N +#undef CWARNING_EVERY_N +#undef CDEBUG_EVERY_N +#undef CERROR_EVERY_N +#undef CFATAL_EVERY_N +#undef CTRACE_EVERY_N +#undef CVERBOSE_EVERY_N +#undef CINFO_AFTER_N +#undef CWARNING_AFTER_N +#undef CDEBUG_AFTER_N +#undef CERROR_AFTER_N +#undef CFATAL_AFTER_N +#undef CTRACE_AFTER_N +#undef CVERBOSE_AFTER_N +#undef CINFO_N_TIMES +#undef CWARNING_N_TIMES +#undef CDEBUG_N_TIMES +#undef CERROR_N_TIMES +#undef CFATAL_N_TIMES +#undef CTRACE_N_TIMES +#undef CVERBOSE_N_TIMES +// Normal logs +#if ELPP_INFO_LOG +# define CINFO(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE(writer, dispatchAction, ...) ELPP_WRITE_LOG(writer, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE(writer, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE(writer, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel)) writer(\ +el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#else +# define CVERBOSE(writer, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// Conditional logs +#if ELPP_INFO_LOG +# define CINFO_IF(writer, condition_, dispatchAction, ...) \ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_IF(writer, condition_, dispatchAction, ...)\ +ELPP_WRITE_LOG_IF(writer, (condition_), el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_IF(writer, condition_, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) if (VLOG_IS_ON(vlevel) && (condition_)) writer( \ +el::Level::Verbose, __FILE__, __LINE__, ELPP_FUNC, dispatchAction, vlevel).construct(el_getVALength(__VA_ARGS__), __VA_ARGS__) +#else +# define CVERBOSE_IF(writer, condition_, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// Occasional logs +#if ELPP_INFO_LOG +# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...)\ +ELPP_WRITE_LOG_EVERY_N(writer, occasion, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_EVERY_N(writer, occasion, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...)\ +CVERBOSE_IF(writer, ELPP->validateEveryNCounter(__FILE__, __LINE__, occasion), vlevel, dispatchAction, __VA_ARGS__) +#else +# define CVERBOSE_EVERY_N(writer, occasion, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// After N logs +#if ELPP_INFO_LOG +# define CINFO_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_AFTER_N(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_AFTER_N(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_AFTER_N(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...)\ +CVERBOSE_IF(writer, ELPP->validateAfterNCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) +#else +# define CVERBOSE_AFTER_N(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// N Times logs +#if ELPP_INFO_LOG +# define CINFO_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Info, dispatchAction, __VA_ARGS__) +#else +# define CINFO_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_INFO_LOG +#if ELPP_WARNING_LOG +# define CWARNING_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Warning, dispatchAction, __VA_ARGS__) +#else +# define CWARNING_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_WARNING_LOG +#if ELPP_DEBUG_LOG +# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Debug, dispatchAction, __VA_ARGS__) +#else +# define CDEBUG_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_DEBUG_LOG +#if ELPP_ERROR_LOG +# define CERROR_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Error, dispatchAction, __VA_ARGS__) +#else +# define CERROR_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_ERROR_LOG +#if ELPP_FATAL_LOG +# define CFATAL_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Fatal, dispatchAction, __VA_ARGS__) +#else +# define CFATAL_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_FATAL_LOG +#if ELPP_TRACE_LOG +# define CTRACE_N_TIMES(writer, n, dispatchAction, ...)\ +ELPP_WRITE_LOG_N_TIMES(writer, n, el::Level::Trace, dispatchAction, __VA_ARGS__) +#else +# define CTRACE_N_TIMES(writer, n, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_TRACE_LOG +#if ELPP_VERBOSE_LOG +# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...)\ +CVERBOSE_IF(writer, ELPP->validateNTimesCounter(__FILE__, __LINE__, n), vlevel, dispatchAction, __VA_ARGS__) +#else +# define CVERBOSE_N_TIMES(writer, n, vlevel, dispatchAction, ...) el::base::NullWriter() +#endif // ELPP_VERBOSE_LOG +// +// Custom Loggers - Requires (level, dispatchAction, loggerId/s) +// +// undef existing +#undef CLOG +#undef CLOG_VERBOSE +#undef CVLOG +#undef CLOG_IF +#undef CLOG_VERBOSE_IF +#undef CVLOG_IF +#undef CLOG_EVERY_N +#undef CVLOG_EVERY_N +#undef CLOG_AFTER_N +#undef CVLOG_AFTER_N +#undef CLOG_N_TIMES +#undef CVLOG_N_TIMES +// Normal logs +#define CLOG(LEVEL, ...)\ +C##LEVEL(el::base::Writer, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG(vlevel, ...) CVERBOSE(el::base::Writer, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +// Conditional logs +#define CLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_IF(condition, vlevel, ...)\ +CVERBOSE_IF(el::base::Writer, condition, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +// Hit counts based logs +#define CLOG_EVERY_N(n, LEVEL, ...)\ +C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_EVERY_N(n, vlevel, ...)\ +CVERBOSE_EVERY_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CLOG_AFTER_N(n, LEVEL, ...)\ +C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_AFTER_N(n, vlevel, ...)\ +CVERBOSE_AFTER_N(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CLOG_N_TIMES(n, LEVEL, ...)\ +C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CVLOG_N_TIMES(n, vlevel, ...)\ +CVERBOSE_N_TIMES(el::base::Writer, n, vlevel, el::base::DispatchAction::NormalLog, __VA_ARGS__) +// +// Default Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros +// +// undef existing +#undef LOG +#undef VLOG +#undef LOG_IF +#undef VLOG_IF +#undef LOG_EVERY_N +#undef VLOG_EVERY_N +#undef LOG_AFTER_N +#undef VLOG_AFTER_N +#undef LOG_N_TIMES +#undef VLOG_N_TIMES +#undef ELPP_CURR_FILE_LOGGER_ID +#if defined(ELPP_DEFAULT_LOGGER) +# define ELPP_CURR_FILE_LOGGER_ID ELPP_DEFAULT_LOGGER +#else +# define ELPP_CURR_FILE_LOGGER_ID el::base::consts::kDefaultLoggerId +#endif +#undef ELPP_TRACE +#define ELPP_TRACE CLOG(TRACE, ELPP_CURR_FILE_LOGGER_ID) +// Normal logs +#define LOG(LEVEL) CLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG(vlevel) CVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Conditional logs +#define LOG_IF(condition, LEVEL) CLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_IF(condition, vlevel) CVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Hit counts based logs +#define LOG_EVERY_N(n, LEVEL) CLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_EVERY_N(n, vlevel) CVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define LOG_AFTER_N(n, LEVEL) CLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_AFTER_N(n, vlevel) CVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define LOG_N_TIMES(n, LEVEL) CLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define VLOG_N_TIMES(n, vlevel) CVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Generic PLOG() +#undef CPLOG +#undef CPLOG_IF +#undef PLOG +#undef PLOG_IF +#undef DCPLOG +#undef DCPLOG_IF +#undef DPLOG +#undef DPLOG_IF +#define CPLOG(LEVEL, ...)\ +C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define CPLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::PErrorWriter, condition, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define DCPLOG(LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL(el::base::PErrorWriter, el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define DCPLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::PErrorWriter, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::NormalLog, __VA_ARGS__) +#define PLOG(LEVEL) CPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define PLOG_IF(condition, LEVEL) CPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DPLOG(LEVEL) DCPLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DPLOG_IF(condition, LEVEL) DCPLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +// Generic SYSLOG() +#undef CSYSLOG +#undef CSYSLOG_IF +#undef CSYSLOG_EVERY_N +#undef CSYSLOG_AFTER_N +#undef CSYSLOG_N_TIMES +#undef SYSLOG +#undef SYSLOG_IF +#undef SYSLOG_EVERY_N +#undef SYSLOG_AFTER_N +#undef SYSLOG_N_TIMES +#undef DCSYSLOG +#undef DCSYSLOG_IF +#undef DCSYSLOG_EVERY_N +#undef DCSYSLOG_AFTER_N +#undef DCSYSLOG_N_TIMES +#undef DSYSLOG +#undef DSYSLOG_IF +#undef DSYSLOG_EVERY_N +#undef DSYSLOG_AFTER_N +#undef DSYSLOG_N_TIMES +#if defined(ELPP_SYSLOG) +# define CSYSLOG(LEVEL, ...)\ +C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::Writer, condition, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_EVERY_N(n, LEVEL, ...) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_AFTER_N(n, LEVEL, ...) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define CSYSLOG_N_TIMES(n, LEVEL, ...) C##LEVEL##_N_TIMES(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define SYSLOG(LEVEL) CSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_IF(condition, LEVEL) CSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_EVERY_N(n, LEVEL) CSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_AFTER_N(n, LEVEL) CSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define SYSLOG_N_TIMES(n, LEVEL) CSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define DCSYSLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) C##LEVEL(el::base::Writer, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_IF(condition, LEVEL, ...)\ +C##LEVEL##_IF(el::base::Writer, (ELPP_DEBUG_LOG) && (condition), el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_EVERY_N(n, LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_AFTER_N(n, LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL##_AFTER_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DCSYSLOG_N_TIMES(n, LEVEL, ...)\ +if (ELPP_DEBUG_LOG) C##LEVEL##_EVERY_N(el::base::Writer, n, el::base::DispatchAction::SysLog, __VA_ARGS__) +# define DSYSLOG(LEVEL) DCSYSLOG(LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_IF(condition, LEVEL) DCSYSLOG_IF(condition, LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_EVERY_N(n, LEVEL) DCSYSLOG_EVERY_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_AFTER_N(n, LEVEL) DCSYSLOG_AFTER_N(n, LEVEL, el::base::consts::kSysLogLoggerId) +# define DSYSLOG_N_TIMES(n, LEVEL) DCSYSLOG_N_TIMES(n, LEVEL, el::base::consts::kSysLogLoggerId) +#else +# define CSYSLOG(LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() +# define CSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() +# define SYSLOG(LEVEL) el::base::NullWriter() +# define SYSLOG_IF(condition, LEVEL) el::base::NullWriter() +# define SYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() +# define SYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() +# define SYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() +# define DCSYSLOG(LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_IF(condition, LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_EVERY_N(n, LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_AFTER_N(n, LEVEL, ...) el::base::NullWriter() +# define DCSYSLOG_N_TIMES(n, LEVEL, ...) el::base::NullWriter() +# define DSYSLOG(LEVEL) el::base::NullWriter() +# define DSYSLOG_IF(condition, LEVEL) el::base::NullWriter() +# define DSYSLOG_EVERY_N(n, LEVEL) el::base::NullWriter() +# define DSYSLOG_AFTER_N(n, LEVEL) el::base::NullWriter() +# define DSYSLOG_N_TIMES(n, LEVEL) el::base::NullWriter() +#endif // defined(ELPP_SYSLOG) +// +// Custom Debug Only Loggers - Requires (level, loggerId/s) +// +// undef existing +#undef DCLOG +#undef DCVLOG +#undef DCLOG_IF +#undef DCVLOG_IF +#undef DCLOG_EVERY_N +#undef DCVLOG_EVERY_N +#undef DCLOG_AFTER_N +#undef DCVLOG_AFTER_N +#undef DCLOG_N_TIMES +#undef DCVLOG_N_TIMES +// Normal logs +#define DCLOG(LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG(LEVEL, __VA_ARGS__) +#define DCLOG_VERBOSE(vlevel, ...) if (ELPP_DEBUG_LOG) CLOG_VERBOSE(vlevel, __VA_ARGS__) +#define DCVLOG(vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG(vlevel, __VA_ARGS__) +// Conditional logs +#define DCLOG_IF(condition, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_IF(condition, LEVEL, __VA_ARGS__) +#define DCVLOG_IF(condition, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_IF(condition, vlevel, __VA_ARGS__) +// Hit counts based logs +#define DCLOG_EVERY_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_EVERY_N(n, LEVEL, __VA_ARGS__) +#define DCVLOG_EVERY_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_EVERY_N(n, vlevel, __VA_ARGS__) +#define DCLOG_AFTER_N(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_AFTER_N(n, LEVEL, __VA_ARGS__) +#define DCVLOG_AFTER_N(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_AFTER_N(n, vlevel, __VA_ARGS__) +#define DCLOG_N_TIMES(n, LEVEL, ...) if (ELPP_DEBUG_LOG) CLOG_N_TIMES(n, LEVEL, __VA_ARGS__) +#define DCVLOG_N_TIMES(n, vlevel, ...) if (ELPP_DEBUG_LOG) CVLOG_N_TIMES(n, vlevel, __VA_ARGS__) +// +// Default Debug Only Loggers macro using CLOG(), CLOG_VERBOSE() and CVLOG() macros +// +// undef existing +#undef DLOG +#undef DVLOG +#undef DLOG_IF +#undef DVLOG_IF +#undef DLOG_EVERY_N +#undef DVLOG_EVERY_N +#undef DLOG_AFTER_N +#undef DVLOG_AFTER_N +#undef DLOG_N_TIMES +#undef DVLOG_N_TIMES +// Normal logs +#define DLOG(LEVEL) DCLOG(LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG(vlevel) DCVLOG(vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Conditional logs +#define DLOG_IF(condition, LEVEL) DCLOG_IF(condition, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_IF(condition, vlevel) DCVLOG_IF(condition, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Hit counts based logs +#define DLOG_EVERY_N(n, LEVEL) DCLOG_EVERY_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_EVERY_N(n, vlevel) DCVLOG_EVERY_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define DLOG_AFTER_N(n, LEVEL) DCLOG_AFTER_N(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_AFTER_N(n, vlevel) DCVLOG_AFTER_N(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +#define DLOG_N_TIMES(n, LEVEL) DCLOG_N_TIMES(n, LEVEL, ELPP_CURR_FILE_LOGGER_ID) +#define DVLOG_N_TIMES(n, vlevel) DCVLOG_N_TIMES(n, vlevel, ELPP_CURR_FILE_LOGGER_ID) +// Check macros +#undef CCHECK +#undef CPCHECK +#undef CCHECK_EQ +#undef CCHECK_NE +#undef CCHECK_LT +#undef CCHECK_GT +#undef CCHECK_LE +#undef CCHECK_GE +#undef CCHECK_BOUNDS +#undef CCHECK_NOTNULL +#undef CCHECK_STRCASEEQ +#undef CCHECK_STRCASENE +#undef CHECK +#undef PCHECK +#undef CHECK_EQ +#undef CHECK_NE +#undef CHECK_LT +#undef CHECK_GT +#undef CHECK_LE +#undef CHECK_GE +#undef CHECK_BOUNDS +#undef CHECK_NOTNULL +#undef CHECK_STRCASEEQ +#undef CHECK_STRCASENE +#define CCHECK(condition, ...) CLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " +#define CPCHECK(condition, ...) CPLOG_IF(!(condition), FATAL, __VA_ARGS__) << "Check failed: [" << #condition << "] " +#define CHECK(condition) CCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#define PCHECK(condition) CPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#define CCHECK_EQ(a, b, ...) CCHECK(a == b, __VA_ARGS__) +#define CCHECK_NE(a, b, ...) CCHECK(a != b, __VA_ARGS__) +#define CCHECK_LT(a, b, ...) CCHECK(a < b, __VA_ARGS__) +#define CCHECK_GT(a, b, ...) CCHECK(a > b, __VA_ARGS__) +#define CCHECK_LE(a, b, ...) CCHECK(a <= b, __VA_ARGS__) +#define CCHECK_GE(a, b, ...) CCHECK(a >= b, __VA_ARGS__) +#define CCHECK_BOUNDS(val, min, max, ...) CCHECK(val >= min && val <= max, __VA_ARGS__) +#define CHECK_EQ(a, b) CCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_NE(a, b) CCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_LT(a, b) CCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_GT(a, b) CCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_LE(a, b) CCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_GE(a, b) CCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_BOUNDS(val, min, max) CCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) +#define CCHECK_NOTNULL(ptr, ...) CCHECK((ptr) != nullptr, __VA_ARGS__) +#define CCHECK_STREQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " == " << #str2 << "] " +#define CCHECK_STRNE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " != " << #str2 << "] " +#define CCHECK_STRCASEEQ(str1, str2, ...) CLOG_IF(!el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " == " << #str2 << "] " +#define CCHECK_STRCASENE(str1, str2, ...) CLOG_IF(el::base::utils::Str::cStringCaseEq(str1, str2), FATAL, __VA_ARGS__) \ +<< "Check failed: [" << #str1 << " != " << #str2 << "] " +#define CHECK_NOTNULL(ptr) CCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STREQ(str1, str2) CCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STRNE(str1, str2) CCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STRCASEEQ(str1, str2) CCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define CHECK_STRCASENE(str1, str2) CCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#undef DCCHECK +#undef DCCHECK_EQ +#undef DCCHECK_NE +#undef DCCHECK_LT +#undef DCCHECK_GT +#undef DCCHECK_LE +#undef DCCHECK_GE +#undef DCCHECK_BOUNDS +#undef DCCHECK_NOTNULL +#undef DCCHECK_STRCASEEQ +#undef DCCHECK_STRCASENE +#undef DCPCHECK +#undef DCHECK +#undef DCHECK_EQ +#undef DCHECK_NE +#undef DCHECK_LT +#undef DCHECK_GT +#undef DCHECK_LE +#undef DCHECK_GE +#undef DCHECK_BOUNDS_ +#undef DCHECK_NOTNULL +#undef DCHECK_STRCASEEQ +#undef DCHECK_STRCASENE +#undef DPCHECK +#define DCCHECK(condition, ...) if (ELPP_DEBUG_LOG) CCHECK(condition, __VA_ARGS__) +#define DCCHECK_EQ(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_EQ(a, b, __VA_ARGS__) +#define DCCHECK_NE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_NE(a, b, __VA_ARGS__) +#define DCCHECK_LT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LT(a, b, __VA_ARGS__) +#define DCCHECK_GT(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GT(a, b, __VA_ARGS__) +#define DCCHECK_LE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_LE(a, b, __VA_ARGS__) +#define DCCHECK_GE(a, b, ...) if (ELPP_DEBUG_LOG) CCHECK_GE(a, b, __VA_ARGS__) +#define DCCHECK_BOUNDS(val, min, max, ...) if (ELPP_DEBUG_LOG) CCHECK_BOUNDS(val, min, max, __VA_ARGS__) +#define DCCHECK_NOTNULL(ptr, ...) if (ELPP_DEBUG_LOG) CCHECK_NOTNULL((ptr), __VA_ARGS__) +#define DCCHECK_STREQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STREQ(str1, str2, __VA_ARGS__) +#define DCCHECK_STRNE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRNE(str1, str2, __VA_ARGS__) +#define DCCHECK_STRCASEEQ(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASEEQ(str1, str2, __VA_ARGS__) +#define DCCHECK_STRCASENE(str1, str2, ...) if (ELPP_DEBUG_LOG) CCHECK_STRCASENE(str1, str2, __VA_ARGS__) +#define DCPCHECK(condition, ...) if (ELPP_DEBUG_LOG) CPCHECK(condition, __VA_ARGS__) +#define DCHECK(condition) DCCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_EQ(a, b) DCCHECK_EQ(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_NE(a, b) DCCHECK_NE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_LT(a, b) DCCHECK_LT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_GT(a, b) DCCHECK_GT(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_LE(a, b) DCCHECK_LE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_GE(a, b) DCCHECK_GE(a, b, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_BOUNDS(val, min, max) DCCHECK_BOUNDS(val, min, max, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_NOTNULL(ptr) DCCHECK_NOTNULL((ptr), ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STREQ(str1, str2) DCCHECK_STREQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STRNE(str1, str2) DCCHECK_STRNE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STRCASEEQ(str1, str2) DCCHECK_STRCASEEQ(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DCHECK_STRCASENE(str1, str2) DCCHECK_STRCASENE(str1, str2, ELPP_CURR_FILE_LOGGER_ID) +#define DPCHECK(condition) DCPCHECK(condition, ELPP_CURR_FILE_LOGGER_ID) +#if defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) +# define ELPP_USE_DEF_CRASH_HANDLER false +#else +# define ELPP_USE_DEF_CRASH_HANDLER true +#endif // defined(ELPP_DISABLE_DEFAULT_CRASH_HANDLING) +#define ELPP_CRASH_HANDLER_INIT +#define ELPP_INIT_EASYLOGGINGPP(val) \ +ELPP_INITI_BASIC_DECLR \ +namespace el { \ +namespace base { \ +el::base::type::StoragePointer elStorage(val); \ +} \ +el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER); \ +} + +#if ELPP_ASYNC_LOGGING +# define INITIALIZE_EASYLOGGINGPP\ +ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()),\ +new el::base::AsyncDispatchWorker()))\ + +#else +# define INITIALIZE_EASYLOGGINGPP ELPP_INIT_EASYLOGGINGPP(new el::base::Storage(el::LogBuilderPtr(new el::base::DefaultLogBuilder()))) +#endif // ELPP_ASYNC_LOGGING +#define INITIALIZE_NULL_EASYLOGGINGPP\ +ELPP_INITI_BASIC_DECLR\ +namespace el {\ +namespace base {\ +el::base::type::StoragePointer elStorage;\ +}\ +el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ +} +// NOTE: no ELPP_INITI_BASIC_DECLR when sharing - causes double free corruption on external symbols +#define SHARE_EASYLOGGINGPP(initializedStorage)\ +namespace el {\ +namespace base {\ +el::base::type::StoragePointer elStorage(initializedStorage);\ +}\ +el::base::debug::CrashHandler elCrashHandler(ELPP_USE_DEF_CRASH_HANDLER);\ +} + +#if defined(ELPP_UNICODE) +# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv); std::locale::global(std::locale("")) +#else +# define START_EASYLOGGINGPP(argc, argv) el::Helpers::setArgs(argc, argv) +#endif // defined(ELPP_UNICODE) +#endif // EASYLOGGINGPP_H diff --git a/src/energy.cpp b/src/energy.cpp deleted file mode 100644 index 8b5039e9..00000000 --- a/src/energy.cpp +++ /dev/null @@ -1,665 +0,0 @@ -#include "energy.h" - -#include "./data/stacking_energies.dat" -#include "./data/stacking_enthalpies.dat" -#include "./data/interior_loop_1_1_energies.dat" -#include "./data/interior_loop_1_1_enthalpies.dat" -#include "./data/interior_loop_1_2_energies.dat" -#include "./data/interior_loop_1_2_enthalpies.dat" -#include "./data/interior_loop_2_2_energies.dat" -#include "./data/interior_loop_2_2_enthalpies.dat" -#include "./data/loop_destabilizing_energies.dat" -#include "./data/single_base_stacking_energies.dat" -#include "./data/single_base_stacking_enthalpies.dat" -#include "./data/terminal_mismatch_hairpin.dat" -#include "./data/terminal_mismatch_interior.dat" -#include "./data/terminal_mismatch_enthalpies.dat" - -void pup_factor_correct(double *pup,int length,int unpaired_length); //adapted of a Vienna function - - -/********************************************************************************** -* scales all free energy parameter for a temperature different from 37°C * -**********************************************************************************/ - -void scale_parameters() -{ - double scaling_factor = (temperature+K_0)/T_MEASURE; // temperature scaling factor - - // scale free energy parameter - for(size_t i = 0; i 0) { - single_base_stacking_energy[i] = 0; - } - } - for(size_t i = 0; i2000) fprintf(stderr, "scaling factor %f\n", pf_scale); - - init_pf_fold(len); - strncpy(pf_structure, c_structure, len+1); - double energy = pf_fold(sequence, pf_structure); - // printf(" free energy of ensemble = %6.2f kcal/mol\n", energy); - // printf(" frequency of mfe structure in ensemble %g; \n\n", exp((energy-min_en)/kT)); - free_pf_arrays(); - - return(energy); -} - - -/****************************************************************************** -* calculates ED = E_unpaired(start_unpaired,end_unfold) - E_all) * -******************************************************************************/ - -double calc_ED (char* sequence, int start_unpaired, int end_unpaired) -{ - double E_all = calc_ensemble_free_energy(sequence, -1, -1); - double E_unpaired = calc_ensemble_free_energy(sequence, start_unpaired, end_unpaired); - return E_unpaired-E_all; -} - -/****************************************************************************** -* calculates ED values for all intervals in targetRNA * -******************************************************************************/ - -void calc_ED_target_matrix() -{ - double E_all = calc_ensemble_free_energy(sequence_target, -1, -1); - - //cout << "no window, no RNAplfold" << endl; - string prefix =" ED(targetRNA) computation: " ; - int count=0; - - for(int i=0;i<(int)strlen(sequence_target);i++) - { - //for(int j=i;j<(int)strlen(sequence_target);j++) - //Mininum is needed, if no -w option is given but a -l option - for(int j=i; j < Minimum((int)strlen(sequence_target),i+max_unpaired_length); j++) - { - ED_target[i][j]= calc_ensemble_free_energy(sequence_target,i,j)-E_all; - - // Ouput progress only if no sequence file given - if( target_file==false && miRNA_file==false) - { - count++; - //number of calculated values out of all values (times 200 since: *100 to change to percent and *2 since actually the denominator has to be divided by 2) - //the denominator represents the number of values in a large upper triangle matrix minus the number in a smaller upper triangle matrix - cout << prefix << count*200/(((int)strlen(sequence_target) * ((int)strlen(sequence_target) + 1))- (((int)strlen(sequence_target)-max_unpaired_length)*((int)strlen(sequence_target)-max_unpaired_length+1))) << "%\r" ; - cout.flush(); - } - } - } - - if( target_file==false && miRNA_file==false) - { - cout << endl; - } -} - -/****************************************************************************** -* calculates ED values for all intervals in miRNA * -******************************************************************************/ - -void calc_ED_miRNA_matrix() -{ - //change direction of the second sequence again for a correct calculation of - //the ED-values - change_direction(sequence_miRNA); - double E_all = calc_ensemble_free_energy(sequence_miRNA , -1, -1); - - int miRNA_len = (int)strlen(sequence_miRNA); - string prefix =" ED( ncRNA) computation: " ; - int count=0; - for(int i=0; iH[i+1][u-1]+pu_struct->I[i+1][u-1]+pu_struct->M[i+1][u-1]+pu_struct->E[i+1][u-1]; - - // since we need the ED-values of the original sequence, but we use the inverse - // one, we have to convert this - if (pu == 0.0) // is not exact since we have double values, but pu can get really small - ED_miRNA[miRNA_len-1-(i+u-1)][miRNA_len-1-i] = - (fabs(ED_miRNA_scaling - 0.0) < DOUBLE_DIFF) ? 0 : MAX_DOUBLE; - else - ED_miRNA[miRNA_len-1-(i+u-1)][miRNA_len-1-i] = -RT * ED_miRNA_scaling * log(pu); - - } - } - -// for(int i=0; i " << pup[i+u][u] << endl; -// cout << " " << " --> " << ED_target[i][i+u-1] << endl; - } - else { - ED_target[i][i+u-1] = -RT * ED_target_scaling * log(pup[i+u][u]); -// cout << "i,j: " << i <<"," << i+u-1 << " --> " << pup[i+u][u] << endl; -// cout << " " << " --> " << ED_target[i][i+u-1] << endl; - } - } - } - - for (size_t i=0;i<=mRNA_len;i++) { - free(pup[i]); - } - free(pup); -} - - -/****************************************************************************** -* calculates ED values for all intervals <= max_unpaired_length of targetRNA * -* using the old RNAplfold of Vienna Package 1.7.x * -******************************************************************************/ - -//void calc_ED_target_matrix_old_plfold(char* sequence) -//{ -// int len = (int)strlen(sequence); -//// double kT = (temperature+273.15)*1.98717/1000.0; /* in Kcal */ -// -// float cutoff=0.01; -// char* structure=NULL; -// double *pup=NULL; /*prob of being unpaired*/ -// plist *pl; -// -// //cout << "RNAplfold used" << endl; -// -// for(int u=1;u<=max_unpaired_length;u++) -// { -// pf_scale = -1; -// -// pup=(double *)space((len+1)*sizeof(double)); -// pup[0]=(double)u; -// -// structure = (char *) space((unsigned) len+1); -// update_fold_params(); -// -// //printf("sequence: %s\n", sequence); -// //printf("window_size: %d\n", window_size); -// //printf("pairdist: %d\n", pairdist); -// //printf("cutoff: %f\n", cutoff); -// //cout << "pup: " << u << endl; -// //cout << endl; -// -// pl=pfl_fold(sequence, window_size, max_pair_dist, cutoff, pup); -// free(pl); -// -// pup_factor_correct(pup,len,u); -// -// //cout << endl << "u: " << u << endl; -// for (int i=0; i " << pup[i+u] << endl; -// //cout << " " << " --> " << ED_target[i][i+u-1] << endl; -// -// } -// //cout << endl; -// free(structure); -// free(pup); -// } - -//} - - -/********************************************************************* -* help function to scale pu_values calulated by the Vienna Package * -* (this function is a modified version of a Vienna function) * -*********************************************************************/ - -void pup_factor_correct(double *pup,int length,int unpaired_length) { - - float factor = 0; - float tfact; - bool left; //help variable to remind whether we are in left-case - fflush(NULL); - - for (int i=unpaired_length; i<=length; i++) { - - left = false; - //left - if (i<=window_size) { - factor=1./(i - unpaired_length + 1); - left = true; - } - //right - //if (i>length - window_size + unpaired_length - 1) { - if (i>length - window_size + unpaired_length) { - - //if left == true, we are in left and right case at the same time and thus there exists no standard case - //furthermore, tfact = 1/#of intervals of length winsize in length - if (left == true) - tfact = 1./(length - window_size + 1); - else - tfact=1./(length-i+1); - - if (tfact > factor) { - factor = tfact; - } - - } - //standard case - else { - tfact=1./(window_size - unpaired_length + 1); - if (tfact > factor) { - factor = tfact; - } - } - - pup[i] *= factor; - //printf("%d %.6g\n",i,pup[i]*factor); - } - - -} - - -/****************************************************************************** -* calculates PUvalue = exp(-(1/(kT))ED(start_unpaired,end_unfold)) -******************************************************************************/ - -double calc_PU (double ED) -{ -// double kT = (temperature+273.15)*1.98717/1000.0; /* in Kcal */ - double PU = exp(-ED/RT); - return PU; -} - -double AU_penalty(char C1,char C2) -{ - if ((C1=='A' && C2=='U') || - (C1=='U' && C2=='A') || - (C1=='G' && C2=='U') || - (C1=='U' && C2=='G')) - return terminal_AU; - return 0.0; -} - -// /***************************************** -// * 5' j 3' 5' di 3' -// * 3' id 5' 3' j 5' -// *****************************************/ -// double ed5(char i, char j, char d) -// { -// double energy=0; -// if (i=='U' && j=='A') -// { -// if (d=='A') energy=-0.3; -// else if (d=='C') energy=-0.1; -// else if (d=='G') energy=-0.2; -// else /*(d=='U')*/ energy=-0.2; -// } -// else if (i=='G' && j=='C') -// { -// if (d=='A') energy=-0.2; -// else if (d=='C') energy=-0.3; -// else if (d=='G') energy=-0.0; -// else /*(d=='U')*/ energy=-0.0; -// } -// else if (i=='C' && j=='G') -// { -// if (d=='A') energy=-0.5; -// else if (d=='C') energy=-0.3; -// else if (d=='G') energy=-0.2; -// else /*(d=='U')*/ energy=-0.1; -// } -// else if (i=='U' && j=='G') -// { -// if (d=='A') energy=-0.3; -// else if (d=='C') energy=-0.1; -// else if (d=='G') energy=-0.2; -// else /*(d=='U')*/ energy=-0.2; -// } -// else if ( (i=='A' || i=='G') && j=='U') -// { -// if (d=='A') energy=-0.3; -// else if (d=='C') energy=-0.3; -// else if (d=='G') energy=-0.4; -// else /*(d=='U')*/ energy=-0.2; -// } -// return energy; -// } -// -// /***************************************** -// * 5' jd 3' 5' i 3' -// * 3' i 5' 3' dj 5' -// *****************************************/ -// double ed3(char i, char j, char d) -// { -// double energy=0; -// if (i=='U' && j=='A') -// { -// if (d=='A') energy=-0.8; -// else if (d=='C') energy=-0.5; -// else if (d=='G') energy=-0.8; -// else /*(d=='U')*/ energy=-0.6; -// } -// else if (i=='G' && j=='C') -// { -// if (d=='A') energy=-1.7; -// else if (d=='C') energy=-0.8; -// else if (d=='G') energy=-1.7; -// else /*(d=='U')*/ energy=-1.2; -// } -// else if (i=='C' && j=='G') -// { -// if (d=='A') energy=-1.1; -// else if (d=='C') energy=-0.4; -// else if (d=='G') energy=-1.3; -// else /*(d=='U')*/ energy=-0.6; -// } -// else if (i=='U' && j=='G') -// { -// if (d=='A') energy=-0.8; -// else if (d=='C') energy=-0.5; -// else if (d=='G') energy=-0.8; -// else /*(d=='U')*/ energy=-0.6; -// } -// else if ( (i=='A' || i=='G') && j=='U') -// { -// if (d=='A') energy=-0.7; -// else if (d=='C') energy=-0.1; -// else if (d=='G') energy=-0.7; -// else /*(d=='U')*/ energy=-0.1; -// } -// return energy; -// } - - diff --git a/src/energy.h b/src/energy.h deleted file mode 100644 index 9911c0ab..00000000 --- a/src/energy.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _ENERGY__ -#define _ENERGY__ - -#include -#include -#include "basics.h" - -using namespace std; - -void scale_parameters(); -void scaling_function(double scaling_factor, double& energy, double enthalpy); -double calc_ensemble_free_energy(char* sequence, int start_unfold, int end_unfold); -double calc_ED (char* sequence, int start_unpaired, int end_unpaired); -double calc_PU (double ED); -void calc_ED_target_matrix(); -void calc_ED_miRNA_matrix(); -void calc_ED_miRNA_matrix_up(); -void calc_ED_target_matrix_window(); -void calc_ED_target_matrix_plfold(char* sequence); -//void calc_ED_target_matrix_old_plfold(char* sequence); -double AU_penalty(char,char); -// double ed5(char, char, char); -// double ed3(char, char, char); - -//bool StackEnd(int bp_pos); -//double Zero_or_StemEndAU(int bp_pos, int bp_assign); - -#endif // _ENERGY_ diff --git a/src/general.h b/src/general.h new file mode 100644 index 00000000..d2a49aed --- /dev/null +++ b/src/general.h @@ -0,0 +1,102 @@ + +#ifndef GENERAL_H_ +#define GENERAL_H_ + + +////////////// GENERAL CONFIGURE FLAGS //////////////// + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include "intarna_config.h" + +//! central compiler flag whether or not debug mode is enabled +#define IN_DEBUG_MODE ((defined(_DEBUG)) || (!defined (NDEBUG))) + +//////////////// CENTRAL LOGGING LIB ////////////////// + +// disable default log file creation +#ifndef ELPP_NO_DEFAULT_LOG_FILE + #define ELPP_NO_DEFAULT_LOG_FILE 1 +#endif +// disable log file argument (and parsing) +#ifndef ELPP_DISABLE_LOG_FILE_FROM_ARG + #define ELPP_DISABLE_LOG_FILE_FROM_ARG 1 +#endif +// enable debug error tracking +#if IN_DEBUG_MODE + #define ELPP_DEBUG_ERRORS 1 +#endif + +#include "easylogging++.h" + +//////////////// GARBAGE COLLECTION /////////////////// + +#define CLEANUP(pointer) if (pointer != NULL) {delete pointer; pointer=NULL;} + +//////////////// ABORT NON-IMPLEMENTED //////////////// + +#include + + #define NOTIMPLEMENTED(message) \ + throw std::runtime_error( \ + std::string("\nSTOP DUE TO MISSING IMPLEMENTATION : ") \ + + message \ + ); + +//////////////// ABORT ON NULL POINTER //////////////// + +#include + + #define CHECKNOTNULL(pointer,message) if (pointer == NULL) { \ + throw std::runtime_error( \ + std::string("\nSTOP DUE TO NULL POINTER : ") \ + + message \ + ); } + + +//////////////// STRING GENERATION //////////////////// + +#include + + #define toString( x ) boost::lexical_cast(x) + + +//////////////// NUMBER STRING LENGTH //////////////////// + +#include + + #define numStringLength( x ) ( (x==0) ? 1 : (1+std::floor(std::log10(x))) ) + + +//////////////// GLOBAL TYPEDEFS ////////////////////// + +#include + + //! type for energy values (energy + accessibility [ED]) + typedef float E_type; + + //! type for temperature values + typedef E_type T_type; + + //! the delta difference range to consider two energies equivalent +#define E_precisionEpsilon 1000.0*std::numeric_limits::epsilon() + + //! check if two energies are equal according to some epsilon +#define E_equal( e1, e2 ) ( std::abs((e1)-(e2)) < E_precisionEpsilon) + + //! check if a given energy is NOT set to E_INF +#define E_isNotINF( e ) ( std::numeric_limits::max() >= e ) + + //! check if a given energy is set to E_INF +#define E_isINF( e ) ( std::numeric_limits::max() < e ) + + +//////////////// GLOBAL CONSTANTS ///////////////////// + +#include + + const E_type E_INF = std::numeric_limits::infinity(); + +#endif /* GENERAL_H_ */ diff --git a/src/hybrid.cpp b/src/hybrid.cpp deleted file mode 100644 index 8413735b..00000000 --- a/src/hybrid.cpp +++ /dev/null @@ -1,1852 +0,0 @@ -#include "hybrid.h" - -/********************************************************************************** -* allocates space for global matrices except ED_target and ED_miRNA * -**********************************************************************************/ - -void allocate_global_matrices() -{ - // space allocation - C = (double**) space(sizeof(double*)*strlen(sequence_target)); - Cseed = (double**) space(sizeof(double*)*strlen(sequence_target)); - U = (double**) space(sizeof(double*)*strlen(sequence_target)); - che1 = (int**) space(sizeof(int*) *strlen(sequence_target)); - che2 = (int**) space(sizeof(int*) *strlen(sequence_target)); - ches1 = (int**) space(sizeof(int*) *strlen(sequence_target)); - ches2 = (int**) space(sizeof(int*) *strlen(sequence_target)); - seed = (double**) space(sizeof(double*)*strlen(sequence_target)); - seed_unpaired_target = (int**) space(sizeof(int*) *strlen(sequence_target)); - seed_unpaired_miRNA = (int**) space(sizeof(int*) *strlen(sequence_target)); - hybrid_matrix = (double*****) space(sizeof(double****)*strlen(sequence_target)); - - for(int i=0;i<(int)strlen(sequence_target);i++) - { - C [i] = (double*) space(sizeof(double)*strlen(sequence_miRNA)); - Cseed[i] = (double*) space(sizeof(double)*strlen(sequence_miRNA)); - U [i] = (double*) space(sizeof(double)*strlen(sequence_miRNA)); - che1 [i] = (int*) space(sizeof(int) *strlen(sequence_miRNA)); - che2 [i] = (int*) space(sizeof(int) *strlen(sequence_miRNA)); - ches1[i] = (int*) space(sizeof(int) *strlen(sequence_miRNA)); - ches2[i] = (int*) space(sizeof(int) *strlen(sequence_miRNA)); - seed [i] = (double*) space(sizeof(double)*strlen(sequence_miRNA)); - seed_unpaired_target[i] = (int*) space(sizeof(int)*strlen(sequence_miRNA)); - seed_unpaired_miRNA [i] = (int*) space(sizeof(int)*strlen(sequence_miRNA)); - hybrid_matrix[i] = (double****) space(sizeof(double***)*strlen(sequence_miRNA)); - for (int j=0; j<(int)strlen(sequence_miRNA); j++) - { - hybrid_matrix[i][j] = (double***) space(sizeof(double**)*(num_bp_seed+1)); - for (int k=0; k<=num_bp_seed; k++) - { - hybrid_matrix[i][j][k] = (double**) space(sizeof(double*)*(max_unpaired_target+1)); - for (int l=0; l<=max_unpaired_target; l++) - hybrid_matrix[i][j][k][l] = (double*) space(sizeof(double)*(max_unpaired_miRNA+1)); - } - } - } -} - -/********************************************************************************** -* allocates space for ED_target matrix * -**********************************************************************************/ - -void allocate_ED_target_matrix() -{ - // space allocation - ED_target = (double**) space(sizeof(double*)*strlen(sequence_target)); - - for(int i=0;i<(int)strlen(sequence_target);i++) - { - ED_target[i] = (double*) space(sizeof(double)*strlen(sequence_target)); - } -} - -/********************************************************************************** -* allocates space for ED_miRNA matrix * -**********************************************************************************/ - -void allocate_ED_miRNA_matrix() -{ - // space allocation - ED_miRNA = (double**) space(sizeof(double*)*strlen(sequence_miRNA )); - - for(int i=0;i<(int)strlen(sequence_miRNA);i++) - { - ED_miRNA[i] =(double*) space(sizeof(double)*strlen(sequence_miRNA)); - } -} - -/********************************************************************************** -* initializing global matrices except ED_target and ED_miRNA * -**********************************************************************************/ - -void init_global_matrices() -{ - // init - for(int i=0;i<(int)strlen(sequence_target);i++) - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - { - C[i][j] = Cseed[i][j] = U[i][j] = seed[i][j] = MAX_DOUBLE; - che1[i][j] = che2[i][j] = ches1[i][j] = ches2[i][j] = -1; - seed_unpaired_target[i][j] = seed_unpaired_miRNA[i][j] = -1; - for (int k=0; k<=num_bp_seed; k++) - for (int l=0; l<=max_unpaired_target; l++) - for (int m=0; m<=max_unpaired_miRNA; m++) - hybrid_matrix[i][j][k][l][m] = MAX_DOUBLE; - } -} - -/********************************************************************************** -* initializing ED_target matrix * -**********************************************************************************/ - -void init_ED_target_matrix() -{ - // init - for(int i=0;i<(int)strlen(sequence_target);i++) - for(int j=0;j<(int)strlen(sequence_target);j++) - ED_target[i][j] = MAX_DOUBLE; -} - -/********************************************************************************** -* initializing ED_miRNA matrix * -**********************************************************************************/ - -void init_ED_miRNA_matrix() -{ - // init - for(int i=0;i<(int)strlen(sequence_miRNA);i++) - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - ED_miRNA[i][j] = MAX_DOUBLE; -} - -/********************************************************************************** -* frees space for global matrices except ED_target and ED_miRNA * -**********************************************************************************/ - -void free_global_matrices() -{ - for(int i=0;i<(int)strlen(sequence_target);i++) - { - free(C[i]); - free(Cseed[i]); - free(U[i]); - free(che1[i]); - free(che2[i]); - free(ches1[i]); - free(ches2[i]); - free(seed[i]); - free(seed_unpaired_target[i]); - free(seed_unpaired_miRNA[i]); - - for (int j=0; j<(int)strlen(sequence_miRNA); j++) - { - for (int k=0; k<=num_bp_seed; k++) - { - for (int l=0; l<=max_unpaired_target; l++) - free(hybrid_matrix[i][j][k][l]); - free(hybrid_matrix[i][j][k]); - } - free(hybrid_matrix[i][j]); - } - free(hybrid_matrix[i]); - } - - free(C); - free(Cseed); - free(U); - free(che1); - free(che2); - free(ches1); - free(ches2); - free(seed); - free(seed_unpaired_target); - free(seed_unpaired_miRNA); - free(hybrid_matrix); -} - -/********************************************************************************** -* frees space for ED_target matrix * -**********************************************************************************/ - -void free_ED_target_matrix() -{ - for(int i=0;i<(int)strlen(sequence_target);i++) - { - free(ED_target[i]); - } - - free(ED_target); -} - -/********************************************************************************** -* frees space for ED_miRNA matrix * -**********************************************************************************/ - -void free_ED_miRNA_matrix() -{ - - for(int i=0;i<(int)strlen(sequence_miRNA);i++) - { - free(ED_miRNA[i]); - } - - free(ED_miRNA); -} - -/********************************************************************************** -* calculates one value of the hybrid_matrix * -**********************************************************************************/ - -double calc_hybrid_value(int left_end_target, int left_end_miRNA, int num_bp, int unpaired_target, int unpaired_miRNA) -{ - double stacking, min_bulge_target, min_bulge_miRNA, min_interior_loop, bulge_target, bulge_miRNA, interior_loop; - double min_energy = MAX_DOUBLE; - -/*printf("left_end_target: %d\n", left_end_target); -printf("left_end_miRNA: %d\n", left_end_miRNA); -printf("num_bp: %d\n", num_bp); -printf("unpaired_target: %d\n", unpaired_target); -printf("unpaired_miRNA: %d\n", unpaired_miRNA);*/ - - //test, whether both enclosing pairs can pair and enough bases are left on both sequences - if ((left_end_target+num_bp+unpaired_target-1 >=(int)strlen(sequence_target)) || - (left_end_miRNA+num_bp+unpaired_miRNA-1 >= (int)strlen(sequence_miRNA)) || - (PairTest(sequence_target[left_end_target],sequence_miRNA[left_end_miRNA]) == false) || - (PairTest(sequence_target[left_end_target+num_bp+unpaired_target-1],sequence_miRNA[left_end_miRNA+num_bp+unpaired_miRNA-1]) == false)) - { - return MAX_DOUBLE; - } - else - { //basic case - if (num_bp == 2) - { - if ((unpaired_target == 0) && (unpaired_miRNA == 0)) /*stacking*/ - return StackingEnergy(int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1], int_sequence_miRNA[left_end_miRNA+1]); - - else if ((unpaired_target > 0) && (unpaired_target <= MAX_BULGE_SIZE) && (unpaired_miRNA == 0)) /*target_bulge, has to be at most MAX_BULGE_SIZE*/ - return BulgeEnergy(unpaired_target, int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1+unpaired_target], int_sequence_miRNA[left_end_miRNA+1]); - - else if ((unpaired_target == 0) && (unpaired_miRNA <= MAX_BULGE_SIZE) && (unpaired_miRNA > 0)) /*miRNA_bulge, has to be at most MAX_BULGE_SIZE*/ - return BulgeEnergy(unpaired_miRNA, int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1], int_sequence_miRNA[left_end_miRNA+1+unpaired_miRNA]); - - else if ((unpaired_target > 0) && (unpaired_target <= MAX_INTERIOR_ONE_SIDE_SIZE) && (unpaired_miRNA > 0) && (unpaired_miRNA <= MAX_INTERIOR_ONE_SIDE_SIZE)) /*interior loop, both sides have to be at most MAX_INTERIOR_ONE_SIDE_SIZE*/ - return InteriorLoopEnergy(unpaired_target, unpaired_miRNA, int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1+unpaired_target], int_sequence_miRNA[left_end_miRNA+1+unpaired_miRNA], int_sequence_target[left_end_target+1], int_sequence_miRNA[left_end_miRNA+1], int_sequence_target[left_end_target+unpaired_target], int_sequence_miRNA[left_end_miRNA+unpaired_miRNA]); - else - return MAX_DOUBLE; - - } - else if (num_bp > 2) //recursion - { - /*stacking*/ - stacking = Sum_or_MAX_DOUBLE(StackingEnergy(int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1], int_sequence_miRNA[left_end_miRNA+1]), hybrid_matrix[left_end_target+1][left_end_miRNA+1][num_bp-1][unpaired_target][unpaired_miRNA]); - - /* bulge in the target mRNA */ - min_bulge_target = MAX_DOUBLE; - for (int p=1; p<=Minimum(unpaired_target,MAX_BULGE_SIZE); p++) - { - bulge_target = Sum_or_MAX_DOUBLE(BulgeEnergy(p, int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1+p], int_sequence_miRNA[left_end_miRNA+1]), hybrid_matrix[left_end_target+1+p][left_end_miRNA+1][num_bp-1][unpaired_target-p][unpaired_miRNA]); - - if (bulge_target < min_bulge_target) - min_bulge_target = bulge_target; - } - - /* bulge in the miRNA */ - min_bulge_miRNA = MAX_DOUBLE; - for (int q=1; q<=Minimum(unpaired_miRNA,MAX_BULGE_SIZE); q++) - { - bulge_miRNA = Sum_or_MAX_DOUBLE(BulgeEnergy(q, int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1], int_sequence_miRNA[left_end_miRNA+1+q]), hybrid_matrix[left_end_target+1][left_end_miRNA+1+q][num_bp-1][unpaired_target][unpaired_miRNA-q]); - - if (bulge_miRNA < min_bulge_miRNA) - min_bulge_miRNA = bulge_miRNA; - } - - /* interior loop */ - min_interior_loop = MAX_DOUBLE; - for (int p=1; p<=Minimum(unpaired_target,MAX_INTERIOR_ONE_SIDE_SIZE); p++) - { - for (int q=1; q<=Minimum(unpaired_miRNA,MAX_INTERIOR_ONE_SIDE_SIZE); q++) - { - interior_loop = Sum_or_MAX_DOUBLE(InteriorLoopEnergy(p, q, int_sequence_target[left_end_target], int_sequence_miRNA[left_end_miRNA], int_sequence_target[left_end_target+1+p], int_sequence_miRNA[left_end_miRNA+1+q], int_sequence_target[left_end_target+1], int_sequence_miRNA[left_end_miRNA+1], int_sequence_target[left_end_target+p], int_sequence_miRNA[left_end_miRNA+q]), hybrid_matrix[left_end_target+1+p][left_end_miRNA+1+q][num_bp-1][unpaired_target-p][unpaired_miRNA-q]); - - if (interior_loop < min_interior_loop) - min_interior_loop = interior_loop; - } - } - - /* find the minimum of the 4 cases */ - min_energy = Minimum(min_energy, stacking); - min_energy = Minimum(min_energy, min_bulge_target); - min_energy = Minimum(min_energy, min_bulge_miRNA); - min_energy = Minimum(min_energy, min_interior_loop); - - return min_energy; - } - else - { - cerr << "Forgotten hybrid cases!\n"; - return MAX_DOUBLE; - } - } - return MAX_DOUBLE; -} - - - -/******************************************************************************** -* findes the best seed starting at base pair (i,j), having 'num_bp_seed' base * -* pairs, having at most 'max_unpaired_target' unbound bases in the target, at * -* most 'max_unpaired_miRNA' unbound bases in the miRNA, and at most * -* 'max_unpaired' unbound bases at all * -* * -* the number of unbound bases in both sequences (which give the best seed) are * -* stored in seed_unpaired_target(i,j) and seed_unpaired_miRNA(i,j) * -********************************************************************************/ - -double compute_seed_ij(int i, int j) -{ - //test, whether it is a valid seed, i.e. j is within ncRNA seed region if applicable, x_i and y_j can pair and - //'num_bp_seed' base pairs starting at (i,j) are possible (depending on the lengths of the sequences) - if ( (seed_region_ncRNA && (jseed_region_end_ncRNA_3)) || - (PairTest(sequence_target[i],sequence_miRNA[j]) == false) || - (i+num_bp_seed-1 >= (int)strlen(sequence_target)) || (j+num_bp_seed-1 >= (int)strlen(sequence_miRNA)) ) - { - return MAX_DOUBLE; - } - else - { - - double min_energy = MAX_DOUBLE; - int min_target_unpaired, min_miRNA_unpaired; // numbers of unpaired bases when reaching the min_energy - int i_star, j_star; //helper variables - double hyb, energy; //energy helper during the recursion - - min_target_unpaired = min_miRNA_unpaired = -1; - i_star = i+num_bp_seed-1; - j_star = j+num_bp_seed-1; - for (int unpaired_target = 0; unpaired_target <= max_unpaired_target; unpaired_target++) - for (int unpaired_miRNA = 0; unpaired_miRNA <= max_unpaired_miRNA; unpaired_miRNA++) - { - if ((unpaired_target + unpaired_miRNA <= max_unpaired) && - (seed_region_ncRNA?(unpaired_miRNA <= seed_region_end_ncRNA_3-j_star):true)) - { - - hyb = hybrid_matrix[i][j][num_bp_seed][unpaired_target][unpaired_miRNA]; - - // if first valid seed found, compute ED_target matrix, ED_miRNA matrix and C matrix if not done yet - if (hyb < MAX_DOUBLE && (ED_miRNA_computed == false || ED_target_computed == false) ) { - if (ED_miRNA_computed == false) { - // calculate ED matrix for miRNA - if (use_RNAup) { - calc_ED_miRNA_matrix_up(); - } - else { - calc_ED_miRNA_matrix(); - } - ED_miRNA_computed = true; - } - - if (ED_target_computed == false) { - // calculate ED matrix for target - if (use_RNAplfold) - calc_ED_target_matrix_plfold(sequence_target); - else - { - if (window) - calc_ED_target_matrix_window(); - else - calc_ED_target_matrix(); - } - ED_target_computed = true; - } - - for(int i=(int)strlen(sequence_target)-1;i>=0;i--) - for(int j=(int)strlen(sequence_miRNA)-1;j>=0;j--) - C[i][j]=Cij(i,j); - } - - if ((hyb < MAX_DOUBLE) && (C[i_star+unpaired_target][j_star+unpaired_miRNA] < MAX_DOUBLE) && - (ED_target[i][che1[i_star+unpaired_target][j_star+unpaired_miRNA]]= pu_comb_threshold) - { - energy = hyb + C[i_star+unpaired_target][j_star+unpaired_miRNA] - - ED_target[i_star+unpaired_target][che1[i_star+unpaired_target][j_star+unpaired_miRNA]] - - ED_miRNA[j_star+unpaired_miRNA][che2[i_star+unpaired_target][j_star+unpaired_miRNA]] + - ED_target[i][che1[i_star+unpaired_target][j_star+unpaired_miRNA]] + - ED_miRNA[j][che2[i_star+unpaired_target][j_star+unpaired_miRNA]]; - - if (energy < min_energy) - { - min_energy = energy; - min_target_unpaired = unpaired_target; - min_miRNA_unpaired = unpaired_miRNA; - } - } - } - } - - seed_unpaired_target[i][j] = min_target_unpaired; - seed_unpaired_miRNA[i][j] = min_miRNA_unpaired; - - return min_energy; - } -} - - - - - -/**************************************************************************** -* calculates the values of C[i][j] * -****************************************************************************/ - -double Cij(int i,int j) -{ - /* test, whether bases can pair and are not the last bases in the sequences */ - if ( !PairTest(sequence_target[i],sequence_miRNA[j]) ) - return MAX_DOUBLE; - else{ - double v1,v2,v3,v4,v5,v6,v7,v8; - v1=v2=v3=v4=v5=v6=v7=v8=MAX_DOUBLE; - - /* stacking */ - v1=( (i+1>=(int)strlen(sequence_target) || j+1>=(int)strlen(sequence_miRNA) || C[i+1][j+1]==MAX_DOUBLE || ED_target[i][che1[i+1][j+1]]==MAX_DOUBLE || ED_miRNA[j][che2[i+1][j+1]]==MAX_DOUBLE)?MAX_DOUBLE: - StackingEnergy(int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1], int_sequence_miRNA[j+1])+ - C[i+1][j+1]+ - ED_target[i][che1[i+1][j+1]]-ED_target[i+1][che1[i+1][j+1]]+ - ED_miRNA [j][che2[i+1][j+1]]-ED_miRNA [j+1][che2[i+1][j+1]]); - - /* bulge in the mRNA (target) */ - double min = MAX_DOUBLE; - int best_bulge_k = 1; - for(int k=1;k<=Minimum(MAX_BULGE_SIZE,(int)strlen(sequence_target)-i-2);k++) - { - min=( (i+1+k>=(int)strlen(sequence_target) || j+1>=(int)strlen(sequence_miRNA) || C[i+1+k][j+1]==MAX_DOUBLE || ED_target[i][che1[i+1+k][j+1]]==MAX_DOUBLE || ED_miRNA[j][che2[i+1+k][j+1]]==MAX_DOUBLE)?MAX_DOUBLE: - BulgeEnergy(k,int_sequence_target[i],int_sequence_miRNA[j],int_sequence_target[i+1+k],int_sequence_miRNA[j+1])+ - C[i+1+k][j+1]+ - ED_target[i][che1[i+1+k][j+1]]-ED_target[i+1+k][che1[i+1+k][j+1]]+ - ED_miRNA [j][che2[i+1+k][j+1]]-ED_miRNA [j+1 ][che2[i+1+k][j+1]]); - if (min=(int)strlen(sequence_target) || j+1+l>=(int)strlen(sequence_miRNA) || C[i+1][j+1+l]==MAX_DOUBLE || ED_target[i][che1[i+1][j+1+l]]==MAX_DOUBLE || ED_miRNA[j][che2[i+1][j+1+l]]==MAX_DOUBLE)?MAX_DOUBLE: - BulgeEnergy(l,int_sequence_target[i],int_sequence_miRNA[j],int_sequence_target[i+1],int_sequence_miRNA[j+1+l])+ - C[i+1][j+1+l]+ - ED_target[i][che1[i+1][j+1+l]]-ED_target[i+1 ][che1[i+1][j+1+l]]+ - ED_miRNA [j][che2[i+1][j+1+l]]-ED_miRNA [j+1+l ][che2[i+1][j+1+l]]); - if (min=(int)strlen(sequence_target) || j+1+l>=(int)strlen(sequence_miRNA) || C[i+1+k][j+1+l]==MAX_DOUBLE || ED_target[i][che1[i+1+k][j+1+l]]==MAX_DOUBLE || ED_miRNA[j][che2[i+1+k][j+1+l]]==MAX_DOUBLE)?MAX_DOUBLE: - InteriorLoopEnergy(k,l, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1+k], int_sequence_miRNA[j+1+l], int_sequence_target[i+1], int_sequence_miRNA[j+1], int_sequence_target[i+k], int_sequence_miRNA[j+l])+ - C[i+1+k][j+1+l]+ - ED_target[i][che1[i+1+k][j+1+l]]-ED_target[i+1+k ][che1[i+1+k][j+1+l]]+ - ED_miRNA [j][che2[i+1+k][j+1+l]]-ED_miRNA [j+1+l ][che2[i+1+k][j+1+l]]); - if (min=(int)strlen(sequence_target) || j+1>=(int)strlen(sequence_miRNA) -// || ED_target[i][i+1]==MAX_DOUBLE || ED_miRNA[j][j+1]==MAX_DOUBLE)?MAX_DOUBLE: -// ed5(sequence_miRNA[j],sequence_target[i],sequence_miRNA[j+1])+ -// ed3(sequence_miRNA[j],sequence_target[i],sequence_target[i+1])+ -// ED_miRNA[j][j+1]+ED_target[i][i+1]+AU_penalty(sequence_miRNA[j],sequence_target[i])); -// v6 = ( (i+1>=(int)strlen(sequence_target) || ED_target[i][i+1]==MAX_DOUBLE || ED_miRNA[j][j]==MAX_DOUBLE)?MAX_DOUBLE: -// ed3(sequence_miRNA[j],sequence_target[i],sequence_target[i+1])+ -// ED_miRNA[j][j]+ED_target[i][i+1]+AU_penalty(sequence_miRNA[j],sequence_target[i])); -// v7 = ( (j+1>=(int)strlen(sequence_miRNA) || ED_target[i][i]==MAX_DOUBLE || ED_miRNA[j][j+1]==MAX_DOUBLE)?MAX_DOUBLE: -// ed5(sequence_miRNA[j],sequence_target[i],sequence_miRNA[j+1])+ -// ED_miRNA[j][j+1]+ED_target[i][i]+AU_penalty(sequence_miRNA[j],sequence_target[i])); -// v8 = ( (ED_target[i][i] == MAX_DOUBLE || ED_miRNA[j][j] == MAX_DOUBLE)?MAX_DOUBLE: -// (AU_penalty(sequence_miRNA[j],sequence_target[i])+ED_target[i][i]+ED_miRNA[j][j])); - - v5 = ( (i+1>=(int)strlen(sequence_target) || j+1>=(int)strlen(sequence_miRNA) - || ED_target[i][i+1]==MAX_DOUBLE || ED_miRNA[j][j+1]==MAX_DOUBLE)?MAX_DOUBLE: - ed5(int_sequence_miRNA[j],int_sequence_target[i],int_sequence_miRNA[j+1])+ - ed3(int_sequence_miRNA[j],int_sequence_target[i],int_sequence_target[i+1])+ - ED_miRNA[j][j+1]+ED_target[i][i+1]+AU_penalty(sequence_miRNA[j],sequence_target[i])+duplex_init); - v6 = ( (i+1>=(int)strlen(sequence_target) || ED_target[i][i+1]==MAX_DOUBLE || ED_miRNA[j][j]==MAX_DOUBLE)?MAX_DOUBLE: - ed3(int_sequence_miRNA[j],int_sequence_target[i],int_sequence_target[i+1])+ - ED_miRNA[j][j]+ED_target[i][i+1]+AU_penalty(sequence_miRNA[j],sequence_target[i])+duplex_init); - v7 = ( (j+1>=(int)strlen(sequence_miRNA) || ED_target[i][i]==MAX_DOUBLE || ED_miRNA[j][j+1]==MAX_DOUBLE)?MAX_DOUBLE: - ed5(int_sequence_miRNA[j],int_sequence_target[i],int_sequence_miRNA[j+1])+ - ED_miRNA[j][j+1]+ED_target[i][i]+AU_penalty(sequence_miRNA[j],sequence_target[i])+duplex_init); - v8 = ( (ED_target[i][i] == MAX_DOUBLE || ED_miRNA[j][j] == MAX_DOUBLE)?MAX_DOUBLE: - (AU_penalty(sequence_miRNA[j],sequence_target[i])+ED_target[i][i]+ED_miRNA[j][j])+duplex_init); - - // che values - if (heuristic) { - if (v1<=v2 && v1<=v3 && v1<=v4 && v1<=v5 && v1<=v6 && v1<=v7 && v1<=v8 && v1=(int)strlen(sequence_target) || j+1>=(int)strlen(sequence_miRNA) || Cseed[i+1][j+1]==MAX_DOUBLE || ED_target[i][ches1[i+1][j+1]]==MAX_DOUBLE || ED_miRNA[j][ches2[i+1][j+1]]==MAX_DOUBLE)?MAX_DOUBLE: - StackingEnergy(int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1], int_sequence_miRNA[j+1])+ - Cseed[i+1][j+1]+ - ED_target[i][ches1[i+1][j+1]]-ED_target[i+1][ches1[i+1][j+1]]+ - ED_miRNA [j][ches2[i+1][j+1]]-ED_miRNA [j+1][ches2[i+1][j+1]]); - - /* bulge in the mRNA (target) */ - double min = MAX_DOUBLE; - int best_bulge_k = 1; - for(int k=1;k<=Minimum(MAX_BULGE_SIZE,(int)strlen(sequence_target)-i-2);k++) - { - min=( (i+1+k>=(int)strlen(sequence_target) || j+1>=(int)strlen(sequence_miRNA) || Cseed[i+1+k][j+1]==MAX_DOUBLE || ED_target[i][ches1[i+1+k][j+1]]==MAX_DOUBLE || ED_miRNA[j][ches2[i+1+k][j+1]]==MAX_DOUBLE)?MAX_DOUBLE: - BulgeEnergy(k,int_sequence_target[i],int_sequence_miRNA[j],int_sequence_target[i+1+k],int_sequence_miRNA[j+1])+ - Cseed[i+1+k][j+1]+ - ED_target[i][ches1[i+1+k][j+1]]-ED_target[i+1+k][ches1[i+1+k][j+1]]+ - ED_miRNA [j][ches2[i+1+k][j+1]]-ED_miRNA [j+1 ][ches2[i+1+k][j+1]]); - if (min=(int)strlen(sequence_target) || j+1+l>=(int)strlen(sequence_miRNA) || Cseed[i+1][j+1+l]==MAX_DOUBLE || ED_target[i][ches1[i+1][j+1+l]]==MAX_DOUBLE || ED_miRNA[j][ches2[i+1][j+1+l]]==MAX_DOUBLE)?MAX_DOUBLE: - BulgeEnergy(l,int_sequence_target[i],int_sequence_miRNA[j],int_sequence_target[i+1],int_sequence_miRNA[j+1+l])+ - Cseed[i+1][j+1+l]+ - ED_target[i][ches1[i+1][j+1+l]]-ED_target[i+1 ][ches1[i+1][j+1+l]]+ - ED_miRNA [j][ches2[i+1][j+1+l]]-ED_miRNA [j+1+l ][ches2[i+1][j+1+l]]); - if (min=(int)strlen(sequence_target) || j+1+l>=(int)strlen(sequence_miRNA) || Cseed[i+1+k][j+1+l]==MAX_DOUBLE || ED_target[i][ches1[i+1+k][j+1+l]]==MAX_DOUBLE || ED_miRNA[j][ches2[i+1+k][j+1+l]]==MAX_DOUBLE)?MAX_DOUBLE: - InteriorLoopEnergy(k,l, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1+k], int_sequence_miRNA[j+1+l], int_sequence_target[i+1], int_sequence_miRNA[j+1], int_sequence_target[i+k], int_sequence_miRNA[j+l])+ - Cseed[i+1+k][j+1+l]+ - ED_target[i][ches1[i+1+k][j+1+l]]-ED_target[i+1+k ][ches1[i+1+k][j+1+l]]+ - ED_miRNA [j][ches2[i+1+k][j+1+l]]-ED_miRNA [j+1+l ][ches2[i+1+k][j+1+l]]); - if (min=0;i--) -// for(int j=(int)strlen(sequence_miRNA)-1;j>=0;j--) -// C[i][j]=Cij(i,j); - - for (int i=(int)strlen(sequence_target)-1;i>=0;i--) - for(int j=(int)strlen(sequence_miRNA)-1;j>=0;j--) - for (int l=2; l<=num_bp_seed; l++) - for (int b_target=0; b_target<=max_unpaired_target; b_target++) - for (int b_miRNA=0; b_miRNA<=max_unpaired_miRNA; b_miRNA++) - hybrid_matrix[i][j][l][b_target][b_miRNA] = calc_hybrid_value(i,j,l,b_target,b_miRNA); - - for(int i=(int)strlen(sequence_target)-1;i>=0;i--) - for(int j=(int)strlen(sequence_miRNA)-1;j>=0;j--) - { - seed [i][j] = compute_seed_ij(i,j); - //is now computed only when valid seed has been found -// Cseed[i][j] = Cij_seed(i,j); -// U [i][j] = U_ij(i,j); - } - - //is now computed only when valid seed has been found - if (ED_target_computed && ED_miRNA_computed) { - for(int i=(int)strlen(sequence_target)-1;i>=0;i--) - for(int j=(int)strlen(sequence_miRNA)-1;j>=0;j--) - { - Cseed[i][j] = Cij_seed(i,j); - U [i][j] = U_ij(i,j); - } - } - - for (int i=1; i<(int)strlen(sequence_target);i++) - { - v = ( Cseed[i][0]==MAX_DOUBLE ? MAX_DOUBLE : Minimum(Cseed[i][0]+AU_penalty(sequence_target[i],sequence_miRNA[0]), - Cseed[i][0]+ed5(int_sequence_target[i],int_sequence_miRNA[0],int_sequence_target[i-1])+AU_penalty(sequence_target[i],sequence_miRNA[0]) - +ED_target[i-1][ches1[i][0]]-ED_target[i][ches1[i][0]] ) ); - if (v < min1) - { - min1 = v; - } - } - - for (int j=1; j<(int)strlen(sequence_miRNA);j++) - { - v = ( Cseed[0][j]==MAX_DOUBLE ? MAX_DOUBLE : Minimum(Cseed[0][j]+AU_penalty(sequence_target[0],sequence_miRNA[j]), - Cseed[0][j]+ed3(int_sequence_target[0],int_sequence_miRNA[j],int_sequence_miRNA[j-1])+AU_penalty(sequence_target[0],sequence_miRNA[j]) - +ED_miRNA[j-1][ches2[0][j]]-ED_miRNA[j][ches2[0][j]] ) ); - if (v < min2) - { - min2 = v; - } - } - - hybrid_energy= Minimum(0.0, - Minimum(Cseed[0][0]==MAX_DOUBLE?MAX_DOUBLE:Cseed[0][0]+AU_penalty(sequence_target[0],sequence_miRNA[0]), - Minimum(min1, - Minimum(min2, U[0][0])))); - } - - else { - double hybrid_energy_pq = MAX_DOUBLE; - - // calculate ED matrix for miRNA - if (use_RNAup) - calc_ED_miRNA_matrix_up(); - else - calc_ED_miRNA_matrix(); - ED_miRNA_computed = true; - - // calculate ED matrix for target - if (use_RNAplfold) - calc_ED_target_matrix_plfold(sequence_target); - else { - if (window) - calc_ED_target_matrix_window(); - else - calc_ED_target_matrix(); - } - ED_target_computed = true; - - // compute recurrences without heuristic for each possible hybridization end p,q - for(int p=(int)strlen(sequence_target)-1;p>=0;p--) - for(int q=(int)strlen(sequence_miRNA)-1;q>=0;q--) { - // set che values to p,q - init_global_matrices(); - for(int i=0;i<=p;i++) - for(int j=0;j<=q;j++) { - che1[i][j] = p; - che2[i][j] = q; - } - - // compute matrices for all indices <= p,q - for(int i=p;i>=0;i--) - for(int j=q;j>=0;j--) - C[i][j]=Cij(i,j); - - for (int i=p;i>=0;i--) - for(int j=q;j>=0;j--) - for (int l=2; l<=num_bp_seed; l++) - for (int b_target=0; b_target<=max_unpaired_target; b_target++) - for (int b_miRNA=0; b_miRNA<=max_unpaired_miRNA; b_miRNA++) - hybrid_matrix[i][j][l][b_target][b_miRNA] = calc_hybrid_value(i,j,l,b_target,b_miRNA); - - for(int i=p;i>=0;i--) { - for(int j=q;j>=0;j--) { - seed [i][j] = compute_seed_ij(i,j); - Cseed[i][j] = Cij_seed(i,j); - U [i][j] = U_ij(i,j); - } - } - - for (int i=1; i<(int)strlen(sequence_target);i++) { - v = ( Cseed[i][0]==MAX_DOUBLE ? MAX_DOUBLE : Minimum(Cseed[i][0]+AU_penalty(sequence_target[i],sequence_miRNA[0]), - Cseed[i][0]+ed5(int_sequence_target[i],int_sequence_miRNA[0],int_sequence_target[i-1])+AU_penalty(sequence_target[i],sequence_miRNA[0]) - +ED_target[i-1][ches1[i][0]]-ED_target[i][ches1[i][0]] ) ); - if (v < min1) { - min1 = v; - } - } - for (int j=1; j<(int)strlen(sequence_miRNA);j++) { - v = ( Cseed[0][j]==MAX_DOUBLE ? MAX_DOUBLE : Minimum(Cseed[0][j]+AU_penalty(sequence_target[0],sequence_miRNA[j]), - Cseed[0][j]+ed3(int_sequence_target[0],int_sequence_miRNA[j],int_sequence_miRNA[j-1])+AU_penalty(sequence_target[0],sequence_miRNA[j]) - +ED_miRNA[j-1][ches2[0][j]]-ED_miRNA[j][ches2[0][j]] ) ); - if (v < min2) { - min2 = v; - } - } - - hybrid_energy_pq = Minimum(0.0, - Minimum(Cseed[0][0]==MAX_DOUBLE?MAX_DOUBLE:Cseed[0][0]+AU_penalty(sequence_target[0],sequence_miRNA[0]), - Minimum(min1, - Minimum(min2, U[0][0])))); - - if (hybrid_energy_pq < hybrid_energy) { - best_che1 = p; - best_che2 = q; - hybrid_energy = hybrid_energy_pq; - } - } - } - - /* - cout << "res 1 : " << 0 << endl; - cout << "res 2 : " << (Cseed[0][0]==MAX_DOUBLE?MAX_DOUBLE:Cseed[0][0]+AU_penalty(sequence_target[0],sequence_miRNA[0])) << endl; - cout << "res 3 : " << (Cseed[1][0]==MAX_DOUBLE?MAX_DOUBLE:Cseed[1][0]+ed5(sequence_target[1],sequence_miRNA[0],sequence_target[0])+AU_penalty(sequence_target[1],sequence_miRNA[0])) << endl; - cout << "res 4 : " << (Cseed[0][1]==MAX_DOUBLE?MAX_DOUBLE:Cseed[0][1]+ed3(sequence_target[0],sequence_miRNA[1],sequence_miRNA[0])+AU_penalty(sequence_target[0],sequence_miRNA[1])) << endl; - cout << "res 5 : " << U[0][0] << endl; - */ - - return hybrid_energy; -} - -/**************************************************************************** -* finds best hybridization at positions not constrained by * -* hybrid_pos_target * -* calculates traceback of suboptimal hybridization * -* returns whether such a suboptimal hybridization was found and the energy * -* of that hybridization (if applicable) * -****************************************************************************/ - -pair find_next_subopt() { - bool hybridization_found = false; - double hybrid_energy = MAX_DOUBLE; - // hybridization energy of 0.0 means no significant hybridization - double min_hybrid_energy = 0.0; - int hybrid_start_target, hybrid_start_miRNA; - hybrid_start_target = hybrid_start_miRNA = -1; - - // test position (0,0) for being a hybridization not considered yet - if (ches1[0][0] != -1 && hybrid_pos_target.substr(0,ches1[0][0]+1).find('1',0) == string::npos && - (Cseed[0][0]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[0][0]+AU_penalty(sequence_target[0],sequence_miRNA[0]))) < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = 0; - hybrid_start_miRNA = 0; - pos_target_1_dangle=hybrid_start_target; - pos_miRNA_1_dangle =hybrid_start_miRNA; - } - - // test position (i,0) for being a hybridization not considered yet - for(int i=1; i<(int)strlen(sequence_target);i++) { - if (ches1[i][0] != -1 && hybrid_pos_target.substr(i,ches1[i][0]-i+1).find('1',0) == string::npos && - (Cseed[i][0]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[i][0]+AU_penalty(sequence_target[i],sequence_miRNA[0]))) < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = i; - hybrid_start_miRNA = 0; - pos_target_1_dangle=hybrid_start_target; - pos_miRNA_1_dangle =hybrid_start_miRNA; - } - if (ches1[i][0] != -1 && hybrid_pos_target.substr(i,ches1[i][0]-i+1).find('1',0) == string::npos && - (Cseed[i][0]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[i][0]+ed5(int_sequence_target[i],int_sequence_miRNA[0],int_sequence_target[i-1]) - +AU_penalty(sequence_target[i],sequence_miRNA[0])+ED_target[i-1][ches1[i][0]]-ED_target[i][ches1[i][0]])) - < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = i; - hybrid_start_miRNA = 0; - pos_target_1_dangle=hybrid_start_target-1; - pos_miRNA_1_dangle =hybrid_start_miRNA; - } - } - - // test position (0,j) for being a hybridization not considered yet - for(int j=1; j<(int)strlen(sequence_miRNA);j++) { - if (ches1[0][j] != -1 && hybrid_pos_target.substr(0,ches1[0][j]+1).find('1',0) == string::npos && - (Cseed[0][j]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[0][j]+AU_penalty(sequence_target[0],sequence_miRNA[j]))) < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = 0; - hybrid_start_miRNA = j; - pos_target_1_dangle=hybrid_start_target; - pos_miRNA_1_dangle =hybrid_start_miRNA; - } - if (ches1[0][j] != -1 && hybrid_pos_target.substr(0,ches1[0][j]+1).find('1',0) == string::npos && - (Cseed[0][j]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[0][j]+ed3(int_sequence_target[0],int_sequence_miRNA[j],int_sequence_miRNA[j-1]) - +AU_penalty(sequence_target[0],sequence_miRNA[j])+ED_miRNA[j-1][ches2[0][j]]-ED_miRNA[j][ches2[0][j]])) - < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = 0; - hybrid_start_miRNA = j; - pos_target_1_dangle=hybrid_start_target; - pos_miRNA_1_dangle =hybrid_start_miRNA-1; - } - } - - // test positions (i,j) for being a hybridization not considered yet - for(int i=0; i<(int)strlen(sequence_target)-1;i++) { - for(int j=0; j<(int)strlen(sequence_miRNA)-1;j++) { - if (ches1[i+1][j+1] != -1 && hybrid_pos_target.substr(i+1,ches1[i+1][j+1]-i).find('1',0) == string::npos && - (Cseed[i+1][j+1]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[i+1][j+1]+ed5(int_sequence_target[i+1],int_sequence_miRNA[j+1],int_sequence_target[i]) - +ed3(int_sequence_target[i+1],int_sequence_miRNA[j+1],int_sequence_miRNA[j])+AU_penalty(sequence_target[i+1],sequence_miRNA[j+1]) - +ED_target[i][ches1[i+1][j+1]]+ED_miRNA[j][ches2[i+1][j+1]]-ED_target[i+1][ches1[i+1][j+1]]-ED_miRNA[j+1][ches2[i+1][j+1]])) - < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = i+1; - hybrid_start_miRNA = j+1; - pos_target_1_dangle = i; - pos_miRNA_1_dangle =j; - } - if (ches1[i+1][j+1] != -1 && hybrid_pos_target.substr(i+1,ches1[i+1][j+1]-i).find('1',0) == string::npos && - (Cseed[i+1][j+1]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[i+1][j+1]+ed5(int_sequence_target[i+1],int_sequence_miRNA[j+1],int_sequence_target[i]) - +AU_penalty(sequence_target[i+1],sequence_miRNA[j+1])+ED_target[i][ches1[i+1][j+1]]-ED_target[i+1][ches1[i+1][j+1]])) - < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = i+1; - hybrid_start_miRNA = j+1; - pos_target_1_dangle = i; - pos_miRNA_1_dangle =j+1; - } - if (ches1[i+1][j+1] != -1 && hybrid_pos_target.substr(i+1,ches1[i+1][j+1]-i).find('1',0) == string::npos && - (Cseed[i+1][j+1]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[i+1][j+1]+ed3(int_sequence_target[i+1],int_sequence_miRNA[j+1],int_sequence_miRNA[j]) - +AU_penalty(sequence_target[i+1],sequence_miRNA[j+1]) +ED_miRNA[j][ches2[i+1][j+1]]-ED_miRNA[j+1][ches2[i+1][j+1]])) - < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = i+1; - hybrid_start_miRNA = j+1; - pos_target_1_dangle = i+1; - pos_miRNA_1_dangle =j; - } - if (ches1[i+1][j+1] != -1 && hybrid_pos_target.substr(i+1,ches1[i+1][j+1]-i).find('1',0) == string::npos && - (Cseed[i+1][j+1]==MAX_DOUBLE ? MAX_DOUBLE : - (hybrid_energy=Cseed[i+1][j+1]+AU_penalty(sequence_target[i+1],sequence_miRNA[j+1]))) - < min_hybrid_energy) - { - min_hybrid_energy = hybrid_energy; - hybridization_found = true; - hybrid_start_target = i+1; - hybrid_start_miRNA = j+1; - pos_target_1_dangle = i+1; - pos_miRNA_1_dangle =j+1; - } - } - } - - - // mark positions of hybridization with '1' as hybridized in hybrid_pos_target - // perform traceback - if (hybridization_found) - { - traceback_print_labels_blanks(hybrid_start_target,hybrid_start_miRNA); - pos_target_1=hybrid_start_target; - pos_miRNA_1 =hybrid_start_miRNA; - hybrid_pos_target.replace(pos_target_1_dangle, ches1[pos_target_1][pos_miRNA_1]-pos_target_1_dangle+1, - ches1[pos_target_1][pos_miRNA_1]-pos_target_1_dangle+1, '1'); - traceback_left(hybrid_start_target,hybrid_start_miRNA); - } - - return pair(hybridization_found,min_hybrid_energy); -} - -/**************************************************************************** -* traceback in C starting in (i,j) (sequence characters for i and j are * -* already written to hybrid_sequence_target and hybrid_sequence_miRNA in * -* traceback_seed(int, int, int)) * -****************************************************************************/ - -void traceback_right(int i, int j) -{ - // cout << "traceback right (" << i << "," << j << ")" << endl; - - if ( i==(int)strlen(sequence_target) || j==(int)strlen(sequence_miRNA) || C[i][j]==MAX_DOUBLE ) - { - cerr << "traceback_right error" << endl; - cerr << "i=" << i << ",j=" << j << ",C=" << C[i][j] << endl; - exit(1); - } - // last base-pair (i,j) - else if ( i<(int)strlen(sequence_target)-1 && j<(int)strlen(sequence_miRNA)-1 && fabs(C[i][j] - - (ed5(int_sequence_miRNA[j],int_sequence_target[i],int_sequence_miRNA[j+1])+ - ed3(int_sequence_miRNA[j],int_sequence_target[i],int_sequence_target[i+1])+ - ED_miRNA[j][j+1]+ED_target[i][i+1]+AU_penalty(sequence_miRNA[j],sequence_target[i])+ - +duplex_init) ) =(int)strlen(sequence_target)-1 || j>=(int)strlen(sequence_miRNA)-1 ) - { - cerr << "i(=" << i << ") or j(=" << j << ") out of range" << endl; - exit(1); - } - - if (fabs(U[i][j]-U[i+1][j]) 0) && (unpaired_target <= MAX_BULGE_SIZE) && (unpaired_miRNA == 0) && (fabs(energy-BulgeEnergy(unpaired_target, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1+unpaired_target], int_sequence_miRNA[j+1])) < DOUBLE_DIFF)) - { - /* - x_{i+1} x_{i+2} ..... x_{i+unpaired_target} - - x_i - - ..... - x_{i+unpaired_target+1} - y_j - - ..... - y_{j+1} - - - - ..... - - */ - - for (int h=1; h<=unpaired_target; h++) - { - bulges_sequence_target += sequence_target[i+h]; - hybrid_sequence_target += " "; - hybrid_sequence_miRNA += " "; - bulges_sequence_miRNA += " "; - } - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+unpaired_target+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+1]; - bulges_sequence_miRNA += " "; - } - - /*miRNA_bulge*/ - else if ((unpaired_target == 0) && (unpaired_miRNA <= MAX_BULGE_SIZE) && (unpaired_miRNA > 0) && (fabs(energy-BulgeEnergy(unpaired_miRNA, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1], int_sequence_miRNA[j+1+unpaired_miRNA])) < DOUBLE_DIFF)) - { - /* - - - ..... - - - x_i - - ..... - x_{i+1} - y_j - - ..... - y_{j+unpaired_miRNA+1} - - y_{j+1} y_{j+2} ..... y_{j+unpaired_miRNA} - */ - - for (int h=1; h<=unpaired_miRNA; h++) - { - bulges_sequence_target += " "; - hybrid_sequence_target += " "; - hybrid_sequence_miRNA += " "; - bulges_sequence_miRNA += sequence_miRNA[j+h]; - } - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+unpaired_miRNA+1]; - bulges_sequence_miRNA += " "; - } - - /* interior loop */ - else if ((unpaired_target > 0) && (unpaired_target <= MAX_INTERIOR_ONE_SIDE_SIZE) && (unpaired_miRNA > 0) && (unpaired_miRNA <= MAX_INTERIOR_ONE_SIDE_SIZE) && (fabs(energy-InteriorLoopEnergy(unpaired_target, unpaired_miRNA, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1+unpaired_target], int_sequence_miRNA[j+1+unpaired_miRNA], int_sequence_target[i+1], int_sequence_miRNA[j+1], int_sequence_target[i+unpaired_target], int_sequence_miRNA[j+unpaired_miRNA])) < DOUBLE_DIFF)) - { - /* - x_{i+1} x_{i+2} .......................... x_{i+unpaired_target} - - x_i - - .......................... - x_{i+unpaired_target+1} - y_j - - .......................... - y_{j+unpaired_miRNA+1} - - y_{j+1} y_{j+2} ... y_{j+unpaired_miRNA} - - */ - - int bulge_max = Maximum(unpaired_target,unpaired_miRNA); - for (int h=1; h<=bulge_max; h++) - { - hybrid_sequence_target += " "; - hybrid_sequence_miRNA += " "; - - /* two cases since the interior loop might be asymmetric*/ - if (unpaired_target < h) - bulges_sequence_target += " "; - else - bulges_sequence_target += sequence_target[i+h]; - - if (unpaired_miRNA < h) - bulges_sequence_miRNA += " "; - else - bulges_sequence_miRNA += sequence_miRNA[j+h]; - } - - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+unpaired_target+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+unpaired_miRNA+1]; - bulges_sequence_miRNA += " "; - - } - - else - { - cerr << "Error in the base case traceback of hybrid!" << endl; - } - - } - else if (num_bp > 2) - { - /*stacking*/ - stacking = Sum_or_MAX_DOUBLE(StackingEnergy(int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1], int_sequence_miRNA[j+1]), hybrid_matrix[i+1][j+1][num_bp-1][unpaired_target][unpaired_miRNA]); - - if (fabs(energy - stacking) < DOUBLE_DIFF) - { - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+1]; - bulges_sequence_miRNA += " "; - traceback_hybrid(i+1, j+1, num_bp-1, unpaired_target, unpaired_miRNA); - return; - } - - - /* bulge in the target mRNA */ - for (int p=1; p<=Minimum(unpaired_target,MAX_BULGE_SIZE); p++) - { - bulge_target = Sum_or_MAX_DOUBLE(BulgeEnergy(p, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1+p], int_sequence_miRNA[j+1]), hybrid_matrix[i+1+p][j+1][num_bp-1][unpaired_target-p][unpaired_miRNA]); - - if (fabs(energy - bulge_target) < DOUBLE_DIFF) - { - /* - x_{i+1} x_{i+2} ..... x_{i+unpaired_target} - - x_i - - ..... - x_{i+unpaired_target+1} - y_j - - ..... - y_{j+1} - - - - ..... - - */ - - for (int h=1; h<=p; h++) - { - bulges_sequence_target += sequence_target[i+h]; - hybrid_sequence_target += " "; - hybrid_sequence_miRNA += " "; - bulges_sequence_miRNA += " "; - } - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+p+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+1]; - bulges_sequence_miRNA += " "; - - traceback_hybrid(i+p+1,j+1,num_bp-1,unpaired_target-p, unpaired_miRNA); - return; - } - - } - - /* bulge in the miRNA */ - for (int q=1; q<=Minimum(unpaired_miRNA,MAX_BULGE_SIZE); q++) - { - bulge_miRNA = Sum_or_MAX_DOUBLE(BulgeEnergy(q, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1], int_sequence_miRNA[j+1+q]), hybrid_matrix[i+1][j+1+q][num_bp-1][unpaired_target][unpaired_miRNA-q]); - - if (fabs(energy - bulge_miRNA) < DOUBLE_DIFF) - { - /* - - - ..... - - - x_i - - ..... - x_{i+1} - y_j - - ..... - y_{j+unpaired_miRNA+1} - - y_{j+1} y_{j+2} ..... y_{j+unpaired_miRNA} - */ - - for (int h=1; h<=q; h++) - { - bulges_sequence_target += " "; - hybrid_sequence_target += " "; - hybrid_sequence_miRNA += " "; - bulges_sequence_miRNA += sequence_miRNA[j+h]; - } - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+q+1]; - bulges_sequence_miRNA += " "; - - traceback_hybrid(i+1,j+q+1,num_bp-1,unpaired_target, unpaired_miRNA-q); - return; - } - } - - /* interior loop */ - for (int p=1; p<=Minimum(unpaired_target,MAX_INTERIOR_ONE_SIDE_SIZE); p++) - { - for (int q=1; q<=Minimum(unpaired_miRNA,MAX_INTERIOR_ONE_SIDE_SIZE); q++) - { - interior_loop = Sum_or_MAX_DOUBLE(InteriorLoopEnergy(p, q, int_sequence_target[i], int_sequence_miRNA[j], int_sequence_target[i+1+p], int_sequence_miRNA[j+1+q], int_sequence_target[i+1], int_sequence_miRNA[j+1], int_sequence_target[i+p], int_sequence_miRNA[j+q]), hybrid_matrix[i+1+p][j+1+q][num_bp-1][unpaired_target-p][unpaired_miRNA-q]); - - if (fabs(energy - interior_loop) < DOUBLE_DIFF) - { - /* - x_{i+1} x_{i+2} .......................... x_{i+unpaired_target} - - x_i - - .......................... - x_{i+unpaired_target+1} - y_j - - .......................... - y_{j+unpaired_miRNA+1} - - y_{j+1} y_{j+2} ... y_{j+unpaired_miRNA} - - */ - - for (int h=1; h<=Maximum(p,q); h++) - { - hybrid_sequence_target += " "; - hybrid_sequence_miRNA += " "; - - /* two cases since the interior loop might be asymmetric*/ - if (p < h) - bulges_sequence_target += " "; - else - bulges_sequence_target += sequence_target[i+h]; - - if (q < h) - bulges_sequence_miRNA += " "; - else - bulges_sequence_miRNA += sequence_miRNA[j+h]; - } - - bulges_sequence_target += " "; - hybrid_sequence_target += sequence_target[i+p+1]; - hybrid_sequence_miRNA += sequence_miRNA[j+q+1]; - bulges_sequence_miRNA += " "; - - traceback_hybrid(i+p+1,j+q+1, num_bp-1, unpaired_target-p, unpaired_miRNA-q); - return; - } - } - } - - } - else - cerr << "Error in hybrid traceback!" << endl; -} - - - -/**************************************************************************** -* traceback in seed starting in (i,j) (sequence characters for i and j are * -* already written to hybrid_sequence_target and hybrid_sequence_miRNA in * -* traceback(int)) * -****************************************************************************/ - -void traceback_seed(int i, int j) -{ - if (seed[i][j] == MAX_DOUBLE) - { - cerr << "No seed found!\n"; - } - else - { - //traceback of hybrid - traceback_hybrid( i, j, num_bp_seed, seed_unpaired_target[i][j], seed_unpaired_miRNA[i][j]); - //traceback of C - - /* the following has to be done, since the traceback of hybrid has already analyzed bases - x_{i+num_bp_seed-1+seed_unpaired_target[i][j]} and y_{j+num_bp_seed-1+seed_unpaired_miRNA[i][j]} - but traceback_right also does it. therefore, we have to remove the last bases here.*/ - bulges_sequence_target = bulges_sequence_target.substr(0,bulges_sequence_target.length()-1); - hybrid_sequence_target = hybrid_sequence_target.substr(0,hybrid_sequence_target.length()-1); - hybrid_sequence_miRNA = hybrid_sequence_miRNA .substr(0,hybrid_sequence_miRNA .length()-1); - bulges_sequence_miRNA = bulges_sequence_miRNA .substr(0,bulges_sequence_miRNA .length()-1); - - pos_target_3=i+num_bp_seed-1+seed_unpaired_target[i][j]; - pos_miRNA_3 =j+num_bp_seed-1+seed_unpaired_miRNA[i][j] ; - - traceback_right( i+num_bp_seed-1+seed_unpaired_target[i][j], j+num_bp_seed-1+seed_unpaired_miRNA[i][j]); - } - - return; -} - -/**************************************************************************** -* traceback in Cseed (matrix) starting in (0,0) * -****************************************************************************/ - -bool traceback(double energy) -{ - // recompute matrices for best che value before traceback - if (!heuristic) { - init_global_matrices(); - - for(int i=0;i<=best_che1;i++) - for(int j=0;j<=best_che2;j++) { - che1[i][j] = best_che1; - che2[i][j] = best_che2; - } - - // compute matrices for all indices <= best_che1,best_che2 - for(int i=best_che1;i>=0;i--) - for(int j=best_che2;j>=0;j--) - C[i][j]=Cij(i,j); - - for (int i=best_che1;i>=0;i--) - for(int j=best_che2;j>=0;j--) - for (int l=2; l<=num_bp_seed; l++) - for (int b_target=0; b_target<=max_unpaired_target; b_target++) - for (int b_miRNA=0; b_miRNA<=max_unpaired_miRNA; b_miRNA++) - hybrid_matrix[i][j][l][b_target][b_miRNA] = calc_hybrid_value(i,j,l,b_target,b_miRNA); - - for(int i=best_che1;i>=0;i--) - for(int j=best_che2;j>=0;j--) { - seed [i][j] = compute_seed_ij(i,j); - Cseed[i][j] = Cij_seed(i,j); - U [i][j] = U_ij(i,j); - } - } - - - if (fabs(energy-0.0) -#include "basics.h" - -using namespace std; - -void allocate_global_matrices(); -void allocate_ED_target_matrix(); -void allocate_ED_miRNA_matrix(); -void init_global_matrices(); -void init_ED_target_matrix(); -void init_ED_miRNA_matrix(); -void free_ED_target_matrix(); -void free_ED_miRNA_matrix(); -void free_global_matrices(); - -double calc_hybrid_value(int left_end_target, int left_end_miRNA, int num_bp, int unpaired_target, int unpaired_miRNA); -double compute_seed_ij(int i, int j); -double Cij (int,int); -double Cij_seed(int,int); -double U_ij (int,int); -double compute_hybrid() ; -pair find_next_subopt(); -void traceback_right (int,int); -void traceback_left (int,int); -void traceback_U (int,int); -void traceback_hybrid(int i, int j, int num_bp, int unpaired_target, int unpaired_miRNA); -void traceback_seed (int i, int j); -bool traceback (double); -void traceback_print_labels_blanks(int i, int j); -void traceback_print_hybrid_end(int i, int j); -#endif // _HYBRID_ diff --git a/src/intaRNA.cpp b/src/intaRNA.cpp new file mode 100644 index 00000000..27d2e859 --- /dev/null +++ b/src/intaRNA.cpp @@ -0,0 +1,298 @@ + +#include "general.h" + +#include +#include + +#if INTARNA_MULITHREADING + #include +#endif + +#include + +#include "CommandLineParsing.h" + +#include "RnaSequence.h" +#include "Accessibility.h" +#include "InteractionEnergy.h" +#include "Predictor.h" +#include "OutputHandler.h" +#include "OutputHandlerIntaRNA1.h" + +// initialize logging for binary +INITIALIZE_EASYLOGGINGPP + + +///////////////////////////////////////////////////////////////////// +/** + * program main entry + * + * @param argc number of program arguments + * @param argv array of program arguments of length argc + */ +int main(int argc, char **argv){ + + try { + + // set overall logging style + el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format, std::string("# %level : %msg")); + // TODO setup log file + el::Loggers::reconfigureAllLoggers(el::ConfigurationType::ToFile, std::string("false")); + // set additional logging flags + el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); + el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog); + el::Loggers::addFlag(el::LoggingFlag::LogDetailedCrashReason); + el::Loggers::addFlag(el::LoggingFlag::AllowVerboseIfModuleNotSpecified); + + // setup logging with given parameters + START_EASYLOGGINGPP(argc, argv); + + // parse command line parameters + CommandLineParsing parameters; + { + VLOG(1) <<"parsing arguments"<<"..."; + int retCode = parameters.parse( argc, argv ); + if (retCode != CommandLineParsing::ReturnCode::KEEP_GOING) { + return retCode; + } + } + + // number of already reported interactions to enable IntaRNA v1 separator output + size_t reportedInteractions = 0; + + // storage to avoid accessibility recomputation (init NULL) + std::vector< ReverseAccessibility * > queryAcc(parameters.getQuerySequences().size(), NULL); + + // compute all query accessibilities to enable parallelization + // do serially since not all VRNA routines are threadsafe + for (size_t qi=0; qigetSequence().isAmbiguous()) { + LOG(INFO) <<"Sequence '"<getSequence().getId() + <<"' contains ambiguous nucleotide encodings. These positions are ignored for interaction computation."; + } + } + + // check which loop to parallelize + const bool parallelizeTargetLoop = parameters.getTargetSequences().size() > 1; + const bool parallelizeQueryLoop = !parallelizeTargetLoop && parameters.getQuerySequences().size() > 1; + + + // run prediction for all pairs of sequences + // first: iterate over all target sequences +#if INTARNA_MULITHREADING + // OMP shared variables to enable exception forwarding from within OMP parallelized for loop + bool threadAborted = false; + std::exception_ptr exceptionPtrDuringOmp = NULL; + std::stringstream exceptionInfoDuringOmp; + // parallelize this loop if possible; if not -> parallelize the query-loop + # pragma omp parallel for schedule(dynamic) num_threads( parameters.getThreads() ) shared(queryAcc,reportedInteractions,exceptionPtrDuringOmp,exceptionInfoDuringOmp) if(parallelizeTargetLoop) +#endif + for ( size_t targetNumber = 0; targetNumber < parameters.getTargetSequences().size(); ++targetNumber ) + { +#if INTARNA_MULITHREADING + #pragma omp flush (threadAborted) + // explicit try-catch-block due to missing OMP exception forwarding + if (!threadAborted) { + try { + // get target accessibility handler + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(1) <<"computing accessibility for target '"<getSequence().isAmbiguous()) { +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { LOG(INFO) <<"Sequence '"<getSequence().getId() + <<"' contains ambiguous IUPAC nucleotide encodings. These positions are ignored for interaction computation and replaced by 'N'.";} + } + + // second: iterate over all query sequences +#if INTARNA_MULITHREADING + // this parallelization should only be enabled if the outer target-loop is not parallelized + # pragma omp parallel for schedule(dynamic) num_threads( parameters.getThreads() ) shared(queryAcc,reportedInteractions,exceptionPtrDuringOmp,exceptionInfoDuringOmp,targetAcc,targetNumber) if(parallelizeQueryLoop) +#endif + for ( size_t queryNumber = 0; queryNumber < parameters.getQuerySequences().size(); ++queryNumber ) + { +#if INTARNA_MULITHREADING + #pragma omp flush (threadAborted) + // explicit try-catch-block due to missing OMP exception forwarding + if (!threadAborted) { + try { +#endif + // sanity check + assert( queryAcc.at(queryNumber) != NULL ); + + // get energy computation handler for both sequences + InteractionEnergy* energy = parameters.getEnergyHandler( *targetAcc, *(queryAcc.at(queryNumber)) ); + CHECKNOTNULL(energy,"energy initialization failed"); + + // get output/storage handler + OutputHandler * output = parameters.getOutputHandler( *energy ); + CHECKNOTNULL(output,"output handler initialization failed"); + + // check if we have to add separator for IntaRNA v1 output + if (reportedInteractions > 0 && dynamic_cast(output) != NULL) { + dynamic_cast(output)->addSeparator( true ); + } + + // get interaction prediction handler + Predictor * predictor = parameters.getPredictor( *energy, *output ); + CHECKNOTNULL(predictor,"predictor initialization failed"); + + // run prediction for all range combinations + BOOST_FOREACH(const IndexRange & tRange, parameters.getTargetRanges(targetNumber)) { + BOOST_FOREACH(const IndexRange & qRange, parameters.getQueryRanges(queryNumber)) { + +#if INTARNA_MULITHREADING + #pragma omp critical(intarna_omp_logOutput) +#endif + { VLOG(1) <<"predicting interactions for" + <<" target "<getSequence().getId() + <<" (range " <getSequence().getId() + <<" (range " <predict( tRange + , queryAcc.at(queryNumber)->getReversedIndexRange(qRange) + , parameters.getOutputConstraint() + ); + + } // target ranges + } // query ranges + +#if INTARNA_MULITHREADING + #pragma omp atomic update +#endif + reportedInteractions += output->reported(); + + // garbage collection + CLEANUP(predictor); + CLEANUP(output); + CLEANUP(energy); + +#if INTARNA_MULITHREADING + ////////////////////// exception handling /////////////////////////// + } catch (std::exception & e) { + // ensure exception handling for first failed thread only + #pragma omp critical(intarna_omp_exception) + { + if (!threadAborted) { + // store exception information + exceptionPtrDuringOmp = std::make_exception_ptr(e); + exceptionInfoDuringOmp <<" #thread "<(queryAcc[queryNumber]->getAccessibilityOrigin()) ); + // write accessibility to file if needed + parameters.writeQueryAccessibility( *queryAccOrig ); + CLEANUP( queryAccOrig ); + // cleanup (now broken) reverse accessibility object + CLEANUP(queryAcc[queryNumber]); + } + +#if INTARNA_MULITHREADING + if (threadAborted) { + if (!exceptionInfoDuringOmp.str().empty()) { + LOG(WARNING) <<"Exception raised for : "< Please report to the IntaRNA development team! Thanks!\n"; + return -1; + } catch (...) { + std::exception_ptr eptr = std::current_exception(); + LOG(WARNING) <<"Unknown exception raised \n\n" + <<" ==> Please report to the IntaRNA development team! Thanks!\n"; + return -1; + } + + // all went fine + return 0; +} + diff --git a/src/intarna_config.h.in b/src/intarna_config.h.in new file mode 100644 index 00000000..dd1b42ce --- /dev/null +++ b/src/intarna_config.h.in @@ -0,0 +1,56 @@ +#ifndef INTARNA_CONFIG_H +#define INTARNA_CONFIG_H + + +/* +* The following pre-processor definitions specify whether +* or not certain features were activated upon build-time +*/ + +/* Name of package */ +#ifndef INTARNA_PACKAGE +#define INTARNA_PACKAGE "@PACKAGE@" +#endif + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef INTARNA_PACKAGE_BUGREPORT +#define INTARNA_PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" +#endif + +/* Define to the full name of this package. */ +#ifndef INTARNA_PACKAGE_NAME +#define INTARNA_PACKAGE_NAME "@PACKAGE_NAME@" +#endif + +/* Define to the full name and version of this package. */ +#ifndef INTARNA_PACKAGE_STRING +#define INTARNA_PACKAGE_STRING "@PACKAGE_STRING@" +#endif + +/* Define to the one symbol short name of this package. */ +#ifndef INTARNA_PACKAGE_TARNAME +#define INTARNA_PACKAGE_TARNAME "@PACKAGE_TARNAME@" +#endif + +/* Define to the home page for this package. */ +#ifndef INTARNA_PACKAGE_URL +#define INTARNA_PACKAGE_URL "@PACKAGE_URL@" +#endif + +/* Define to the version of this package. */ +#ifndef INTARNA_PACKAGE_VERSION +#define INTARNA_PACKAGE_VERSION "@PACKAGE_VERSION@" +#endif + +/* Version number of package */ +#ifndef INTARNA_VERSION +#define INTARNA_VERSION "@VERSION@" +#endif + + +/* multi-threading support */ +#ifndef INTARNA_MULITHREADING +#define INTARNA_MULITHREADING @INTARNA_MULITHREADING@ +#endif + +#endif // INTARNA_CONFIG_H diff --git a/src/interior_energy.cpp b/src/interior_energy.cpp deleted file mode 100644 index b9aacbe0..00000000 --- a/src/interior_energy.cpp +++ /dev/null @@ -1,136 +0,0 @@ - - -#include "interior_energy.h" - -/************************************************************ - -finds the energy of an interior loop, if the assignments of -both closing BPs and all free bases are known - -(only energy fragments that are important for the difference -of two assignments of the loop) - -************************************************************/ - -double InteriorLoopEnergy(int leftSize, int rightSize, int bp_i, int bp_j, int bp_before_i, int bp_before_j, int bp_i_plus1, int bp_j_minus1, int bp_before_i_minus1, int bp_before_j_plus1) -{ - /* bp_i_plus1 ........ bp_before_i_minus1 - ------bp_i bp_before_i------------ - - ------bp_j bp_before_j------------ - bp_j_minus1..........bp_before_j_plus1 - - bp_i_plus1 and bp_before_i_minus1 might be the same nucleotide (if leftSize == 1) - */ - - // valid base pair test: - //**************************** - if ((PairTest(bp_before_i, bp_before_j) == false) || (PairTest(bp_i, bp_j) == false)) - return MAX_DOUBLE; - else - { - double energy = 0.0; - // double asym = 0.0; - int x1, x2, y1, y2, i1, i2, i3, i4; - int size = leftSize + rightSize; - - int bp_new = BP2int(bp_i, bp_j); - int bp_before = BP2int(bp_before_i, bp_before_j); - - // no bulges and loops of size 0: - //-------------------------------------------- - if ((leftSize == 0) || (rightSize == 0)) - { - printf("No interiorLoop!\n"); - exit(1); - } - - // Special cases: - //------------------------------------------------------ - if ((leftSize == 1) && (rightSize == 1)) - { - x1 = bp_i_plus1; - y1 = bp_j_minus1; - energy += interior_loop_1_1_energy[96*bp_new+24*x1+4*bp_before+y1]; - } - else if ((leftSize == 1) && (rightSize == 2)) /*x(i-1)-x(i)=2 and y(i)-y(i-1)=3*/ - { - x1 = bp_i_plus1; - y1 = bp_before_j_plus1; - y2 = bp_j_minus1; - energy += interior_loop_1_2_energy[384*bp_new+96*y1+24*x1+4*bp_before+y2]; - } - else if ((leftSize == 2) && (rightSize == 1)) /*x(i-1)-x(i)=3 and y(i)-y(i-1)=2*/ - { - x1 = bp_i_plus1; - x2 = bp_before_i_minus1; - y1 = bp_j_minus1; - energy += interior_loop_1_2_energy[384*bp_before+96*x1+24*y1+4*bp_new+x2]; - } - else if ((leftSize == 2) && (rightSize == 2)) - { - x1 = bp_i_plus1; - x2 = bp_before_i_minus1; - y1 = bp_before_j_plus1; - y2 = bp_j_minus1; - energy += interior_loop_2_2_energy[1536*bp_new+256*bp_before+64*x1+16*y2+4*x2+y1]; - } - else - { - if (size <= 30) - energy += loop_destabilizing_energies[3*(size-1)]; - else - { - energy += loop_destabilizing_energies[3*(30-1)]; - // energy += 1.75*RT*log((double)(size/30.0)); replaced by - energy += loop_extrapolation*log((double)(size/30.0)); - } - - // terminal mismatches on both closings: - //---------------------------------------- - // Attention: there are dependencies, if the IL has size 1 at one side of the loop, - // then this base is involved in the terminal mismatches at both closings - if (leftSize == 1) // bp_before_i - bp_before_j - { // i1 i2 - // i3 - // bp_i - bp_j - i1 = bp_i_plus1; - i2 = bp_before_j_plus1; - i3 = bp_j_minus1; - energy += mismatch_energies_interior[64*bp_before_j+16*i2+4*bp_before_i+i1] + mismatch_energies_interior[64*bp_i+16*i1+4*bp_j+i3]; - } - else if (rightSize == 1)// bp_before_i - bp_before_j - { // i1 i3 - // i2 - // bp_i - bp_j - i1 = bp_before_i_minus1; - i2 = bp_i_plus1; - i3 = bp_j_minus1; - energy += mismatch_energies_interior[64*bp_before_j+16*i3+4*bp_before_i+i1] + mismatch_energies_interior[64*bp_i+16*i2+4*bp_j+i3]; - } - else // bp_before_i - bp_before_j - { // i1 i3 - // i2 i4 - // bp_i - bp_j - i1 = bp_before_i_minus1; - i2 = bp_i_plus1; - i3 = bp_before_j_plus1; - i4 = bp_j_minus1; - energy += mismatch_energies_interior[64*bp_before_j+16*i3+4*bp_before_i+i1] + mismatch_energies_interior[64*bp_i+16*i2+4*bp_j+i4]; - } - - // asymmetry-penalty: - //------------------------ - // (for 1x2 IL no extra penalty) - if (leftSize != rightSize) - { - // asym = 0.5 * abs(leftSize-rightSize); if (asym > 3.0) asym = 3.0; energy+=asym; replaced by - energy += Minimum( max_ninio_correction, (ninio_correction * abs(leftSize-rightSize)) ); - } - } - return energy; - } -} - - - diff --git a/src/interior_energy.h b/src/interior_energy.h deleted file mode 100644 index 8b2c00e6..00000000 --- a/src/interior_energy.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _INTERIOR_ENERGY__ -#define _INTERIOR_ENERGY__ - -#include -#include "basics.h" - -using namespace std; - -double InteriorLoopEnergy(int leftSize, int rightSize, int bp_i, int bp_j, int bp_before_i, int bp_before_j, int bp_i_plus1, int bp_j_minus1, int bp_before_i_minus1, int bp_before_j_plus1); - -#endif // _INTERIOR_ENERGY_ diff --git a/src/single_run.cpp b/src/single_run.cpp deleted file mode 100644 index 47b031c0..00000000 --- a/src/single_run.cpp +++ /dev/null @@ -1,666 +0,0 @@ -#include "single_run.h" - - -/************************************************************************************* -* reads a fasta file of sequences in and stores them in a global vector of strings, * -* the sequences are written to every second line of the vector, the other lines are * -* filled with the sequences' names * -*************************************************************************************/ - - -bool readin_fasta(char* filename, vector& vec) -{ - bool okay; - ifstream seqin(filename); - - if (seqin.fail()) - { - cerr << "The file " << filename << " does not exist!\n"; - exit(1); - } - - string tmp, tmp_seq = ""; - while (!seqin.eof()) - { - getline(seqin,tmp); - if (tmp[0] == '>') - { - if (tmp_seq == "") - { - if ((int)vec.size() == 0) - vec.push_back(tmp); - else // sequence missing - { - cout << "# WARNING: Sequence " << vec[(int)vec.size()-1] << " is missing and thus skipped.\n"; - vec.pop_back(); - vec.push_back(tmp); - } - } - else - { - okay = check_sequence_and_set2upper(tmp_seq); - if (okay) - vec.push_back(tmp_seq); - else - { - cout << "# WARNING: Sequence " << vec[(int)vec.size()-1] << " in file " << filename << " is skipped due to invalid character(s).\n"; - vec.pop_back(); - } - vec.push_back(tmp); - tmp_seq = ""; - } - } - else - tmp_seq += tmp; - } - - seqin.close(); - - //if file empty - if ((int)vec.size() == 0) - return false; - - - //final sequence - if (tmp_seq == "") - { - cout << "# WARNING: Sequence " << vec[(int)vec.size()-1] << " is missing and thus skipped.\n"; - vec.pop_back(); - } - else - { - okay = check_sequence_and_set2upper(tmp_seq); - if (okay) - vec.push_back(tmp_seq); - else - { - cout << "# WARNING: Sequence " << vec[(int)vec.size()-1] << " in file " << filename << " is skipped due to invalid character(s).\n"; - vec.pop_back(); - } - } - - //print - // for (int i=0; i<(int)vec.size(); i++) - // cout << vec[i] << endl; - - - // if size == 0 => no sequence in the file or all sequences have errors - if ((int)vec.size() == 0) - return false; - else - return true; -} - - - -/*************************************************************************** -* test, whether the values of the input options relevant for the * - hybridization are valid for the current sequences * -***************************************************************************/ - -bool test_options_hybridization() -{ - - if (num_bp_seed < 2) - { - cerr << "The length of the seed has to be at least 2!\n\n"; - return false; - } - - if (num_bp_seed > Minimum((int)strlen(sequence_target),(int)strlen(sequence_miRNA))) - { - cerr << "The length of the seed has to be less than or equal the length of the shortest input sequence!\n\n"; - return false; - } - - if ((max_unpaired_target < 0) || (max_unpaired_miRNA < 0) || (max_unpaired < 0)) - { - if (max_unpaired < 0) - cerr << "The maximal sum of unpaired bases in the seed region has to be greater or equal to 0!\n\n"; - else - cerr << "The maximal number of unpaired bases in the seed region of both sequences has to be greater or equal to 0!\n\n"; - return false; - } - - if (max_unpaired_target > (int)strlen(sequence_target)) - { - cerr << "The number of unpaired bases in the seed region of sequence 1 has to be less or equal to the length of sequence 1!\n\n"; - return false; - } - - if (max_unpaired_miRNA > (int)strlen(sequence_miRNA)) - { - cerr << "The number of unpaired bases in the seed region of sequence 2 has to be less or equal to the length of sequence 2!\n\n"; - return false; - } - - if (max_unpaired > ((int)strlen(sequence_target)+(int)strlen(sequence_miRNA))) - { - cerr << "The number of unpaired bases in the seed region of both sequences has to be less or equal to the sum of the lengths of the sequences!\n\n"; - return false; - } - - if (seed_region_ncRNA && num_bp_seed > seed_region_end_ncRNA_5-seed_region_start_ncRNA_5+1) - { - cerr << "The length of the seed has to be at most the length of the seed region in the binding RNA!\n\n"; - return false; - } - - if (seed_region_ncRNA && seed_region_start_ncRNA_5 > seed_region_end_ncRNA_5 ) - { - cerr << "The start of the seed region in the binding RNA has to be less than or equal to the end of the seed region!\n\n"; - return false; - } - - if (seed_region_ncRNA && seed_region_start_ncRNA_5 < 1 ) - { - cerr << "The start of the seed region in the binding RNA has to be at least 1!\n\n"; - return false; - } - - if ( seed_region_ncRNA && seed_region_end_ncRNA_5 > (int)strlen(sequence_miRNA)) - { - cerr << "The end of the seed region in the binding RNA has to be less than or equal to the length of its sequence!\n\n"; - return false; - } - - if (max_unpaired > max_unpaired_target + max_unpaired_miRNA) - { - if (max_unpaired_target == 0 && max_unpaired_miRNA == 0) - { - max_unpaired_target = max_unpaired_miRNA = max_unpaired; - } - else if (max_unpaired_miRNA == 0) - { - max_unpaired_miRNA = max_unpaired; - } - else if (max_unpaired_target == 0) - { - max_unpaired_target = max_unpaired; - } - } - - if (max_unpaired == 0 && (max_unpaired_target != 0 || max_unpaired_miRNA != 0)) - { - cerr << "The number of unpaired bases in the seed region of both sequences should be at least equal to the number of unpaired bases in a single sequence!\n\n"; - return false; - } - - return true; - -} - - -/*************************************************************************** -* test, whether the values of the input options relevant for the * - sliding window are valid for the current sequences * -***************************************************************************/ - -bool test_options_window() -{ - if ((window == true) && (window_size < 3)) // RNAplfold crashes if W is set smaller than 3 - { - cerr << "The window size has to be higher or equal to 3!\n"; - return false; - } - - if (window_size > (int)strlen(sequence_target)) - { - cerr << "The window size has to be at most the size of the target sequence!\n"; - return false; - } - - if ((max_length == true) && (max_unpaired_length < 1)) - { - cerr << "The max. length of unpaired bases has to be higher or equal to 1!\n"; - return false; - } - - if (max_unpaired_length > window_size) - { - cerr << "The max. length of unpaired bases has to be lower or equal to the window size!\n"; - return false; - } - - if ((max_dist == true) && (max_pair_dist < 1)) - { - cerr << "The max. distance of two paired bases has to be higher or equal to 1!\n"; - return false; - } - - if (max_pair_dist > window_size) - { - cerr << "The max. distance of two paired bases has to be lower or equal to the window size!\n"; - return false; - } - -/* if (max_unpaired_length < max_unpaired) - { - cerr << "The max. length of unpaired bases has to be higher or equal to the number of unpaired base in the seed region of both sequences!\n"; - return false; - } -*/ - return true; -} - - -/********************************************************************************** -* Init all data structures for target * -**********************************************************************************/ - -void init_target() -{ - //translate sequences into integer - int_sequence_target = char2int(sequence_target); - - /************************************************************************* - * if window and/or max_length are false, the values for window_size * - * and max_unpaired_length are set to the maximal values (in the target)* - * if max_dist is false, the value of max_bp_dist is set to the window * - * size * - ************************************************************************/ - - if (window == false) - window_size = (int)strlen(sequence_target); - - if (max_length == false) - // max_unpaired_length has to be longer than length of miRNA sequence, - // since interacting region in target can contain long bulges - max_unpaired_length = window_size; - - if (max_dist == false) - max_pair_dist = window_size; - - /*************************************************************************** - * test, whether the values of the input options relevant for * - * hybridization are valid * - ***************************************************************************/ - - if (!test_options_window()) - exit(1); - - - allocate_ED_target_matrix(); /* space allocation */ - init_ED_target_matrix() ; /* init */ - - ED_target_computed = false; - -//has been moved to compute_seed_ij and is computed only when valid seed has been found -// // calculate ED matrix for target -// if (use_RNAplfold) -// calc_ED_target_matrix_plfold(sequence_target); -// else -// { -// if (window) -// calc_ED_target_matrix_window(); -// else -// calc_ED_target_matrix(); -// } -} - - -/********************************************************************************** -* Init all data structures for miRNA * -**********************************************************************************/ - -void init_miRNA() -{ - //translate sequences into integer - int_sequence_miRNA = char2int(sequence_miRNA); - - allocate_ED_miRNA_matrix(); /* space allocation */ - init_ED_miRNA_matrix() ; /* init */ - - ED_miRNA_computed = false; - -//has been moved to compute_seed_ij and is computed only when valid seed has been found -// // calculate ED matrix for miRNA -// calc_ED_miRNA_matrix(); -} - - -/********************************************************************************** -* Free all data structures for miRNA * -**********************************************************************************/ - -void free_target() -{ - free_ED_target_matrix(); - free(int_sequence_target); -} - - -/********************************************************************************** -* Free all data structures for miRNA * -**********************************************************************************/ - -void free_miRNA() -{ - free_ED_miRNA_matrix(); - free(int_sequence_miRNA); -} - - -/********************************************************************************** -* Clear sequences after hybridization * -**********************************************************************************/ - -void clear_hydrization_seq() -{ - bulges_sequence_target.clear(); - hybrid_sequence_target.clear(); - hybrid_sequence_miRNA.clear(); - bulges_sequence_miRNA.clear(); -} - - -/********************************************************************************** -* Print the input and the results of the initializing step * -**********************************************************************************/ - -void print_input() -{ - cout << "-------------------------" << endl; - cout << "INPUT " << endl; - cout << "-------------------------" << endl; - cout << "number of base pairs in seed : " << num_bp_seed << endl; - cout << "max. number of unpaired bases in the seed region of seq. 1 : " << max_unpaired_target << endl; - cout << "max. number of unpaired bases in the seed region of seq. 2 : " << max_unpaired_miRNA << endl; - cout << "max. number of unpaired bases in the seed region of both seq's: " << max_unpaired << endl; - if (seed_region_ncRNA) - //recalculated start and end positions since up to now we are using the reverse of the miRNA - cout << "search region for seed in seq. 2 : " - << seed_region_start_ncRNA_5 << " -- " - << seed_region_end_ncRNA_5 << endl; - cout << "RNAup used : " << (use_RNAup ? "true":"false") << endl; - cout << "RNAplfold used : " << (use_RNAplfold ? "true":"false") << endl; - if (window || use_RNAplfold) - cout << "sliding window size : " << window_size << endl; - if (max_length || use_RNAplfold) - cout << "max. length of unpaired region : " << max_unpaired_length << endl; - if (max_dist || use_RNAplfold) - cout << "max. distance of two paired bases : " << max_pair_dist << endl; - cout << "weight for ED values of target RNA in energy : " << ED_target_scaling << endl; - cout << "weight for ED values of binding RNA in energy : " << ED_miRNA_scaling << endl; - if (fabs(pu_comb_threshold+1.0) > DOUBLE_DIFF) - cout << "threshold for seed accessibility : " << pu_comb_threshold << endl; - cout << "temperature : " << temperature << " Celsius" << endl; - cout << "max. number of subopt. results : " << max_subopt << endl; - cout << "Heuristic for hybridization end used : " << (heuristic ? "true":"false") << endl << endl; - cout << "-------------------------" << endl; - cout << "OUTPUT " << endl; - cout << "-------------------------" << endl; - - return; -} - - -void print_matrices() -{ - cout << "ED_target" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_target);j++) - cout << ED_target[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "ED_ncRNA" << endl; - for(int i=0;i<(int)strlen(sequence_miRNA);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << ED_miRNA[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "C" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << C[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "C_seed" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << Cseed[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "U" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << U[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "seed" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << seed[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "seed_unpaired_target" << endl; - for (int i=0; i<(int)strlen(sequence_target); i++) - { - for (int j=0; j<(int)strlen(sequence_miRNA); j++) - cout << seed_unpaired_target[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "seed_unpaired_ncRNA" << endl; - for (int i=0; i<(int)strlen(sequence_target); i++) - { - for (int j=0; j<(int)strlen(sequence_miRNA); j++) - cout << seed_unpaired_miRNA[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "che1" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << che1[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "che2" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << che2[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "ches1" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << ches1[i][j] << "\t"; - cout << endl; - } - cout << endl; - - cout << "ches2" << endl; - for(int i=0;i<(int)strlen(sequence_target);i++) - { - for(int j=0;j<(int)strlen(sequence_miRNA);j++) - cout << ches2[i][j] << "\t"; - cout << endl; - } - cout << endl; -} - - -/********************************************************************************** -* Print hybridization * -**********************************************************************************/ - -void print_hybridization(double v) -{ - cout << bulges_sequence_target << endl; - cout << hybrid_sequence_target << endl; - cout << hybrid_sequence_miRNA << endl; - cout << bulges_sequence_miRNA << endl << endl; - - if (detailed_output) - { - //cout << "positions(target): -- " << pos_target_1 << " -- " << pos_target_2 << " -- " << pos_target_3 << " -- " << pos_target_4 << endl; - //cout << "positions(miRNA ): -- " << pos_miRNA_1 << " -- " << pos_miRNA_2 << " -- " << pos_miRNA_3 << " -- " << pos_miRNA_4 << endl; - - //pos+1 for using a numbering starting at 1 - cout << "positions(target) : " << pos_target_1+1 << " -- " << pos_target_4+1 << endl; - cout << "positions seed(target): " << pos_target_2+1 << " -- " << pos_target_3+1 << endl; - //positions including dangling ends - cout << "positions with dangle(target): " << pos_target_1_dangle+1 << " -- " << pos_target_4_dangle+1 << endl; - //recalculated start and end positions since up to now we are using the reverse of the miRNA - int real_pos_miRNA_1 = (int)strlen(sequence_miRNA) - pos_miRNA_1; - int real_pos_miRNA_4 = (int)strlen(sequence_miRNA) - pos_miRNA_4; - cout << "positions(ncRNA) : " << real_pos_miRNA_4 << " -- " << real_pos_miRNA_1 << endl; - cout << "positions seed(ncRNA) : " << (int)strlen(sequence_miRNA)-pos_miRNA_3 << " -- " - << (int)strlen(sequence_miRNA)-pos_miRNA_2 << endl; - cout << "positions with dangle(ncRNA): " << (int)strlen(sequence_miRNA) - pos_miRNA_4_dangle << " -- " - << (int)strlen(sequence_miRNA) - pos_miRNA_1_dangle << endl; - //cout << "positions(miRNA ): " << pos_miRNA_1+1 << " -- " << pos_miRNA_4+1 << endl; - - double round_ED_target= (fabs(ED_target[pos_target_1_dangle][pos_target_4_dangle]) subopt_hybrid; - - //Computation and Traceback of optimal hybridization - //**************************************************** - allocate_global_matrices(); /* space allocation */ - init_global_matrices() ; /* init */ - - double v=compute_hybrid(); - bool hybridization_found=traceback(v); - - //Output of optimal hybridization - //**************************************************** - - if (detailed_output && target_counter==0 && miRNA_counter==0) - print_input(); - - if (!hybridization_found || v>=threshold) - { - if ((target_file == false) && (miRNA_file == false)) - { - if (is_ambiguous_sequence(sequence_target) || - is_ambiguous_sequence(sequence_miRNA)) - cout << "\n# WARNING: Ambiguous nucleotide(s) 'N' are excluded from all base pairings of the interaction.\n\n"; - - cout << "no significant hybridization found" << endl << endl; - } - clear_hydrization_seq(); - } - else - { - if ((target_counter > 0) || (miRNA_counter > 0)) - cout << "=========================" << endl << endl;; - - // Name of target - cout << target_name << endl; - - // Sequence of target - if (detailed_output) - cout << sequence_target << endl; - - // Name of miRNA - cout << miRNA_name << endl; - - // Sequence of miRNA - if (detailed_output) - { - change_direction(sequence_miRNA); - cout << sequence_miRNA << endl; - change_direction(sequence_miRNA); - } - - cout << endl; - - if (is_ambiguous_sequence(sequence_target) || - is_ambiguous_sequence(sequence_miRNA)) - cout << "# WARNING: Ambiguous nucleotide(s) 'N' are excluded from all base pairings of the interaction.\n\n"; - - print_hybridization(v); - - //Traceback of suboptimal hybridizations and Output - //**************************************************** - - // Find and Output max. n suboptimal hybridizations if below value 'threshold' - for (int n=0;hybridization_found && n < max_subopt && v < threshold;n++) - { - // find next suboptimal hybridization - subopt_hybrid = find_next_subopt(); - hybridization_found = subopt_hybrid.first; - v = subopt_hybrid.second; - - if (hybridization_found && v < threshold) - { - print_hybridization(v); - } - else - { - if (n == 0) - { - if ((target_file == false) && (miRNA_file == false)) - { - cout << "no significant suboptimal hybridization found" << endl << endl; - } - } - else - { - if ((target_file == false) && (miRNA_file == false)) - { - cout << "no more significant suboptimal hybridizations found" << endl << endl; - } - } - clear_hydrization_seq(); - } - } - } - - // print_matrices(); - - free_global_matrices(); - - return; -} - diff --git a/src/single_run.h b/src/single_run.h deleted file mode 100644 index 66fc41ef..00000000 --- a/src/single_run.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _SINGLE_RUN__ -#define _SINGLE_RUN__ - -#include -#include "basics.h" - -using namespace std; - -bool readin_fasta(char* filename, vector& vec); -bool test_options_hybridization(); -bool test_options_window(); -void init_target(); -void init_miRNA(); -void free_target(); -void free_miRNA(); -void clear_hydrization_seq(); -void print_input(); -void print_matrices(); -void print_hybridization(double v); -void calculation(); - -#endif // _SINGLE_RUN__ diff --git a/src/stacking_energy.cpp b/src/stacking_energy.cpp deleted file mode 100644 index d5f1515a..00000000 --- a/src/stacking_energy.cpp +++ /dev/null @@ -1,16 +0,0 @@ - -#include "stacking_energy.h" - -double StackingEnergy(int bp_i, int bp_j, int bp_before_i, int bp_before_j) -{ - double energy; - - if ((PairTest(bp_before_i, bp_before_j) == true) && (PairTest(bp_i, bp_j) == true)) - energy = stacking_energies[64*bp_i+16*bp_before_i+4*bp_j+bp_before_j]; - else - energy = MAX_DOUBLE; - - return energy; -} - - diff --git a/src/stacking_energy.h b/src/stacking_energy.h deleted file mode 100644 index d1134294..00000000 --- a/src/stacking_energy.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _STACKING_ENERGY__ -#define _STACKING_ENERGY__ - -#include -#include "basics.h" - -using namespace std; - -double StackingEnergy(int bp_i, int bp_j, int bp_before_i, int bp_before_j); - -#endif // _STACKING_ENERGY_ diff --git a/tests/AccessibilityConstraint_test.cpp b/tests/AccessibilityConstraint_test.cpp new file mode 100644 index 00000000..4480ec23 --- /dev/null +++ b/tests/AccessibilityConstraint_test.cpp @@ -0,0 +1,40 @@ + + +#include "catch.hpp" + +#undef NDEBUG + +#include "AccessibilityConstraint.h" + +TEST_CASE( "AccessibilityConstraint", "[AccessibilityConstraint]" ) { + + + SECTION("check empty construction") { + AccessibilityConstraint c(10); + REQUIRE( c.isEmpty() ); + REQUIRE_FALSE( c.isMarkedBlocked(0) ); + REQUIRE_FALSE( c.isMarkedAccessible(0) ); + REQUIRE( c.isAccessible(0) ); + REQUIRE( c.isUnconstrained(0) ); + } + + SECTION("check dot-bracket construction") { + AccessibilityConstraint c("..bb..xx..bb"); + REQUIRE_FALSE( c.isEmpty() ); + REQUIRE_FALSE( c.isMarkedBlocked(0) ); + REQUIRE_FALSE( c.isMarkedAccessible(0) ); + REQUIRE( c.isAccessible(0) ); + REQUIRE( c.isUnconstrained(0) ); + REQUIRE( c.isMarkedBlocked(3) ); + REQUIRE_FALSE( c.isAccessible(3) ); + REQUIRE_FALSE( c.isUnconstrained(3) ); + REQUIRE( c.isMarkedAccessible(6) ); + REQUIRE( c.isAccessible(6) ); + REQUIRE_FALSE( c.isUnconstrained(6) ); + REQUIRE( c.isMarkedBlocked(10) ); + REQUIRE_FALSE( c.isAccessible(10) ); + } + + +} + diff --git a/tests/AccessibilityFromStream_test.cpp b/tests/AccessibilityFromStream_test.cpp new file mode 100644 index 00000000..65cd0d66 --- /dev/null +++ b/tests/AccessibilityFromStream_test.cpp @@ -0,0 +1,136 @@ + +#include "catch.hpp" + +#undef NDEBUG + +#include "AccessibilityFromStream.h" + +const std::string seq = "uaugacugacuggcgcgcguacugacguga"; + +const std::string accString = +"#unpaired probabilities\n" +" #i$ l=1 2 3 4 5 6 7 8 9 10 \n" +"1 0.9949492 NA NA NA NA NA NA NA NA NA \n" +"2 0.9949079 0.9941056 NA NA NA NA NA NA NA NA \n" +"3 0.9554214 0.9518663 0.9511048 NA NA NA NA NA NA NA \n" +"4 0.9165814 0.9122866 0.9090283 0.9083552 NA NA NA NA NA NA \n" +"5 0.998999 0.915609 0.9117766 0.9085215 0.9079146 NA NA NA NA NA \n" +"6 0.8549929 0.8541667 0.8448852 0.8431375 0.8398829 0.8393024 NA NA NA NA \n" +"7 0.9161161 0.8446519 0.8438282 0.8348281 0.8330847 0.8313335 0.8307534 NA NA NA \n" +"8 0.9830043 0.9081378 0.8373899 0.8365669 0.8278368 0.8262157 0.824465 0.824227 NA NA \n" +"9 0.997844 0.9813391 0.9065023 0.8358459 0.8350237 0.8264586 0.8260226 0.8242721 0.8241441 NA \n" +"10 0.9906155 0.9893027 0.9730023 0.8981675 0.8275292 0.8267074 0.8218168 0.8213811 0.8196307 0.8195027 \n" +"11 0.9941335 0.9851103 0.9839263 0.9676888 0.8928559 0.8222774 0.8222198 0.8180557 0.817621 0.8176206 \n" +"12 0.8690241 0.8654449 0.8566608 0.8554815 0.839264 0.8380446 0.8219215 0.821864 0.8177102 0.8174872 \n" +"13 0.9107177 0.8531571 0.8517984 0.8431146 0.8419464 0.8257519 0.8253962 0.8198182 0.8197612 0.8156254 \n" +"14 0.7755244 0.747624 0.7155972 0.7144589 0.706254 0.7052549 0.7036699 0.7033524 0.6977753 0.6977266 \n" +"15 0.8058957 0.7601865 0.7326016 0.7027262 0.7016679 0.6982151 0.6972195 0.6956395 0.6954189 0.695329 \n" +"16 0.02191314 0.01959841 0.01791968 0.01723728 0.01616173 0.01612733 0.01540904 0.01538624 0.01534086 0.01533351 \n" +"17 0.006584845 0.004112372 0.003121421 0.002703536 0.00256851 0.002078218 0.002074677 0.00146262 0.001459626 0.001442846 \n" +"18 0.06644609 0.003804626 0.002098785 0.001559709 0.001266798 0.001193299 0.001136074 0.001133916 0.0005256679 0.0005240971 \n" +"19 0.111588 0.06519989 0.002731614 0.001196305 0.0006678619 0.0006216257 0.0005496343 0.0004939404 0.0004923591 0.0004805025 \n" +"20 0.218612 0.1112393 0.06492555 0.002594459 0.001065674 0.0005483276 0.000508408 0.0004408385 0.0003950237 0.0003935838 \n" +"21 0.9994454 0.2185816 0.1112115 0.06489999 0.002569867 0.001041783 0.0005260561 0.0004874071 0.000420591 0.0003755812 \n" +"22 0.9989273 0.9985739 0.2182373 0.110926 0.06462868 0.002470349 0.0009426092 0.0004363855 0.000398409 0.0003850587 \n" +"23 0.9710494 0.970038 0.9696895 0.1893656 0.1088858 0.06258917 0.002455754 0.0009280366 0.0004343271 0.0003963808 \n" +"24 0.9250563 0.9249602 0.9243959 0.9240502 0.1446156 0.06419723 0.06149891 0.001366442 0.0008949269 0.0004013865 \n" +"25 0.2210327 0.1460893 0.1460065 0.1454443 0.1450991 0.1446134 0.06419553 0.06149747 0.001365021 0.0008935096 \n" +"26 0.004788834 0.004701346 0.004555013 0.004523588 0.004243178 0.003900484 0.003612546 0.003570138 0.0008844166 0.0008689095 \n" +"27 0.001313809 0.001162996 0.001158495 0.001102602 0.001085606 0.001015911 0.0006740694 0.0004613423 0.0004217853 0.0003974838 \n" +"28 0.003579508 0.001248483 0.001151334 0.001146998 0.00109294 0.001076138 0.001006977 0.0006660441 0.0004544384 0.0004200339 \n" +"29 0.02706842 0.002727444 0.001208356 0.001115501 0.001111228 0.001059088 0.001043366 0.001003024 0.0006621005 0.0004513765 \n" +"30 0.9980056 0.02520127 0.002719133 0.001206888 0.001114084 0.001109818 0.001057748 0.001043013 0.001002708 0.0006617864 \n" +"\n" +; + + +#include + +TEST_CASE( "AccessibilityFromStream", "[AccessibilityFromStream]" ) { + + // create data + RnaSequence rna("test",seq); + + SECTION("construction") { + + // prepare stream to read from + std::istringstream accStream(accString); + + // trigger parsing + AccessibilityFromStream acc( rna, 10, NULL, accStream, AccessibilityFromStream::Pu_RNAplfold_Text, 1.0 ); + +// std::cerr <<"orig data:\n" < 0.998 ); + REQUIRE( std::exp( - acc.getED(29, 29) ) < 0.999 ); + REQUIRE( std::exp( - acc.getED(20, 29) ) > 0.0006 ); + REQUIRE( std::exp( - acc.getED(20, 29) ) < 0.0007 ); + } + + SECTION("Pu_RNAplfold output reparsed") { + + // prepare stream to read from + std::istringstream accStream(accString); + + // trigger parsing + AccessibilityFromStream acc( rna, 10, NULL, accStream, AccessibilityFromStream::Pu_RNAplfold_Text, 1.0 ); + + // check elements + REQUIRE( std::exp( - acc.getED(29, 29) ) > 0.998 ); + REQUIRE( std::exp( - acc.getED(29, 29) ) < 0.999 ); + REQUIRE( std::exp( - acc.getED(20, 29) ) > 0.0006 ); + REQUIRE( std::exp( - acc.getED(20, 29) ) < 0.0007 ); + + std::stringstream accStream2; + acc.writeRNAplfold_Pu_text( accStream2, 1.0 ); + + // trigger parsing + AccessibilityFromStream acc2( rna, 10, NULL, accStream2, AccessibilityFromStream::Pu_RNAplfold_Text, 1.0 ); + + // check elements + REQUIRE( std::exp( - acc2.getED(29, 29) ) > 0.998 ); + REQUIRE( std::exp( - acc2.getED(29, 29) ) < 0.999 ); + REQUIRE( std::exp( - acc2.getED(20, 29) ) > 0.0006 ); + REQUIRE( std::exp( - acc2.getED(20, 29) ) < 0.0007 ); + + } + + SECTION("ED_RNAplfold output reparsed") { + + // prepare stream to read from + std::istringstream accStream(accString); + + // trigger parsing + AccessibilityFromStream acc( rna, 10, NULL, accStream, AccessibilityFromStream::Pu_RNAplfold_Text, 1.0 ); + + // check elements + REQUIRE( std::exp( - acc.getED(29, 29) ) > 0.998 ); + REQUIRE( std::exp( - acc.getED(29, 29) ) < 0.999 ); + REQUIRE( std::exp( - acc.getED(20, 29) ) > 0.0006 ); + REQUIRE( std::exp( - acc.getED(20, 29) ) < 0.0007 ); + + std::stringstream accStream2; + acc.writeRNAplfold_ED_text( accStream2 ); + + // trigger parsing + AccessibilityFromStream acc2( rna, 10, NULL, accStream2, AccessibilityFromStream::ED_RNAplfold_Text, 1.0 ); + + // check elements + REQUIRE( std::exp( - acc2.getED(29, 29) ) > 0.998 ); + REQUIRE( std::exp( - acc2.getED(29, 29) ) < 0.999 ); + REQUIRE( std::exp( - acc2.getED(20, 29) ) > 0.0006 ); + REQUIRE( std::exp( - acc2.getED(20, 29) ) < 0.0007 ); + + } + + SECTION("sequence too long") { + // prepare stream to read from + std::istringstream accStream(accString); + RnaSequence rnaDouble("tooLong",seq+seq); + // trigger parsing exception + REQUIRE_THROWS( AccessibilityFromStream( rnaDouble, 10, NULL, accStream, AccessibilityFromStream::Pu_RNAplfold_Text, 1.0 ) ); + } + +} diff --git a/tests/IndexRangeList_test.cpp b/tests/IndexRangeList_test.cpp new file mode 100644 index 00000000..5e8d0999 --- /dev/null +++ b/tests/IndexRangeList_test.cpp @@ -0,0 +1,180 @@ + + + +#include "catch.hpp" + +#undef NDEBUG + +#include "IndexRangeList.h" + +TEST_CASE( "IndexRangeList", "[IndexRangeList]" ) { + + + IndexRangeList rangeList; + + SECTION("check construction and empty list") { + REQUIRE( rangeList.size() == 0 ); + REQUIRE( rangeList.empty() ); + REQUIRE( rangeList.begin() == rangeList.end() ); + REQUIRE( rangeList.rbegin() == rangeList.rend() ); + REQUIRE_FALSE( rangeList.covers( 3 ) ); + REQUIRE_FALSE( rangeList.overlaps( IndexRange(2,3) ) ); + } + + SECTION("check push_back()") { + + IndexRange r5_10(5,10); + + rangeList.push_back(r5_10); + REQUIRE( *rangeList.begin() == r5_10 ); + REQUIRE( *rangeList.rbegin() == r5_10 ); + REQUIRE( rangeList.size() == 1 ); + REQUIRE_FALSE( rangeList.empty() ); + REQUIRE( rangeList.begin() != rangeList.end() ); + REQUIRE( rangeList.rbegin() != rangeList.rend() ); + REQUIRE_FALSE( rangeList.covers( 3 ) ); + REQUIRE_FALSE( rangeList.overlaps( IndexRange(2,3) ) ); + REQUIRE( rangeList.covers( 8 ) ); + REQUIRE( rangeList.covers( 8, 10 ) ); + REQUIRE( rangeList.covers( 5, 10 ) ); + REQUIRE( rangeList.covers( 5, 6 ) ); + REQUIRE_FALSE( rangeList.covers( 5, 12 ) ); + REQUIRE_FALSE( rangeList.covers( 1, 12 ) ); + REQUIRE_FALSE( rangeList.covers( 1, 8 ) ); + REQUIRE( rangeList.overlaps( IndexRange(2,8) ) ); + REQUIRE( rangeList.overlaps( IndexRange(6,8) ) ); + REQUIRE( rangeList.overlaps( IndexRange(6,12) ) ); + + IndexRange r15_20(15,20); + + rangeList.push_back(r15_20); + REQUIRE( *rangeList.begin() == r5_10 ); + REQUIRE( *rangeList.begin() != r15_20 ); + REQUIRE( *rangeList.rbegin() == r15_20 ); + REQUIRE( rangeList.size() == 2 ); + REQUIRE_FALSE( rangeList.empty() ); + REQUIRE_FALSE( rangeList.covers( 3 ) ); + REQUIRE_FALSE( rangeList.covers( 13 ) ); + REQUIRE_FALSE( rangeList.overlaps( IndexRange(12,13) ) ); + REQUIRE_FALSE( rangeList.overlaps( IndexRange(28,30) ) ); + REQUIRE( rangeList.covers( 8 ) ); + REQUIRE( rangeList.covers( 18 ) ); + REQUIRE( rangeList.covers( 8 ) ); + REQUIRE( rangeList.covers( 8, 10 ) ); + REQUIRE( rangeList.covers( 5, 10 ) ); + REQUIRE( rangeList.covers( 5, 6 ) ); + REQUIRE( rangeList.covers( 16, 18 ) ); + REQUIRE_FALSE( rangeList.covers( 12, 13 ) ); + REQUIRE_FALSE( rangeList.covers( 12, 16 ) ); + REQUIRE_FALSE( rangeList.covers( 10, 18 ) ); + REQUIRE( rangeList.overlaps( IndexRange(2,8) ) ); + REQUIRE( rangeList.overlaps( IndexRange(5,8) ) ); + REQUIRE( rangeList.overlaps( IndexRange(6,8) ) ); + REQUIRE( rangeList.overlaps( IndexRange(6,10) ) ); + REQUIRE( rangeList.overlaps( IndexRange(6,12) ) ); + REQUIRE( rangeList.overlaps( IndexRange(5,18) ) ); + REQUIRE( rangeList.overlaps( IndexRange(6,18) ) ); + REQUIRE( rangeList.overlaps( IndexRange(2,28) ) ); + REQUIRE( rangeList.overlaps( IndexRange(2,28) ) ); + REQUIRE( rangeList.overlaps( IndexRange(12,28) ) ); + + } + + SECTION("check insert()") { + + IndexRange r5_10(5,10); + + IndexRangeList::iterator it = rangeList.insert(r5_10); + REQUIRE( rangeList.begin() == it ); + REQUIRE( *it == r5_10 ); + REQUIRE( *rangeList.begin() == r5_10 ); + REQUIRE( *rangeList.rbegin() == r5_10 ); + REQUIRE( rangeList.size() == 1 ); + REQUIRE_FALSE( rangeList.empty() ); + REQUIRE( rangeList.begin() != rangeList.end() ); + REQUIRE( rangeList.rbegin() != rangeList.rend() ); + + IndexRange r1_2(1,2); + + it = rangeList.insert(r1_2); + REQUIRE( rangeList.begin() == it ); + REQUIRE( *it == r1_2 ); + REQUIRE( *rangeList.begin() == r1_2 ); + REQUIRE( *rangeList.rbegin() == r5_10 ); + REQUIRE( rangeList.size() == 2 ); + REQUIRE_FALSE( rangeList.empty() ); + + IndexRange r3_4(3,4); + + it = rangeList.insert(r3_4); + REQUIRE( rangeList.begin() != it ); + REQUIRE( *it == r3_4 ); + REQUIRE( *rangeList.begin() == r1_2 ); + REQUIRE( *(++rangeList.begin()) == r3_4 ); + REQUIRE( *rangeList.rbegin() == r5_10 ); + REQUIRE( rangeList.size() == 3 ); + + } + + + SECTION("check string en-/decoding") { + + // write to string + std::stringstream s; + // parse from string + IndexRangeList list2(s.str()); + REQUIRE( rangeList == list2 ); + + rangeList.insert(IndexRange(4,8)); + s.str(""); s < + +TEST_CASE( "IndexRange", "[IndexRange]" ) { + + + IndexRange range; + + SECTION("check default construction") { + REQUIRE( range.isAscending() ); + REQUIRE( range.from == 0 ); + REQUIRE( range.to > range.from ); + REQUIRE_FALSE( range.isDescending() ); + REQUIRE( range.to > std::numeric_limits::max()-1 ); + } + + SECTION("check ordering") { + + IndexRange r2; + + // equal + REQUIRE_FALSE( range < r2 ); + + // equal from + r2.to = 10; + REQUIRE_FALSE( range < r2 ); + REQUIRE( r2 < range ); + REQUIRE( r2.isAscending() ); + REQUIRE_FALSE( r2.isDescending() ); + + // from ordered + r2.from = 10; + REQUIRE( range < r2 ); + REQUIRE( r2.isDescending() ); + REQUIRE( r2.isAscending() ); + } + + + SECTION("check string en-/decoding") { + + // write to string + std::stringstream s; + range = (4,8); + s < 0.0 ); + + // base pairs possible + REQUIRE( energy.getE_interLeft( 0,1, 0,1 ) < 0.0 ); + + // base pairs overlapping + REQUIRE_FALSE( energy.getE_interLeft( 0,0, 0,1 ) < 0.0 ); + REQUIRE_FALSE( energy.getE_interLeft( 0,1, 0,0 ) < 0.0 ); + + // base pairs not possible + REQUIRE_FALSE( energy.getE_interLeft( 0,0, 1,1 ) < 0.0 ); + REQUIRE_FALSE( energy.getE_interLeft( 0,1, 2,3 ) < 0.0 ); + REQUIRE_FALSE( energy.getE_interLeft( 0,1, 0,2 ) < 0.0 ); + REQUIRE_FALSE( energy.getE_interLeft( 0,2, 1,2 ) < 0.0 ); + + // loop size exceeded + REQUIRE_FALSE( energy.getE_interLeft( 0,3, 1,2 ) < 0.0 ); + REQUIRE_FALSE( energy.getE_interLeft( 1,2, 0,3 ) < 0.0 ); + REQUIRE_FALSE( energy.getE_interLeft( 0,3, 0,3 ) < 0.0 ); + + } + +} diff --git a/tests/InteractionRange_test.cpp b/tests/InteractionRange_test.cpp new file mode 100644 index 00000000..0b9fdd4e --- /dev/null +++ b/tests/InteractionRange_test.cpp @@ -0,0 +1,36 @@ + + +#include "catch.hpp" + +#undef NDEBUG + +#include "InteractionRange.h" + +TEST_CASE( "InteractionRange", "[InteractionRange]" ) { + + RnaSequence r("test","AACCGGUU"); + + + SECTION("empty construction") { + + InteractionRange range( r, r ); + + REQUIRE( range.isSane() ); + REQUIRE( range.s1 == &r ); + REQUIRE( range.s2 == &r ); + REQUIRE( range.r1.isAscending() ); + REQUIRE_FALSE( range.r1.isDescending() ); + REQUIRE( range.r2.isDescending() ); + REQUIRE_FALSE( range.r2.isAscending() ); + REQUIRE( range.r1.from < r.size() ); + REQUIRE( (range.r1.to < r.size() || range.r1.to == RnaSequence::lastPos) ); + REQUIRE( range.r2.from < r.size() ); + REQUIRE( (range.r2.to < r.size() || range.r2.to == RnaSequence::lastPos) ); + + } + + // TODO init with interaction + + // TODO check operators + +} diff --git a/tests/Interaction_test.cpp b/tests/Interaction_test.cpp new file mode 100644 index 00000000..447ecde3 --- /dev/null +++ b/tests/Interaction_test.cpp @@ -0,0 +1,88 @@ + + +#include "catch.hpp" + +#undef NDEBUG + +#include "Interaction.h" +#include "InteractionRange.h" + +TEST_CASE( "Interaction", "[Interaction]" ) { + + RnaSequence r("test","AACCGGUU"); + + SECTION("empty construction") { + + Interaction inter( r, r ); + + REQUIRE( inter.isEmpty() ); + REQUIRE( inter.s1 == &r ); + REQUIRE( inter.s2 == &r ); + REQUIRE_FALSE( inter.isValid() ); + } + + SECTION("add base pairs and sort") { + + Interaction inter( r, r ); + + inter.basePairs.push_back( Interaction::BasePair( 1, 6 ) ); + REQUIRE_FALSE( inter.isEmpty() ); + REQUIRE( inter.isValid() ); + REQUIRE( Interaction::dotBracket(inter) == "(&)"); + REQUIRE( Interaction::dotBar(inter) == "2|&7|"); + + inter.basePairs.push_back( Interaction::BasePair( 0, 7 ) ); + REQUIRE_FALSE( inter.isEmpty() ); + REQUIRE_FALSE( inter.isValid() ); + + inter.sort(); + REQUIRE( inter.isValid() ); + REQUIRE( Interaction::dotBracket(inter) == "((&))"); + REQUIRE( Interaction::dotBar(inter) == "1||&7||"); + + inter.basePairs.push_back( Interaction::BasePair( 3, 4 ) ); + REQUIRE( inter.isValid() ); + REQUIRE( Interaction::dotBracket(inter) == "((.(&).))"); + REQUIRE( Interaction::dotBar(inter) == "1||.|&5|.||"); + + } + + + SECTION("init with interaction range") { + + InteractionRange range(r,r, IndexRange(0,2), IndexRange(7,5)); + REQUIRE( range.isSane() ); + + Interaction inter(range); + REQUIRE_FALSE( inter.isEmpty() ); + REQUIRE( inter.isValid() ); + REQUIRE( inter.basePairs.size() == 2 ); + REQUIRE( inter.basePairs.at(0).first == 0 ); + REQUIRE( inter.basePairs.at(0).second == 7 ); + REQUIRE( inter.basePairs.at(1).first == 2 ); + REQUIRE( inter.basePairs.at(1).second == 5 ); + + } + + SECTION("assign interaction range") { + + InteractionRange range(r,r, IndexRange(0,2), IndexRange(7,5)); + REQUIRE( range.isSane() ); + + // empty interaction + Interaction inter(r,r); + REQUIRE( inter.isEmpty() ); + + // assignment operator + inter = range; + REQUIRE_FALSE( inter.isEmpty() ); + REQUIRE( inter.isValid() ); + REQUIRE( inter.basePairs.size() == 2 ); + REQUIRE( inter.basePairs.at(0).first == 0 ); + REQUIRE( inter.basePairs.at(0).second == 7 ); + REQUIRE( inter.basePairs.at(1).first == 2 ); + REQUIRE( inter.basePairs.at(1).second == 5 ); + + } + +} diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 00000000..830e90b6 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,29 @@ + +# ensure serial test build and run +AUTOMAKE_OPTIONS = serial-tests + +# list of tests to run +TESTS = runTests + + +# the program to build +check_PROGRAMS = runTests + +# test sources +runTests_SOURCES = catch.hpp \ + AccessibilityConstraint_test.cpp \ + AccessibilityFromStream_test.cpp \ + IndexRange_test.cpp \ + IndexRangeList_test.cpp \ + Interaction_test.cpp \ + InteractionEnergyBasePair_test.cpp \ + InteractionRange_test.cpp \ + RnaSequence_test.cpp \ + OutputRangeOnly_test.cpp \ + runTests.cpp + +# add source objects for linking +runTests_LDFLAGS = `ls ../src/*.o | tr " " "\n" | grep -v "intaRNA" | grep -v "Command" | tr "\n" " "` @AM_LDFLAGS@ @LDFLAGS@ + +# add source include for compilation +runTests_CXXFLAGS = -I$(top_srcdir)/src @AM_CXXFLAGS@ @CXXFLAGS@ diff --git a/tests/OutputRangeOnly_test.cpp b/tests/OutputRangeOnly_test.cpp new file mode 100644 index 00000000..ccffc66b --- /dev/null +++ b/tests/OutputRangeOnly_test.cpp @@ -0,0 +1,60 @@ + +#include "catch.hpp" + +#undef NDEBUG + +#include "OutputHandlerRangeOnly.h" +#include + +/** + * Dummy class for testing the add result + */ +class RangeStore : public OutputHandler { +public: + + InteractionRange lastAdded; + + RangeStore( const RnaSequence& s ) : lastAdded(s,s) {} + + void add( const Interaction& i ) { + // reset, ignoring the given interaction + lastAdded = InteractionRange(*(i.s1),*(i.s2)); + } + void add( const InteractionRange& r ) { + // store the range + lastAdded = r; + } +}; + +TEST_CASE( "OutputHandlerRangeOnly", "[OutputHandlerRangeOnly]" ) { + + RnaSequence r("test","AACCGGUU"); + + RangeStore succOut(r); + + OutputHandlerRangeOnly out(succOut); + + Interaction i(r,r); + i.basePairs.push_back( Interaction::BasePair(0,7)); + i.basePairs.push_back( Interaction::BasePair(1,6)); + REQUIRE( i.isValid() ); + + InteractionRange ir(i); + + SECTION("add interaction") { + // ensure difference before add + REQUIRE( ((succOut.lastAdded < ir) || (ir < succOut.lastAdded))); + out.add(i); + // check equivalence after add + REQUIRE( (!(succOut.lastAdded < ir) && !(ir < succOut.lastAdded))); + } + + SECTION("add interaction range") { + // ensure difference before add + REQUIRE( ((succOut.lastAdded < ir) || (ir < succOut.lastAdded))); + out.add(ir); + // check equivalence after add + REQUIRE( (!(succOut.lastAdded < ir) && !(ir < succOut.lastAdded))); + } + +} diff --git a/tests/RnaSequence_test.cpp b/tests/RnaSequence_test.cpp new file mode 100644 index 00000000..2dd57384 --- /dev/null +++ b/tests/RnaSequence_test.cpp @@ -0,0 +1,46 @@ + +#include "catch.hpp" + +#undef NDEBUG + +#include "RnaSequence.h" + +TEST_CASE( "RnaSequence", "[RNAsequence]" ) { + + + SECTION( "sequence with non-ACGU" ) { + bool exceptionRaised = ! RnaSequence::isValidSequenceIUPAC("ACUGAC_error"); + REQUIRE( exceptionRaised ); + } + + SECTION( "getter", "[RNAsequence]" ) { + + std::string id= "test", seq="AAAUUUGGGCCC"; + + RnaSequence rna(id, seq); + + // check data access + REQUIRE( rna.size() == seq.size() ); + REQUIRE( rna.getId() == id ); + REQUIRE( rna.asString() == seq ); + REQUIRE( rna.asCodes().size() == seq.size() ); + } + + + SECTION( "areComplementary()" ) { + + std::string id= "test", seq="AAAUUUGGGCCC"; + + RnaSequence rna(id, seq); + + // check complementarity + REQUIRE( RnaSequence::areComplementary( rna, rna, 0, 3) ); + REQUIRE_FALSE( RnaSequence::areComplementary( rna, rna, 0, 6) ); + REQUIRE_FALSE( RnaSequence::areComplementary( rna, rna, 0, 9) ); + REQUIRE( RnaSequence::areComplementary( rna, rna, 3, 6) ); + REQUIRE_FALSE( RnaSequence::areComplementary( rna, rna, 3, 9) ); + REQUIRE( RnaSequence::areComplementary( rna, rna, 6, 9) ); + + } + +} diff --git a/tests/catch.hpp b/tests/catch.hpp new file mode 100644 index 00000000..a11ecce3 --- /dev/null +++ b/tests/catch.hpp @@ -0,0 +1,10524 @@ +/* + * Catch v1.5.7 + * Generated: 2016-09-27 10:45:46.824849 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + +#define TWOBLUECUBES_CATCH_HPP_INCLUDED + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// #included from: internal/catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic ignored "-Wglobal-constructors" +# pragma clang diagnostic ignored "-Wvariadic-macros" +# pragma clang diagnostic ignored "-Wc99-extensions" +# pragma clang diagnostic ignored "-Wunused-variable" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic ignored "-Wvariadic-macros" +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +#endif + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// #included from: internal/catch_notimplemented_exception.h +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED + +// #included from: catch_common.h +#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED + +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr +#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) + +#include +#include +#include + +// #included from: catch_compiler_capabilities.h +#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? +// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported +// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? +// CATCH_CONFIG_CPP11_OVERRIDE : is override supported? +// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) + +// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 + +#ifdef __cplusplus + +# if __cplusplus >= 201103L +# define CATCH_CPP11_OR_GREATER +# endif + +# if __cplusplus >= 201402L +# define CATCH_CPP14_OR_GREATER +# endif + +#endif + +#ifdef __clang__ + +# if __has_feature(cxx_nullptr) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if __has_feature(cxx_noexcept) +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# if defined(CATCH_CPP11_OR_GREATER) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +# endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Borland +#ifdef __BORLANDC__ + +#endif // __BORLANDC__ + +//////////////////////////////////////////////////////////////////////////////// +// EDG +#ifdef __EDG_VERSION__ + +#endif // __EDG_VERSION__ + +//////////////////////////////////////////////////////////////////////////////// +// Digital Mars +#ifdef __DMC__ + +#endif // __DMC__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) +# endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#if (_MSC_VER >= 1600) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// Use variadic macros if the compiler supports them +#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ + ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ + ( defined __GNUC__ && __GNUC__ >= 3 ) || \ + ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) + +#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS + +#endif + +// Use __COUNTER__ if the compiler supports it +#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ + ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \ + ( defined __clang__ && __clang_major__ >= 3 ) + +#define CATCH_INTERNAL_CONFIG_COUNTER + +#endif + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(CATCH_CPP11_OR_GREATER) + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# endif + +# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) +# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) +# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +# endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NULLPTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_IS_ENUM +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TUPLE +#endif +#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) +# define CATCH_CONFIG_VARIADIC_MACROS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_LONG_LONG +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_UNIQUE_PTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif + +// noexcept support: +#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) +# define CATCH_NOEXCEPT noexcept +# define CATCH_NOEXCEPT_IS(x) noexcept(x) +#else +# define CATCH_NOEXCEPT throw() +# define CATCH_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_NULL nullptr +#else +# define CATCH_NULL NULL +#endif + +// override support +#ifdef CATCH_CONFIG_CPP11_OVERRIDE +# define CATCH_OVERRIDE override +#else +# define CATCH_OVERRIDE +#endif + +// unique_ptr support +#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR +# define CATCH_AUTO_PTR( T ) std::unique_ptr +#else +# define CATCH_AUTO_PTR( T ) std::auto_ptr +#endif + +namespace Catch { + + struct IConfig; + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { +#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; +#else + NonCopyable( NonCopyable const& info ); + NonCopyable& operator = ( NonCopyable const& ); +#endif + + protected: + NonCopyable() {} + virtual ~NonCopyable(); + }; + + class SafeBool { + public: + typedef void (SafeBool::*type)() const; + + static type makeSafe( bool value ) { + return value ? &SafeBool::trueValue : 0; + } + private: + void trueValue() const {} + }; + + template + inline void deleteAll( ContainerT& container ) { + typename ContainerT::const_iterator it = container.begin(); + typename ContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete *it; + } + template + inline void deleteAllValues( AssociativeContainerT& container ) { + typename AssociativeContainerT::const_iterator it = container.begin(); + typename AssociativeContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete it->second; + } + + bool startsWith( std::string const& s, std::string const& prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + std::string trim( std::string const& str ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; + + struct SourceLineInfo { + + SourceLineInfo(); + SourceLineInfo( char const* _file, std::size_t _line ); + SourceLineInfo( SourceLineInfo const& other ); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SourceLineInfo( SourceLineInfo && ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo& operator = ( SourceLineInfo && ) = default; +# endif + bool empty() const; + bool operator == ( SourceLineInfo const& other ) const; + bool operator < ( SourceLineInfo const& other ) const; + + std::string file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // This is just here to avoid compiler warnings with macro constants and boolean literals + inline bool isTrue( bool value ){ return value; } + inline bool alwaysTrue() { return true; } + inline bool alwaysFalse() { return false; } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); + + void seedRng( IConfig const& config ); + unsigned int rngSeed(); + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() { + return std::string(); + } + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); + +#include + +namespace Catch { + + class NotImplementedException : public std::exception + { + public: + NotImplementedException( SourceLineInfo const& lineInfo ); + NotImplementedException( NotImplementedException const& ) {} + + virtual ~NotImplementedException() CATCH_NOEXCEPT {} + + virtual const char* what() const CATCH_NOEXCEPT; + + private: + std::string m_what; + SourceLineInfo m_lineInfo; + }; + +} // end namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) + +// #included from: internal/catch_context.h +#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED + +// #included from: catch_interfaces_generators.h +#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED + +#include + +namespace Catch { + + struct IGeneratorInfo { + virtual ~IGeneratorInfo(); + virtual bool moveNext() = 0; + virtual std::size_t getCurrentIndex() const = 0; + }; + + struct IGeneratorsForTest { + virtual ~IGeneratorsForTest(); + + virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; + virtual bool moveNext() = 0; + }; + + IGeneratorsForTest* createGeneratorsForTest(); + +} // end namespace Catch + +// #included from: catch_ptr.hpp +#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + // An intrusive reference counting smart pointer. + // T must implement addRef() and release() methods + // typically implementing the IShared interface + template + class Ptr { + public: + Ptr() : m_p( CATCH_NULL ){} + Ptr( T* p ) : m_p( p ){ + if( m_p ) + m_p->addRef(); + } + Ptr( Ptr const& other ) : m_p( other.m_p ){ + if( m_p ) + m_p->addRef(); + } + ~Ptr(){ + if( m_p ) + m_p->release(); + } + void reset() { + if( m_p ) + m_p->release(); + m_p = CATCH_NULL; + } + Ptr& operator = ( T* p ){ + Ptr temp( p ); + swap( temp ); + return *this; + } + Ptr& operator = ( Ptr const& other ){ + Ptr temp( other ); + swap( temp ); + return *this; + } + void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } + T* get() const{ return m_p; } + T& operator*() const { return *m_p; } + T* operator->() const { return m_p; } + bool operator !() const { return m_p == CATCH_NULL; } + operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } + + private: + T* m_p; + }; + + struct IShared : NonCopyable { + virtual ~IShared(); + virtual void addRef() const = 0; + virtual void release() const = 0; + }; + + template + struct SharedImpl : T { + + SharedImpl() : m_rc( 0 ){} + + virtual void addRef() const { + ++m_rc; + } + virtual void release() const { + if( --m_rc == 0 ) + delete this; + } + + mutable unsigned int m_rc; + }; + +} // end namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#include +#include +#include + +namespace Catch { + + class TestCase; + class Stream; + struct IResultCapture; + struct IRunner; + struct IGeneratorsForTest; + struct IConfig; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; + virtual bool advanceGeneratorsForCurrentTest() = 0; + virtual Ptr getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( Ptr const& config ) = 0; + }; + + IContext& getCurrentContext(); + IMutableContext& getCurrentMutableContext(); + void cleanUpContext(); + Stream createStream( std::string const& streamName ); + +} + +// #included from: internal/catch_test_registry.hpp +#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED + +// #included from: catch_interfaces_testcase.h +#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED + +#include + +namespace Catch { + + class TestSpec; + + struct ITestCase : IShared { + virtual void invoke () const = 0; + protected: + virtual ~ITestCase(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +namespace Catch { + +template +class MethodTestCase : public SharedImpl { + +public: + MethodTestCase( void (C::*method)() ) : m_method( method ) {} + + virtual void invoke() const { + C obj; + (obj.*m_method)(); + } + +private: + virtual ~MethodTestCase() {} + + void (C::*m_method)(); +}; + +typedef void(*TestFunction)(); + +struct NameAndDesc { + NameAndDesc( const char* _name = "", const char* _description= "" ) + : name( _name ), description( _description ) + {} + + const char* name; + const char* description; +}; + +void registerTestCase + ( ITestCase* testCase, + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ); + +struct AutoReg { + + AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + + template + AutoReg + ( void (C::*method)(), + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + registerTestCase + ( new MethodTestCase( method ), + className, + nameAndDesc, + lineInfo ); + } + + ~AutoReg(); + +private: + AutoReg( AutoReg const& ); + void operator= ( AutoReg const& ); +}; + +void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + namespace{ \ + struct TestName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ + } \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); + +#else + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ + static void TestName(); \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ + namespace{ \ + struct TestCaseName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ + } \ + void TestCaseName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); +#endif + +// #included from: internal/catch_capture.hpp +#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED + +// #included from: catch_result_builder.h +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED + +// #included from: catch_result_type.h +#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + inline bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + inline bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast( static_cast( lhs ) | static_cast( rhs ) ); + } + + inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch + +// #included from: catch_assertionresult.h +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED + +#include + +namespace Catch { + + struct AssertionInfo + { + AssertionInfo() {} + AssertionInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + std::string const& _capturedExpression, + ResultDisposition::Flags _resultDisposition ); + + std::string macroName; + SourceLineInfo lineInfo; + std::string capturedExpression; + ResultDisposition::Flags resultDisposition; + }; + + struct AssertionResultData + { + AssertionResultData() : resultType( ResultWas::Unknown ) {} + + std::string reconstructedExpression; + std::string message; + ResultWas::OfType resultType; + }; + + class AssertionResult { + public: + AssertionResult(); + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + ~AssertionResult(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionResult( AssertionResult const& ) = default; + AssertionResult( AssertionResult && ) = default; + AssertionResult& operator = ( AssertionResult const& ) = default; + AssertionResult& operator = ( AssertionResult && ) = default; +# endif + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + std::string getTestMacroName() const; + + protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +// #included from: catch_matchers.hpp +#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED + +namespace Catch { +namespace Matchers { + namespace Impl { + + namespace Generic { + template class AllOf; + template class AnyOf; + template class Not; + } + + template + struct Matcher : SharedImpl + { + typedef ExpressionT ExpressionType; + + virtual ~Matcher() {} + virtual Ptr clone() const = 0; + virtual bool match( ExpressionT const& expr ) const = 0; + virtual std::string toString() const = 0; + + Generic::AllOf operator && ( Matcher const& other ) const; + Generic::AnyOf operator || ( Matcher const& other ) const; + Generic::Not operator ! () const; + }; + + template + struct MatcherImpl : Matcher { + + virtual Ptr > clone() const { + return Ptr >( new DerivedT( static_cast( *this ) ) ); + } + }; + + namespace Generic { + template + class Not : public MatcherImpl, ExpressionT> { + public: + explicit Not( Matcher const& matcher ) : m_matcher(matcher.clone()) {} + Not( Not const& other ) : m_matcher( other.m_matcher ) {} + + virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE { + return !m_matcher->match( expr ); + } + + virtual std::string toString() const CATCH_OVERRIDE { + return "not " + m_matcher->toString(); + } + private: + Ptr< Matcher > m_matcher; + }; + + template + class AllOf : public MatcherImpl, ExpressionT> { + public: + + AllOf() {} + AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {} + + AllOf& add( Matcher const& matcher ) { + m_matchers.push_back( matcher.clone() ); + return *this; + } + virtual bool match( ExpressionT const& expr ) const + { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) + if( !m_matchers[i]->match( expr ) ) + return false; + return true; + } + virtual std::string toString() const { + std::ostringstream oss; + oss << "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + oss << " and "; + oss << m_matchers[i]->toString(); + } + oss << " )"; + return oss.str(); + } + + AllOf operator && ( Matcher const& other ) const { + AllOf allOfExpr( *this ); + allOfExpr.add( other ); + return allOfExpr; + } + + private: + std::vector > > m_matchers; + }; + + template + class AnyOf : public MatcherImpl, ExpressionT> { + public: + + AnyOf() {} + AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {} + + AnyOf& add( Matcher const& matcher ) { + m_matchers.push_back( matcher.clone() ); + return *this; + } + virtual bool match( ExpressionT const& expr ) const + { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) + if( m_matchers[i]->match( expr ) ) + return true; + return false; + } + virtual std::string toString() const { + std::ostringstream oss; + oss << "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + oss << " or "; + oss << m_matchers[i]->toString(); + } + oss << " )"; + return oss.str(); + } + + AnyOf operator || ( Matcher const& other ) const { + AnyOf anyOfExpr( *this ); + anyOfExpr.add( other ); + return anyOfExpr; + } + + private: + std::vector > > m_matchers; + }; + + } // namespace Generic + + template + Generic::AllOf Matcher::operator && ( Matcher const& other ) const { + Generic::AllOf allOfExpr; + allOfExpr.add( *this ); + allOfExpr.add( other ); + return allOfExpr; + } + + template + Generic::AnyOf Matcher::operator || ( Matcher const& other ) const { + Generic::AnyOf anyOfExpr; + anyOfExpr.add( *this ); + anyOfExpr.add( other ); + return anyOfExpr; + } + + template + Generic::Not Matcher::operator ! () const { + return Generic::Not( *this ); + } + + namespace StdString { + + inline std::string makeString( std::string const& str ) { return str; } + inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); } + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + + } + std::string toStringSuffix() const + { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : ""; + } + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct Equals : MatcherImpl { + Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) + : m_data( str, caseSensitivity ) + {} + Equals( Equals const& other ) : m_data( other.m_data ){} + + virtual ~Equals(); + + virtual bool match( std::string const& expr ) const { + return m_data.m_str == m_data.adjustString( expr );; + } + virtual std::string toString() const { + return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); + } + + CasedString m_data; + }; + + struct Contains : MatcherImpl { + Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) + : m_data( substr, caseSensitivity ){} + Contains( Contains const& other ) : m_data( other.m_data ){} + + virtual ~Contains(); + + virtual bool match( std::string const& expr ) const { + return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos; + } + virtual std::string toString() const { + return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); + } + + CasedString m_data; + }; + + struct StartsWith : MatcherImpl { + StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) + : m_data( substr, caseSensitivity ){} + + StartsWith( StartsWith const& other ) : m_data( other.m_data ){} + + virtual ~StartsWith(); + + virtual bool match( std::string const& expr ) const { + return startsWith( m_data.adjustString( expr ), m_data.m_str ); + } + virtual std::string toString() const { + return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); + } + + CasedString m_data; + }; + + struct EndsWith : MatcherImpl { + EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) + : m_data( substr, caseSensitivity ){} + EndsWith( EndsWith const& other ) : m_data( other.m_data ){} + + virtual ~EndsWith(); + + virtual bool match( std::string const& expr ) const { + return endsWith( m_data.adjustString( expr ), m_data.m_str ); + } + virtual std::string toString() const { + return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); + } + + CasedString m_data; + }; + } // namespace StdString + } // namespace Impl + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + template + inline Impl::Generic::Not Not( Impl::Matcher const& m ) { + return Impl::Generic::Not( m ); + } + + template + inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1, + Impl::Matcher const& m2 ) { + return Impl::Generic::AllOf().add( m1 ).add( m2 ); + } + template + inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1, + Impl::Matcher const& m2, + Impl::Matcher const& m3 ) { + return Impl::Generic::AllOf().add( m1 ).add( m2 ).add( m3 ); + } + template + inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1, + Impl::Matcher const& m2 ) { + return Impl::Generic::AnyOf().add( m1 ).add( m2 ); + } + template + inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1, + Impl::Matcher const& m2, + Impl::Matcher const& m3 ) { + return Impl::Generic::AnyOf().add( m1 ).add( m2 ).add( m3 ); + } + + inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { + return Impl::StdString::Equals( str, caseSensitivity ); + } + inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { + return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity ); + } + inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { + return Impl::StdString::Contains( substr, caseSensitivity ); + } + inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { + return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity ); + } + inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) { + return Impl::StdString::StartsWith( substr ); + } + inline Impl::StdString::StartsWith StartsWith( const char* substr ) { + return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) ); + } + inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) { + return Impl::StdString::EndsWith( substr ); + } + inline Impl::StdString::EndsWith EndsWith( const char* substr ) { + return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) ); + } + +} // namespace Matchers + +using namespace Matchers; + +} // namespace Catch + +namespace Catch { + + struct TestFailureException{}; + + template class ExpressionLhs; + + struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; + + struct CopyableStream { + CopyableStream() {} + CopyableStream( CopyableStream const& other ) { + oss << other.oss.str(); + } + CopyableStream& operator=( CopyableStream const& other ) { + oss.str(""); + oss << other.oss.str(); + return *this; + } + std::ostringstream oss; + }; + + class ResultBuilder { + public: + ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg = "" ); + + template + ExpressionLhs operator <= ( T const& operand ); + ExpressionLhs operator <= ( bool value ); + + template + ResultBuilder& operator << ( T const& value ) { + m_stream.oss << value; + return *this; + } + + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); + + ResultBuilder& setResultType( ResultWas::OfType result ); + ResultBuilder& setResultType( bool result ); + ResultBuilder& setLhs( std::string const& lhs ); + ResultBuilder& setRhs( std::string const& rhs ); + ResultBuilder& setOp( std::string const& op ); + + void endExpression(); + + std::string reconstructExpression() const; + AssertionResult build() const; + + void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); + void captureResult( ResultWas::OfType resultType ); + void captureExpression(); + void captureExpectedException( std::string const& expectedMessage ); + void captureExpectedException( Matchers::Impl::Matcher const& matcher ); + void handleResult( AssertionResult const& result ); + void react(); + bool shouldDebugBreak() const; + bool allowThrows() const; + + private: + AssertionInfo m_assertionInfo; + AssertionResultData m_data; + struct ExprComponents { + ExprComponents() : testFalse( false ) {} + bool testFalse; + std::string lhs, rhs, op; + } m_exprComponents; + CopyableStream m_stream; + + bool m_shouldDebugBreak; + bool m_shouldThrow; + }; + +} // namespace Catch + +// Include after due to circular dependency: +// #included from: catch_expression_lhs.hpp +#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED + +// #included from: catch_evaluate.hpp +#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#endif + +#include + +namespace Catch { +namespace Internal { + + enum Operator { + IsEqualTo, + IsNotEqualTo, + IsLessThan, + IsGreaterThan, + IsLessThanOrEqualTo, + IsGreaterThanOrEqualTo + }; + + template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; + template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; + template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; + + template + inline T& opCast(T const& t) { return const_cast(t); } + +// nullptr_t support based on pull request #154 from Konstantin Baumann +#ifdef CATCH_CONFIG_CPP11_NULLPTR + inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } +#endif // CATCH_CONFIG_CPP11_NULLPTR + + // So the compare overloads can be operator agnostic we convey the operator as a template + // enum, which is used to specialise an Evaluator for doing the comparison. + template + class Evaluator{}; + + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs) { + return bool( opCast( lhs ) == opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) != opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) < opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) > opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) >= opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) <= opCast( rhs ) ); + } + }; + + template + bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // This level of indirection allows us to specialise for integer types + // to avoid signed/ unsigned warnings + + // "base" overload + template + bool compare( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // unsigned X to int + template bool compare( unsigned int lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // unsigned X to long + template bool compare( unsigned int lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // int to unsigned X + template bool compare( int lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // long to unsigned X + template bool compare( long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long (when comparing against NULL) + template bool compare( long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + + // pointer to int (when comparing against NULL) + template bool compare( int lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, int rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG + // long long to unsigned X + template bool compare( long long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // unsigned long long to X + template bool compare( unsigned long long lhs, int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long long (when comparing against NULL) + template bool compare( long long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } +#endif // CATCH_CONFIG_CPP11_LONG_LONG + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + // pointer to nullptr_t (when comparing against nullptr) + template bool compare( std::nullptr_t, T* rhs ) { + return Evaluator::evaluate( nullptr, rhs ); + } + template bool compare( T* lhs, std::nullptr_t ) { + return Evaluator::evaluate( lhs, nullptr ); + } +#endif // CATCH_CONFIG_CPP11_NULLPTR + +} // end of namespace Internal +} // end of namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// #included from: catch_tostring.h +#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED + +#include +#include +#include +#include +#include + +#ifdef __OBJC__ +// #included from: catch_objc_arc.hpp +#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED + +#import + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +#endif + +#ifdef CATCH_CONFIG_CPP11_TUPLE +#include +#endif + +#ifdef CATCH_CONFIG_CPP11_IS_ENUM +#include +#endif + +namespace Catch { + +// Why we're here. +template +std::string toString( T const& value ); + +// Built in overloads + +std::string toString( std::string const& value ); +std::string toString( std::wstring const& value ); +std::string toString( const char* const value ); +std::string toString( char* const value ); +std::string toString( const wchar_t* const value ); +std::string toString( wchar_t* const value ); +std::string toString( int value ); +std::string toString( unsigned long value ); +std::string toString( unsigned int value ); +std::string toString( const double value ); +std::string toString( const float value ); +std::string toString( bool value ); +std::string toString( char value ); +std::string toString( signed char value ); +std::string toString( unsigned char value ); + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ); +std::string toString( unsigned long long value ); +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ); +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ); + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); + std::string toString( NSObject* const& nsObject ); +#endif + +namespace Detail { + + extern const std::string unprintableString; + + struct BorgType { + template BorgType( T const& ); + }; + + struct TrueType { char sizer[1]; }; + struct FalseType { char sizer[2]; }; + + TrueType& testStreamable( std::ostream& ); + FalseType testStreamable( FalseType ); + + FalseType operator<<( std::ostream const&, BorgType const& ); + + template + struct IsStreamInsertable { + static std::ostream &s; + static T const&t; + enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; + }; + +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template::value + > + struct EnumStringMaker + { + static std::string convert( T const& ) { return unprintableString; } + }; + + template + struct EnumStringMaker + { + static std::string convert( T const& v ) + { + return ::Catch::toString( + static_cast::type>(v) + ); + } + }; +#endif + template + struct StringMakerBase { +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template + static std::string convert( T const& v ) + { + return EnumStringMaker::convert( v ); + } +#else + template + static std::string convert( T const& ) { return unprintableString; } +#endif + }; + + template<> + struct StringMakerBase { + template + static std::string convert( T const& _value ) { + std::ostringstream oss; + oss << _value; + return oss.str(); + } + }; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template + inline std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + +} // end namespace Detail + +template +struct StringMaker : + Detail::StringMakerBase::value> {}; + +template +struct StringMaker { + template + static std::string convert( U* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +template +struct StringMaker { + static std::string convert( R C::* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ); +} + +//template +//struct StringMaker > { +// static std::string convert( std::vector const& v ) { +// return Detail::rangeToString( v.begin(), v.end() ); +// } +//}; + +template +std::string toString( std::vector const& v ) { + return Detail::rangeToString( v.begin(), v.end() ); +} + +#ifdef CATCH_CONFIG_CPP11_TUPLE + +// toString for tuples +namespace TupleDetail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size::value) + > + struct ElementPrinter { + static void print( const Tuple& tuple, std::ostream& os ) + { + os << ( N ? ", " : " " ) + << Catch::toString(std::get(tuple)); + ElementPrinter::print(tuple,os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct ElementPrinter { + static void print( const Tuple&, std::ostream& ) {} + }; + +} + +template +struct StringMaker> { + + static std::string convert( const std::tuple& tuple ) + { + std::ostringstream os; + os << '{'; + TupleDetail::ElementPrinter>::print( tuple, os ); + os << " }"; + return os.str(); + } +}; +#endif // CATCH_CONFIG_CPP11_TUPLE + +namespace Detail { + template + std::string makeString( T const& value ) { + return StringMaker::convert( value ); + } +} // end namespace Detail + +/// \brief converts any type to a string +/// +/// The default template forwards on to ostringstream - except when an +/// ostringstream overload does not exist - in which case it attempts to detect +/// that and writes {?}. +/// Overload (not specialise) this template for custom typs that you don't want +/// to provide an ostream overload for. +template +std::string toString( T const& value ) { + return StringMaker::convert( value ); +} + + namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ) { + std::ostringstream oss; + oss << "{ "; + if( first != last ) { + oss << Catch::toString( *first ); + for( ++first ; first != last ; ++first ) + oss << ", " << Catch::toString( *first ); + } + oss << " }"; + return oss.str(); + } +} + +} // end namespace Catch + +namespace Catch { + +// Wraps the LHS of an expression and captures the operator and RHS (if any) - +// wrapping them all in a ResultBuilder object +template +class ExpressionLhs { + ExpressionLhs& operator = ( ExpressionLhs const& ); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + ExpressionLhs& operator = ( ExpressionLhs && ) = delete; +# endif + +public: + ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + ExpressionLhs( ExpressionLhs const& ) = default; + ExpressionLhs( ExpressionLhs && ) = default; +# endif + + template + ResultBuilder& operator == ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + ResultBuilder& operator != ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + ResultBuilder& operator < ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + ResultBuilder& operator > ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + ResultBuilder& operator <= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + ResultBuilder& operator >= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + ResultBuilder& operator == ( bool rhs ) { + return captureExpression( rhs ); + } + + ResultBuilder& operator != ( bool rhs ) { + return captureExpression( rhs ); + } + + void endExpression() { + bool value = m_lhs ? true : false; + m_rb + .setLhs( Catch::toString( value ) ) + .setResultType( value ) + .endExpression(); + } + + // Only simple binary expressions are allowed on the LHS. + // If more complex compositions are required then place the sub expression in parentheses + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); + +private: + template + ResultBuilder& captureExpression( RhsT const& rhs ) { + return m_rb + .setResultType( Internal::compare( m_lhs, rhs ) ) + .setLhs( Catch::toString( m_lhs ) ) + .setRhs( Catch::toString( rhs ) ) + .setOp( Internal::OperatorTraits::getName() ); + } + +private: + ResultBuilder& m_rb; + T m_lhs; +}; + +} // end namespace Catch + + +namespace Catch { + + template + inline ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { + return ExpressionLhs( *this, operand ); + } + + inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { + return ExpressionLhs( *this, value ); + } + +} // namespace Catch + +// #included from: catch_message.h +#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED + +#include + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + SourceLineInfo lineInfo; + ResultWas::OfType type; + std::string message; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const { + return sequence == other.sequence; + } + bool operator < ( MessageInfo const& other ) const { + return sequence < other.sequence; + } + private: + static unsigned int globalCount; + }; + + struct MessageBuilder { + MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + : m_info( macroName, lineInfo, type ) + {} + + template + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + std::ostringstream m_stream; + }; + + class ScopedMessage { + public: + ScopedMessage( MessageBuilder const& builder ); + ScopedMessage( ScopedMessage const& other ); + ~ScopedMessage(); + + MessageInfo m_info; + }; + +} // end namespace Catch + +// #included from: catch_interfaces_capture.h +#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED + +#include + +namespace Catch { + + class TestCase; + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + class ScopedMessageBuilder; + struct Counts; + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual void assertionEnded( AssertionResult const& result ) = 0; + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + + virtual void handleFatalErrorCondition( std::string const& message ) = 0; + }; + + IResultCapture& getResultCapture(); +} + +// #included from: catch_debugger.h +#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED + +// #included from: catch_platform.h +#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED + +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +#define CATCH_PLATFORM_MAC +#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#define CATCH_PLATFORM_IPHONE +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#define CATCH_PLATFORM_WINDOWS +#endif + +#include + +namespace Catch{ + + bool isDebuggerActive(); + void writeToDebugConsole( std::string const& text ); +} + +#ifdef CATCH_PLATFORM_MAC + + // The following code snippet based on: + // http://cocoawithlove.com/2008/03/break-into-debugger.html + #ifdef DEBUG + #if defined(__ppc64__) || defined(__ppc__) + #define CATCH_BREAK_INTO_DEBUGGER() \ + if( Catch::isDebuggerActive() ) { \ + __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ + : : : "memory","r0","r3","r4" ); \ + } + #else + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} + #endif + #endif + +#elif defined(_MSC_VER) + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); } +#endif + +#ifndef CATCH_BREAK_INTO_DEBUGGER +#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); +#endif + +// #included from: catch_interfaces_runner.h +#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED + +namespace Catch { + class TestCase; + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// In the event of a failure works out if the debugger needs to be invoked +// and/or an exception thrown and takes appropriate action. +// This needs to be done as a macro so the debugger will stop in the user +// source code rather than in Catch library code +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ + resultBuilder.react(); + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + try { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + ( __catchResult <= expr ).endExpression(); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::isTrue( false && !!(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ + INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ + if( Catch::getResultCapture().getLastResult()->succeeded() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ + INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ + if( !Catch::getResultCapture().getLastResult()->succeeded() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + try { \ + expr; \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \ + if( __catchResult.allowThrows() ) \ + try { \ + expr; \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( ... ) { \ + __catchResult.captureExpectedException( matcher ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ + if( __catchResult.allowThrows() ) \ + try { \ + expr; \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( exceptionType ) { \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#else + #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << log + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( log, macroName ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ + try { \ + std::string matcherAsString = (matcher).toString(); \ + __catchResult \ + .setLhs( Catch::toString( arg ) ) \ + .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ + .setOp( "matches" ) \ + .setResultType( (matcher).match( arg ) ); \ + __catchResult.captureExpression(); \ + } catch( ... ) { \ + __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +// #included from: internal/catch_section.h +#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED + +// #included from: catch_section_info.h +#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED + +// #included from: catch_totals.hpp +#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED + +#include + +namespace Catch { + + struct Counts { + Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} + + Counts operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + Counts& operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t total() const { + return passed + failed + failedButOk; + } + bool allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool allOk() const { + return failed == 0; + } + + std::size_t passed; + std::size_t failed; + std::size_t failedButOk; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + + Totals& operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Counts assertions; + Counts testCases; + }; +} + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description = std::string() ); + + std::string name; + std::string description; + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) + : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) + {} + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +// #included from: catch_timer.h +#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED + +#ifdef CATCH_PLATFORM_WINDOWS +typedef unsigned long long uint64_t; +#else +#include +#endif + +namespace Catch { + + class Timer { + public: + Timer() : m_ticks( 0 ) {} + void start(); + unsigned int getElapsedMicroseconds() const; + unsigned int getElapsedMilliseconds() const; + double getElapsedSeconds() const; + + private: + uint64_t m_ticks; + }; + +} // namespace Catch + +#include + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_SECTION( ... ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) +#else + #define INTERNAL_CATCH_SECTION( name, desc ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) +#endif + +// #included from: internal/catch_generators.hpp +#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + +template +struct IGenerator { + virtual ~IGenerator() {} + virtual T getValue( std::size_t index ) const = 0; + virtual std::size_t size () const = 0; +}; + +template +class BetweenGenerator : public IGenerator { +public: + BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} + + virtual T getValue( std::size_t index ) const { + return m_from+static_cast( index ); + } + + virtual std::size_t size() const { + return static_cast( 1+m_to-m_from ); + } + +private: + + T m_from; + T m_to; +}; + +template +class ValuesGenerator : public IGenerator { +public: + ValuesGenerator(){} + + void add( T value ) { + m_values.push_back( value ); + } + + virtual T getValue( std::size_t index ) const { + return m_values[index]; + } + + virtual std::size_t size() const { + return m_values.size(); + } + +private: + std::vector m_values; +}; + +template +class CompositeGenerator { +public: + CompositeGenerator() : m_totalSize( 0 ) {} + + // *** Move semantics, similar to auto_ptr *** + CompositeGenerator( CompositeGenerator& other ) + : m_fileInfo( other.m_fileInfo ), + m_totalSize( 0 ) + { + move( other ); + } + + CompositeGenerator& setFileInfo( const char* fileInfo ) { + m_fileInfo = fileInfo; + return *this; + } + + ~CompositeGenerator() { + deleteAll( m_composed ); + } + + operator T () const { + size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); + + typename std::vector*>::const_iterator it = m_composed.begin(); + typename std::vector*>::const_iterator itEnd = m_composed.end(); + for( size_t index = 0; it != itEnd; ++it ) + { + const IGenerator* generator = *it; + if( overallIndex >= index && overallIndex < index + generator->size() ) + { + return generator->getValue( overallIndex-index ); + } + index += generator->size(); + } + CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); + return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so + } + + void add( const IGenerator* generator ) { + m_totalSize += generator->size(); + m_composed.push_back( generator ); + } + + CompositeGenerator& then( CompositeGenerator& other ) { + move( other ); + return *this; + } + + CompositeGenerator& then( T value ) { + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( value ); + add( valuesGen ); + return *this; + } + +private: + + void move( CompositeGenerator& other ) { + std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); + m_totalSize += other.m_totalSize; + other.m_composed.clear(); + } + + std::vector*> m_composed; + std::string m_fileInfo; + size_t m_totalSize; +}; + +namespace Generators +{ + template + CompositeGenerator between( T from, T to ) { + CompositeGenerator generators; + generators.add( new BetweenGenerator( from, to ) ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3 ){ + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3, T val4 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + valuesGen->add( val4 ); + generators.add( valuesGen ); + return generators; + } + +} // end namespace Generators + +using namespace Generators; + +} // end namespace Catch + +#define INTERNAL_CATCH_LINESTR2( line ) #line +#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) + +#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) + +// #included from: internal/catch_interfaces_exception.h +#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED + +#include +#include + +// #included from: catch_interfaces_registry_hub.h +#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED + +#include + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; + virtual void registerListener( Ptr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + }; + + IRegistryHub& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +namespace Catch { + + typedef std::string(*exceptionTranslateFunction)(); + + struct IExceptionTranslator; + typedef std::vector ExceptionTranslators; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { + try { + if( it == itEnd ) + throw; + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// #included from: internal/catch_approx.hpp +#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED + +#include +#include + +namespace Catch { +namespace Detail { + + class Approx { + public: + explicit Approx ( double value ) + : m_epsilon( std::numeric_limits::epsilon()*100 ), + m_scale( 1.0 ), + m_value( value ) + {} + + Approx( Approx const& other ) + : m_epsilon( other.m_epsilon ), + m_scale( other.m_scale ), + m_value( other.m_value ) + {} + + static Approx custom() { + return Approx( 0 ); + } + + Approx operator()( double value ) { + Approx approx( value ); + approx.epsilon( m_epsilon ); + approx.scale( m_scale ); + return approx; + } + + friend bool operator == ( double lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) ); + } + + friend bool operator == ( Approx const& lhs, double rhs ) { + return operator==( rhs, lhs ); + } + + friend bool operator != ( double lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + friend bool operator != ( Approx const& lhs, double rhs ) { + return !operator==( rhs, lhs ); + } + + Approx& epsilon( double newEpsilon ) { + m_epsilon = newEpsilon; + return *this; + } + + Approx& scale( double newScale ) { + m_scale = newScale; + return *this; + } + + std::string toString() const { + std::ostringstream oss; + oss << "Approx( " << Catch::toString( m_value ) << " )"; + return oss.str(); + } + + private: + double m_epsilon; + double m_scale; + double m_value; + }; +} + +template<> +inline std::string toString( Detail::Approx const& value ) { + return value.toString(); +} + +} // end namespace Catch + +// #included from: internal/catch_interfaces_tag_alias_registry.h +#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED + +// #included from: catch_tag_alias.h +#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED + +#include + +namespace Catch { + + struct TagAlias { + TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} + + std::string tag; + SourceLineInfo lineInfo; + }; + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } +// #included from: catch_option.hpp +#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED + +namespace Catch { + + // An optional type + template + class Option { + public: + Option() : nullableValue( CATCH_NULL ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = CATCH_NULL; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != CATCH_NULL; } + bool none() const { return nullableValue == CATCH_NULL; } + + bool operator !() const { return nullableValue == CATCH_NULL; } + operator SafeBool::type() const { + return SafeBool::makeSafe( some() ); + } + + private: + T* nullableValue; + char storage[sizeof(T)]; + }; + +} // end namespace Catch + +namespace Catch { + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + virtual Option find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// #included from: internal/catch_test_case_info.h +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED + +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestCase; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ); + + TestCaseInfo( TestCaseInfo const& other ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string name; + std::string className; + std::string description; + std::set tags; + std::set lcaseTags; + std::string tagsAsString; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestCase* testCase, TestCaseInfo const& info ); + TestCase( TestCase const& other ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + void swap( TestCase& other ); + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + TestCase& operator = ( TestCase const& other ); + + private: + Ptr test; + }; + + TestCase makeTestCase( ITestCase* testCase, + std::string const& className, + std::string const& name, + std::string const& description, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + +#ifdef __OBJC__ +// #included from: internal/catch_objc.hpp +#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED + +#import + +#include + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public SharedImpl { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline size_t registerTestMethods() { + size_t noTestMethods = 0; + int noClasses = objc_getClassList( CATCH_NULL, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + template + struct StringHolder : MatcherImpl{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + NSString* m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + virtual std::string toString() const { + return "equals string: " + Catch::toString( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + virtual std::string toString() const { + return "contains string: " + Catch::toString( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + virtual std::string toString() const { + return "starts with: " + Catch::toString( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( ExpressionType const& str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + virtual std::string toString() const { + return "ends with: " + Catch::toString( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_TEST_CASE( name, desc )\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ +{\ +return @ name; \ +}\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ +{ \ +return @ desc; \ +} \ +-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) + +#endif + +#ifdef CATCH_IMPL +// #included from: internal/catch_impl.hpp +#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED + +// Collect all the implementation files together here +// These are the equivalent of what would usually be cpp files + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// #included from: ../catch_session.hpp +#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED + +// #included from: internal/catch_commandline.hpp +#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED + +// #included from: catch_config.hpp +#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED + +// #included from: catch_test_spec_parser.hpp +#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// #included from: catch_test_spec.hpp +#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// #included from: catch_wildcard_pattern.hpp +#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_wildcard( NoWildcard ), + m_pattern( adjustCase( pattern ) ) + { + if( startsWith( m_pattern, "*" ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, "*" ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); + } + } + virtual ~WildcardPattern(); + virtual bool matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == adjustCase( str ); + case WildcardAtStart: + return endsWith( adjustCase( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( adjustCase( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( adjustCase( str ), m_pattern ); + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + throw std::logic_error( "Unknown enum" ); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + } + private: + std::string adjustCase( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; + } + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard; + std::string m_pattern; + }; +} + +#include +#include + +namespace Catch { + + class TestSpec { + struct Pattern : SharedImpl<> { + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + }; + class NamePattern : public Pattern { + public: + NamePattern( std::string const& name ) + : m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + virtual ~NamePattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( toLower( testCase.name ) ); + } + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} + virtual ~TagPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); + } + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} + virtual ~ExcludedPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } + private: + Ptr m_underlyingPattern; + }; + + struct Filter { + std::vector > m_patterns; + + bool matches( TestCaseInfo const& testCase ) const { + // All patterns in a filter must match for the filter to be a match + for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { + if( !(*it)->matches( testCase ) ) + return false; + } + return true; + } + }; + + public: + bool hasFilters() const { + return !m_filters.empty(); + } + bool matches( TestCaseInfo const& testCase ) const { + // A TestSpec matches if any filter matches + for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) + if( it->matches( testCase ) ) + return true; + return false; + } + + private: + std::vector m_filters; + + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag }; + Mode m_mode; + bool m_exclusion; + std::size_t m_start, m_pos; + std::string m_arg; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + + TestSpecParser& parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases( arg ); + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + visitChar( m_arg[m_pos] ); + if( m_mode == Name ) + addPattern(); + return *this; + } + TestSpec testSpec() { + addFilter(); + return m_testSpec; + } + private: + void visitChar( char c ) { + if( m_mode == None ) { + switch( c ) { + case ' ': return; + case '~': m_exclusion = true; return; + case '[': return startNewMode( Tag, ++m_pos ); + case '"': return startNewMode( QuotedName, ++m_pos ); + default: startNewMode( Name, m_pos ); break; + } + } + if( m_mode == Name ) { + if( c == ',' ) { + addPattern(); + addFilter(); + } + else if( c == '[' ) { + if( subString() == "exclude:" ) + m_exclusion = true; + else + addPattern(); + startNewMode( Tag, ++m_pos ); + } + } + else if( m_mode == QuotedName && c == '"' ) + addPattern(); + else if( m_mode == Tag && c == ']' ) + addPattern(); + } + void startNewMode( Mode mode, std::size_t start ) { + m_mode = mode; + m_start = start; + } + std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } + template + void addPattern() { + std::string token = subString(); + if( startsWith( token, "exclude:" ) ) { + m_exclusion = true; + token = token.substr( 8 ); + } + if( !token.empty() ) { + Ptr pattern = new T( token ); + if( m_exclusion ) + pattern = new TestSpec::ExcludedPattern( pattern ); + m_currentFilter.m_patterns.push_back( pattern ); + } + m_exclusion = false; + m_mode = None; + } + void addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + }; + inline TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// #included from: catch_interfaces_config.h +#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct Verbosity { enum Level { + NoOutput = 0, + Quiet, + Normal + }; }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + + class TestSpec; + + struct IConfig : IShared { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + }; +} + +// #included from: catch_stream.h +#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED + +// #included from: catch_streambuf.h +#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED + +#include + +namespace Catch { + + class StreamBufBase : public std::streambuf { + public: + virtual ~StreamBufBase() CATCH_NOEXCEPT; + }; +} + +#include +#include +#include + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + + struct IStream { + virtual ~IStream() CATCH_NOEXCEPT; + virtual std::ostream& stream() const = 0; + }; + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( std::string const& filename ); + virtual ~FileStream() CATCH_NOEXCEPT; + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + CoutStream(); + virtual ~CoutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + class DebugOutStream : public IStream { + CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream(); + virtual ~DebugOutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; +} + +#include +#include +#include +#include +#include + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct ConfigData { + + ConfigData() + : listTests( false ), + listTags( false ), + listReporters( false ), + listTestNamesOnly( false ), + showSuccessfulTests( false ), + shouldDebugBreak( false ), + noThrow( false ), + showHelp( false ), + showInvisibles( false ), + filenamesAsTags( false ), + abortAfter( -1 ), + rngSeed( 0 ), + verbosity( Verbosity::Normal ), + warnings( WarnAbout::Nothing ), + showDurations( ShowDurations::DefaultForReporter ), + runOrder( RunTests::InDeclarationOrder ), + useColour( UseColour::Auto ) + {} + + bool listTests; + bool listTags; + bool listReporters; + bool listTestNamesOnly; + + bool showSuccessfulTests; + bool shouldDebugBreak; + bool noThrow; + bool showHelp; + bool showInvisibles; + bool filenamesAsTags; + + int abortAfter; + unsigned int rngSeed; + + Verbosity::Level verbosity; + WarnAbout::What warnings; + ShowDurations::OrNot showDurations; + RunTests::InWhatOrder runOrder; + UseColour::YesOrNo useColour; + + std::string outputFilename; + std::string name; + std::string processName; + + std::vector reporterNames; + std::vector testsOrTags; + }; + + class Config : public SharedImpl { + private: + Config( Config const& other ); + Config& operator = ( Config const& other ); + virtual void dummy(); + public: + + Config() + {} + + Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + if( !data.testsOrTags.empty() ) { + TestSpecParser parser( ITagAliasRegistry::get() ); + for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) + parser.parse( data.testsOrTags[i] ); + m_testSpec = parser.testSpec(); + } + } + + virtual ~Config() { + } + + std::string const& getFilename() const { + return m_data.outputFilename ; + } + + bool listTests() const { return m_data.listTests; } + bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool listTags() const { return m_data.listTags; } + bool listReporters() const { return m_data.listReporters; } + + std::string getProcessName() const { return m_data.processName; } + + bool shouldDebugBreak() const { return m_data.shouldDebugBreak; } + + std::vector getReporterNames() const { return m_data.reporterNames; } + + int abortAfter() const { return m_data.abortAfter; } + + TestSpec const& testSpec() const { return m_testSpec; } + + bool showHelp() const { return m_data.showHelp; } + bool showInvisibles() const { return m_data.showInvisibles; } + + // IConfig interface + virtual bool allowThrows() const { return !m_data.noThrow; } + virtual std::ostream& stream() const { return m_stream->stream(); } + virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } + virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; } + virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } + virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } + virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; } + virtual unsigned int rngSeed() const { return m_data.rngSeed; } + virtual UseColour::YesOrNo useColour() const { return m_data.useColour; } + + private: + + IStream const* openStream() { + if( m_data.outputFilename.empty() ) + return new CoutStream(); + else if( m_data.outputFilename[0] == '%' ) { + if( m_data.outputFilename == "%debug" ) + return new DebugOutStream(); + else + throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); + } + else + return new FileStream( m_data.outputFilename ); + } + ConfigData m_data; + + CATCH_AUTO_PTR( IStream const ) m_stream; + TestSpec m_testSpec; + }; + +} // end namespace Catch + +// #included from: catch_clara.h +#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH +#undef CLARA_CONFIG_CONSOLE_WIDTH +#endif +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +// Declare Clara inside the Catch namespace +#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { +// #included from: ../external/clara.h + +// Version 0.0.2.4 + +// Only use header guard if we are not using an outer namespace +#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) + +#ifndef STITCH_CLARA_OPEN_NAMESPACE +#define TWOBLUECUBES_CLARA_H_INCLUDED +#define STITCH_CLARA_OPEN_NAMESPACE +#define STITCH_CLARA_CLOSE_NAMESPACE +#else +#define STITCH_CLARA_CLOSE_NAMESPACE } +#endif + +#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE + +// ----------- #included from tbc_text_format.h ----------- + +// Only use header guard if we are not using an outer namespace +#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) +#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +#define TBC_TEXT_FORMAT_H_INCLUDED +#endif + +#include +#include +#include +#include + +// Use optional outer namespace +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ), + tabChar( '\t' ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + char tabChar; // If this char is seen the indent is changed to current pos + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + std::string wrappableChars = " [({.,/|\\-"; + std::size_t indent = _attr.initialIndent != std::string::npos + ? _attr.initialIndent + : _attr.indent; + std::string remainder = _str; + + while( !remainder.empty() ) { + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + std::size_t tabPos = std::string::npos; + std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); + std::size_t pos = remainder.find_first_of( '\n' ); + if( pos <= width ) { + width = pos; + } + pos = remainder.find_last_of( _attr.tabChar, width ); + if( pos != std::string::npos ) { + tabPos = pos; + if( remainder[width] == '\n' ) + width--; + remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); + } + + if( width == remainder.size() ) { + spliceLine( indent, remainder, width ); + } + else if( remainder[width] == '\n' ) { + spliceLine( indent, remainder, width ); + if( width <= 1 || remainder.size() != 1 ) + remainder = remainder.substr( 1 ); + indent = _attr.indent; + } + else { + pos = remainder.find_last_of( wrappableChars, width ); + if( pos != std::string::npos && pos > 0 ) { + spliceLine( indent, remainder, pos ); + if( remainder[0] == ' ' ) + remainder = remainder.substr( 1 ); + } + else { + spliceLine( indent, remainder, width-1 ); + lines.back() += "-"; + } + if( lines.size() == 1 ) + indent = _attr.indent; + if( tabPos != std::string::npos ) + indent += tabPos; + } + } + } + + void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { + lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); + _remainder = _remainder.substr( _pos ); + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TBC_TEXT_FORMAT_H_INCLUDED + +// ----------- end of #include from tbc_text_format.h ----------- +// ........... back in clara.h + +#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE + +// ----------- #included from clara_compilers.h ----------- + +#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED +#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CLARA_CONFIG_CPP11_OVERRIDE : is override supported? +// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) + +// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? + +// In general each macro has a _NO_ form +// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 + +#ifdef __clang__ + +#if __has_feature(cxx_nullptr) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#if __has_feature(cxx_noexcept) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#if (_MSC_VER >= 1600) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(__cplusplus) && __cplusplus >= 201103L + +#define CLARA_CPP11_OR_GREATER + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) +#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE +#endif +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NULLPTR +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_UNIQUE_PTR +#endif + +// noexcept support: +#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) +#define CLARA_NOEXCEPT noexcept +# define CLARA_NOEXCEPT_IS(x) noexcept(x) +#else +#define CLARA_NOEXCEPT throw() +# define CLARA_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CLARA_CONFIG_CPP11_NULLPTR +#define CLARA_NULL nullptr +#else +#define CLARA_NULL NULL +#endif + +// override support +#ifdef CLARA_CONFIG_CPP11_OVERRIDE +#define CLARA_OVERRIDE override +#else +#define CLARA_OVERRIDE +#endif + +// unique_ptr support +#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR +# define CLARA_AUTO_PTR( T ) std::unique_ptr +#else +# define CLARA_AUTO_PTR( T ) std::auto_ptr +#endif + +#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// ----------- end of #include from clara_compilers.h ----------- +// ........... back in clara.h + +#include +#include +#include + +#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#define CLARA_PLATFORM_WINDOWS +#endif + +// Use optional outer namespace +#ifdef STITCH_CLARA_OPEN_NAMESPACE +STITCH_CLARA_OPEN_NAMESPACE +#endif + +namespace Clara { + + struct UnpositionalTag {}; + + extern UnpositionalTag _; + +#ifdef CLARA_CONFIG_MAIN + UnpositionalTag _; +#endif + + namespace Detail { + +#ifdef CLARA_CONSOLE_WIDTH + const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + using namespace Tbc; + + inline bool startsWith( std::string const& str, std::string const& prefix ) { + return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; + } + + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + + template struct IsBool { static const bool value = false; }; + template<> struct IsBool { static const bool value = true; }; + + template + void convertInto( std::string const& _source, T& _dest ) { + std::stringstream ss; + ss << _source; + ss >> _dest; + if( ss.fail() ) + throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); + } + inline void convertInto( std::string const& _source, std::string& _dest ) { + _dest = _source; + } + inline void convertInto( std::string const& _source, bool& _dest ) { + std::string sourceLC = _source; + std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower ); + if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) + _dest = true; + else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) + _dest = false; + else + throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); + } + + template + struct IArgFunction { + virtual ~IArgFunction() {} +#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS + IArgFunction() = default; + IArgFunction( IArgFunction const& ) = default; +#endif + virtual void set( ConfigT& config, std::string const& value ) const = 0; + virtual bool takesArg() const = 0; + virtual IArgFunction* clone() const = 0; + }; + + template + class BoundArgFunction { + public: + BoundArgFunction() : functionObj( CLARA_NULL ) {} + BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} + BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} + BoundArgFunction& operator = ( BoundArgFunction const& other ) { + IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; + delete functionObj; + functionObj = newFunctionObj; + return *this; + } + ~BoundArgFunction() { delete functionObj; } + + void set( ConfigT& config, std::string const& value ) const { + functionObj->set( config, value ); + } + bool takesArg() const { return functionObj->takesArg(); } + + bool isSet() const { + return functionObj != CLARA_NULL; + } + private: + IArgFunction* functionObj; + }; + + template + struct NullBinder : IArgFunction{ + virtual void set( C&, std::string const& ) const {} + virtual bool takesArg() const { return true; } + virtual IArgFunction* clone() const { return new NullBinder( *this ); } + }; + + template + struct BoundDataMember : IArgFunction{ + BoundDataMember( M C::* _member ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + convertInto( stringValue, p.*member ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } + M C::* member; + }; + template + struct BoundUnaryMethod : IArgFunction{ + BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + (p.*member)( value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } + void (C::*member)( M ); + }; + template + struct BoundNullaryMethod : IArgFunction{ + BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + (p.*member)(); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } + void (C::*member)(); + }; + + template + struct BoundUnaryFunction : IArgFunction{ + BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + function( obj ); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } + void (*function)( C& ); + }; + + template + struct BoundBinaryFunction : IArgFunction{ + BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + function( obj, value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } + void (*function)( C&, T ); + }; + + } // namespace Detail + + inline std::vector argsToVector( int argc, char const* const* const argv ) { + std::vector args( static_cast( argc ) ); + for( std::size_t i = 0; i < static_cast( argc ); ++i ) + args[i] = argv[i]; + + return args; + } + + class Parser { + enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; + Mode mode; + std::size_t from; + bool inQuotes; + public: + + struct Token { + enum Type { Positional, ShortOpt, LongOpt }; + Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} + Type type; + std::string data; + }; + + Parser() : mode( None ), from( 0 ), inQuotes( false ){} + + void parseIntoTokens( std::vector const& args, std::vector& tokens ) { + const std::string doubleDash = "--"; + for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) + parseIntoTokens( args[i], tokens); + } + + void parseIntoTokens( std::string const& arg, std::vector& tokens ) { + for( std::size_t i = 0; i <= arg.size(); ++i ) { + char c = arg[i]; + if( c == '"' ) + inQuotes = !inQuotes; + mode = handleMode( i, c, arg, tokens ); + } + } + Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + switch( mode ) { + case None: return handleNone( i, c ); + case MaybeShortOpt: return handleMaybeShortOpt( i, c ); + case ShortOpt: + case LongOpt: + case SlashOpt: return handleOpt( i, c, arg, tokens ); + case Positional: return handlePositional( i, c, arg, tokens ); + default: throw std::logic_error( "Unknown mode" ); + } + } + + Mode handleNone( std::size_t i, char c ) { + if( inQuotes ) { + from = i; + return Positional; + } + switch( c ) { + case '-': return MaybeShortOpt; +#ifdef CLARA_PLATFORM_WINDOWS + case '/': from = i+1; return SlashOpt; +#endif + default: from = i; return Positional; + } + } + Mode handleMaybeShortOpt( std::size_t i, char c ) { + switch( c ) { + case '-': from = i+1; return LongOpt; + default: from = i; return ShortOpt; + } + } + Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) + return mode; + + std::string optName = arg.substr( from, i-from ); + if( mode == ShortOpt ) + for( std::size_t j = 0; j < optName.size(); ++j ) + tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); + else if( mode == SlashOpt && optName.size() == 1 ) + tokens.push_back( Token( Token::ShortOpt, optName ) ); + else + tokens.push_back( Token( Token::LongOpt, optName ) ); + return None; + } + Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) + return mode; + + std::string data = arg.substr( from, i-from ); + tokens.push_back( Token( Token::Positional, data ) ); + return None; + } + }; + + template + struct CommonArgProperties { + CommonArgProperties() {} + CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} + + Detail::BoundArgFunction boundField; + std::string description; + std::string detail; + std::string placeholder; // Only value if boundField takes an arg + + bool takesArg() const { + return !placeholder.empty(); + } + void validate() const { + if( !boundField.isSet() ) + throw std::logic_error( "option not bound" ); + } + }; + struct OptionArgProperties { + std::vector shortNames; + std::string longName; + + bool hasShortName( std::string const& shortName ) const { + return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); + } + bool hasLongName( std::string const& _longName ) const { + return _longName == longName; + } + }; + struct PositionalArgProperties { + PositionalArgProperties() : position( -1 ) {} + int position; // -1 means non-positional (floating) + + bool isFixedPositional() const { + return position != -1; + } + }; + + template + class CommandLine { + + struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { + Arg() {} + Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} + + using CommonArgProperties::placeholder; // !TBD + + std::string dbgName() const { + if( !longName.empty() ) + return "--" + longName; + if( !shortNames.empty() ) + return "-" + shortNames[0]; + return "positional args"; + } + std::string commands() const { + std::ostringstream oss; + bool first = true; + std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); + for(; it != itEnd; ++it ) { + if( first ) + first = false; + else + oss << ", "; + oss << "-" << *it; + } + if( !longName.empty() ) { + if( !first ) + oss << ", "; + oss << "--" << longName; + } + if( !placeholder.empty() ) + oss << " <" << placeholder << ">"; + return oss.str(); + } + }; + + typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; + + friend void addOptName( Arg& arg, std::string const& optName ) + { + if( optName.empty() ) + return; + if( Detail::startsWith( optName, "--" ) ) { + if( !arg.longName.empty() ) + throw std::logic_error( "Only one long opt may be specified. '" + + arg.longName + + "' already specified, now attempting to add '" + + optName + "'" ); + arg.longName = optName.substr( 2 ); + } + else if( Detail::startsWith( optName, "-" ) ) + arg.shortNames.push_back( optName.substr( 1 ) ); + else + throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); + } + friend void setPositionalArg( Arg& arg, int position ) + { + arg.position = position; + } + + class ArgBuilder { + public: + ArgBuilder( Arg* arg ) : m_arg( arg ) {} + + // Bind a non-boolean data member (requires placeholder string) + template + void bind( M C::* field, std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + m_arg->placeholder = placeholder; + } + // Bind a boolean data member (no placeholder required) + template + void bind( bool C::* field ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + } + + // Bind a method taking a single, non-boolean argument (requires a placeholder string) + template + void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + m_arg->placeholder = placeholder; + } + + // Bind a method taking a single, boolean argument (no placeholder string required) + template + void bind( void (C::* unaryMethod)( bool ) ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + } + + // Bind a method that takes no arguments (will be called if opt is present) + template + void bind( void (C::* nullaryMethod)() ) { + m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); + } + + // Bind a free function taking a single argument - the object to operate on (no placeholder string required) + template + void bind( void (* unaryFunction)( C& ) ) { + m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); + } + + // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) + template + void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); + m_arg->placeholder = placeholder; + } + + ArgBuilder& describe( std::string const& description ) { + m_arg->description = description; + return *this; + } + ArgBuilder& detail( std::string const& detail ) { + m_arg->detail = detail; + return *this; + } + + protected: + Arg* m_arg; + }; + + class OptBuilder : public ArgBuilder { + public: + OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} + OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} + + OptBuilder& operator[]( std::string const& optName ) { + addOptName( *ArgBuilder::m_arg, optName ); + return *this; + } + }; + + public: + + CommandLine() + : m_boundProcessName( new Detail::NullBinder() ), + m_highestSpecifiedArgPosition( 0 ), + m_throwOnUnrecognisedTokens( false ) + {} + CommandLine( CommandLine const& other ) + : m_boundProcessName( other.m_boundProcessName ), + m_options ( other.m_options ), + m_positionalArgs( other.m_positionalArgs ), + m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), + m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) + { + if( other.m_floatingArg.get() ) + m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); + } + + CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { + m_throwOnUnrecognisedTokens = shouldThrow; + return *this; + } + + OptBuilder operator[]( std::string const& optName ) { + m_options.push_back( Arg() ); + addOptName( m_options.back(), optName ); + OptBuilder builder( &m_options.back() ); + return builder; + } + + ArgBuilder operator[]( int position ) { + m_positionalArgs.insert( std::make_pair( position, Arg() ) ); + if( position > m_highestSpecifiedArgPosition ) + m_highestSpecifiedArgPosition = position; + setPositionalArg( m_positionalArgs[position], position ); + ArgBuilder builder( &m_positionalArgs[position] ); + return builder; + } + + // Invoke this with the _ instance + ArgBuilder operator[]( UnpositionalTag ) { + if( m_floatingArg.get() ) + throw std::logic_error( "Only one unpositional argument can be added" ); + m_floatingArg.reset( new Arg() ); + ArgBuilder builder( m_floatingArg.get() ); + return builder; + } + + template + void bindProcessName( M C::* field ) { + m_boundProcessName = new Detail::BoundDataMember( field ); + } + template + void bindProcessName( void (C::*_unaryMethod)( M ) ) { + m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); + } + + void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { + typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; + std::size_t maxWidth = 0; + for( it = itBegin; it != itEnd; ++it ) + maxWidth = (std::max)( maxWidth, it->commands().size() ); + + for( it = itBegin; it != itEnd; ++it ) { + Detail::Text usage( it->commands(), Detail::TextAttributes() + .setWidth( maxWidth+indent ) + .setIndent( indent ) ); + Detail::Text desc( it->description, Detail::TextAttributes() + .setWidth( width - maxWidth - 3 ) ); + + for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { + std::string usageCol = i < usage.size() ? usage[i] : ""; + os << usageCol; + + if( i < desc.size() && !desc[i].empty() ) + os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) + << desc[i]; + os << "\n"; + } + } + } + std::string optUsage() const { + std::ostringstream oss; + optUsage( oss ); + return oss.str(); + } + + void argSynopsis( std::ostream& os ) const { + for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { + if( i > 1 ) + os << " "; + typename std::map::const_iterator it = m_positionalArgs.find( i ); + if( it != m_positionalArgs.end() ) + os << "<" << it->second.placeholder << ">"; + else if( m_floatingArg.get() ) + os << "<" << m_floatingArg->placeholder << ">"; + else + throw std::logic_error( "non consecutive positional arguments with no floating args" ); + } + // !TBD No indication of mandatory args + if( m_floatingArg.get() ) { + if( m_highestSpecifiedArgPosition > 1 ) + os << " "; + os << "[<" << m_floatingArg->placeholder << "> ...]"; + } + } + std::string argSynopsis() const { + std::ostringstream oss; + argSynopsis( oss ); + return oss.str(); + } + + void usage( std::ostream& os, std::string const& procName ) const { + validate(); + os << "usage:\n " << procName << " "; + argSynopsis( os ); + if( !m_options.empty() ) { + os << " [options]\n\nwhere options are: \n"; + optUsage( os, 2 ); + } + os << "\n"; + } + std::string usage( std::string const& procName ) const { + std::ostringstream oss; + usage( oss, procName ); + return oss.str(); + } + + ConfigT parse( std::vector const& args ) const { + ConfigT config; + parseInto( args, config ); + return config; + } + + std::vector parseInto( std::vector const& args, ConfigT& config ) const { + std::string processName = args[0]; + std::size_t lastSlash = processName.find_last_of( "/\\" ); + if( lastSlash != std::string::npos ) + processName = processName.substr( lastSlash+1 ); + m_boundProcessName.set( config, processName ); + std::vector tokens; + Parser parser; + parser.parseIntoTokens( args, tokens ); + return populate( tokens, config ); + } + + std::vector populate( std::vector const& tokens, ConfigT& config ) const { + validate(); + std::vector unusedTokens = populateOptions( tokens, config ); + unusedTokens = populateFixedArgs( unusedTokens, config ); + unusedTokens = populateFloatingArgs( unusedTokens, config ); + return unusedTokens; + } + + std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + std::vector errors; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); + for(; it != itEnd; ++it ) { + Arg const& arg = *it; + + try { + if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || + ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { + if( arg.takesArg() ) { + if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) + errors.push_back( "Expected argument to option: " + token.data ); + else + arg.boundField.set( config, tokens[++i].data ); + } + else { + arg.boundField.set( config, "true" ); + } + break; + } + } + catch( std::exception& ex ) { + errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); + } + } + if( it == itEnd ) { + if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) + unusedTokens.push_back( token ); + else if( errors.empty() && m_throwOnUnrecognisedTokens ) + errors.push_back( "unrecognised option: " + token.data ); + } + } + if( !errors.empty() ) { + std::ostringstream oss; + for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); + it != itEnd; + ++it ) { + if( it != errors.begin() ) + oss << "\n"; + oss << *it; + } + throw std::runtime_error( oss.str() ); + } + return unusedTokens; + } + std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + int position = 1; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::map::const_iterator it = m_positionalArgs.find( position ); + if( it != m_positionalArgs.end() ) + it->second.boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + if( token.type == Parser::Token::Positional ) + position++; + } + return unusedTokens; + } + std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { + if( !m_floatingArg.get() ) + return tokens; + std::vector unusedTokens; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + if( token.type == Parser::Token::Positional ) + m_floatingArg->boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + } + return unusedTokens; + } + + void validate() const + { + if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) + throw std::logic_error( "No options or arguments specified" ); + + for( typename std::vector::const_iterator it = m_options.begin(), + itEnd = m_options.end(); + it != itEnd; ++it ) + it->validate(); + } + + private: + Detail::BoundArgFunction m_boundProcessName; + std::vector m_options; + std::map m_positionalArgs; + ArgAutoPtr m_floatingArg; + int m_highestSpecifiedArgPosition; + bool m_throwOnUnrecognisedTokens; + }; + +} // end namespace Clara + +STITCH_CLARA_CLOSE_NAMESPACE +#undef STITCH_CLARA_OPEN_NAMESPACE +#undef STITCH_CLARA_CLOSE_NAMESPACE + +#endif // TWOBLUECUBES_CLARA_H_INCLUDED +#undef STITCH_CLARA_OPEN_NAMESPACE + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#include + +namespace Catch { + + inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } + inline void abortAfterX( ConfigData& config, int x ) { + if( x < 1 ) + throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); + config.abortAfter = x; + } + inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } + inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } + + inline void addWarning( ConfigData& config, std::string const& _warning ) { + if( _warning == "NoAssertions" ) + config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); + else + throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" ); + } + inline void setOrder( ConfigData& config, std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + throw std::runtime_error( "Unrecognised ordering: '" + order + "'" ); + } + inline void setRngSeed( ConfigData& config, std::string const& seed ) { + if( seed == "time" ) { + config.rngSeed = static_cast( std::time(0) ); + } + else { + std::stringstream ss; + ss << seed; + ss >> config.rngSeed; + if( ss.fail() ) + throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" ); + } + } + inline void setVerbosity( ConfigData& config, int level ) { + // !TBD: accept strings? + config.verbosity = static_cast( level ); + } + inline void setShowDurations( ConfigData& config, bool _showDurations ) { + config.showDurations = _showDurations + ? ShowDurations::Always + : ShowDurations::Never; + } + inline void setUseColour( ConfigData& config, std::string const& value ) { + std::string mode = toLower( value ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); + } + inline void forceColour( ConfigData& config ) { + config.useColour = UseColour::Yes; + } + inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { + std::ifstream f( _filename.c_str() ); + if( !f.is_open() ) + throw std::domain_error( "Unable to load input file: " + _filename ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, "#" ) ) { + if( !startsWith( line, "\"" ) ) + line = "\"" + line + "\""; + addTestOrTags( config, line + "," ); + } + } + } + + inline Clara::CommandLine makeCommandLineParser() { + + using namespace Clara; + CommandLine cli; + + cli.bindProcessName( &ConfigData::processName ); + + cli["-?"]["-h"]["--help"] + .describe( "display usage information" ) + .bind( &ConfigData::showHelp ); + + cli["-l"]["--list-tests"] + .describe( "list all/matching test cases" ) + .bind( &ConfigData::listTests ); + + cli["-t"]["--list-tags"] + .describe( "list all/matching tags" ) + .bind( &ConfigData::listTags ); + + cli["-s"]["--success"] + .describe( "include successful tests in output" ) + .bind( &ConfigData::showSuccessfulTests ); + + cli["-b"]["--break"] + .describe( "break into debugger on failure" ) + .bind( &ConfigData::shouldDebugBreak ); + + cli["-e"]["--nothrow"] + .describe( "skip exception tests" ) + .bind( &ConfigData::noThrow ); + + cli["-i"]["--invisibles"] + .describe( "show invisibles (tabs, newlines)" ) + .bind( &ConfigData::showInvisibles ); + + cli["-o"]["--out"] + .describe( "output filename" ) + .bind( &ConfigData::outputFilename, "filename" ); + + cli["-r"]["--reporter"] +// .placeholder( "name[:filename]" ) + .describe( "reporter to use (defaults to console)" ) + .bind( &addReporterName, "name" ); + + cli["-n"]["--name"] + .describe( "suite name" ) + .bind( &ConfigData::name, "name" ); + + cli["-a"]["--abort"] + .describe( "abort at first failure" ) + .bind( &abortAfterFirst ); + + cli["-x"]["--abortx"] + .describe( "abort after x failures" ) + .bind( &abortAfterX, "no. failures" ); + + cli["-w"]["--warn"] + .describe( "enable warnings" ) + .bind( &addWarning, "warning name" ); + +// - needs updating if reinstated +// cli.into( &setVerbosity ) +// .describe( "level of verbosity (0=no output)" ) +// .shortOpt( "v") +// .longOpt( "verbosity" ) +// .placeholder( "level" ); + + cli[_] + .describe( "which test or tests to use" ) + .bind( &addTestOrTags, "test name, pattern or tags" ); + + cli["-d"]["--durations"] + .describe( "show test durations" ) + .bind( &setShowDurations, "yes|no" ); + + cli["-f"]["--input-file"] + .describe( "load test names to run from a file" ) + .bind( &loadTestNamesFromFile, "filename" ); + + cli["-#"]["--filenames-as-tags"] + .describe( "adds a tag for the filename" ) + .bind( &ConfigData::filenamesAsTags ); + + // Less common commands which don't have a short form + cli["--list-test-names-only"] + .describe( "list all/matching test cases names only" ) + .bind( &ConfigData::listTestNamesOnly ); + + cli["--list-reporters"] + .describe( "list all reporters" ) + .bind( &ConfigData::listReporters ); + + cli["--order"] + .describe( "test case order (defaults to decl)" ) + .bind( &setOrder, "decl|lex|rand" ); + + cli["--rng-seed"] + .describe( "set a specific seed for random numbers" ) + .bind( &setRngSeed, "'time'|number" ); + + cli["--force-colour"] + .describe( "force colourised output (deprecated)" ) + .bind( &forceColour ); + + cli["--use-colour"] + .describe( "should output be colourised" ) + .bind( &setUseColour, "yes|no" ); + + return cli; + } + +} // end namespace Catch + +// #included from: internal/catch_list.hpp +#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED + +// #included from: catch_text.h +#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED + +#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch +// #included from: ../external/tbc_text_format.h +// Only use header guard if we are not using an outer namespace +#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# endif +# else +# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# endif +#endif +#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#include +#include +#include + +// Use optional outer namespace +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ), + tabChar( '\t' ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + char tabChar; // If this char is seen the indent is changed to current pos + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + std::string wrappableChars = " [({.,/|\\-"; + std::size_t indent = _attr.initialIndent != std::string::npos + ? _attr.initialIndent + : _attr.indent; + std::string remainder = _str; + + while( !remainder.empty() ) { + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + std::size_t tabPos = std::string::npos; + std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); + std::size_t pos = remainder.find_first_of( '\n' ); + if( pos <= width ) { + width = pos; + } + pos = remainder.find_last_of( _attr.tabChar, width ); + if( pos != std::string::npos ) { + tabPos = pos; + if( remainder[width] == '\n' ) + width--; + remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); + } + + if( width == remainder.size() ) { + spliceLine( indent, remainder, width ); + } + else if( remainder[width] == '\n' ) { + spliceLine( indent, remainder, width ); + if( width <= 1 || remainder.size() != 1 ) + remainder = remainder.substr( 1 ); + indent = _attr.indent; + } + else { + pos = remainder.find_last_of( wrappableChars, width ); + if( pos != std::string::npos && pos > 0 ) { + spliceLine( indent, remainder, pos ); + if( remainder[0] == ' ' ) + remainder = remainder.substr( 1 ); + } + else { + spliceLine( indent, remainder, width-1 ); + lines.back() += "-"; + } + if( lines.size() == 1 ) + indent = _attr.indent; + if( tabPos != std::string::npos ) + indent += tabPos; + } + } + } + + void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { + lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); + _remainder = _remainder.substr( _pos ); + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE + +namespace Catch { + using Tbc::Text; + using Tbc::TextAttributes; +} + +// #included from: catch_console_colour.hpp +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + + // By intention + FileName = LightGrey, + Warning = Yellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = Yellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour const& other ); + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved; + }; + + inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } + +} // end namespace Catch + +// #included from: catch_interfaces_reporter.h +#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED + +#include +#include +#include +#include + +namespace Catch +{ + struct ReporterConfig { + explicit ReporterConfig( Ptr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& stream() const { return *m_stream; } + Ptr fullConfig() const { return m_fullConfig; } + + private: + std::ostream* m_stream; + Ptr m_fullConfig; + }; + + struct ReporterPreferences { + ReporterPreferences() + : shouldRedirectStdOut( false ) + {} + + bool shouldRedirectStdOut; + }; + + template + struct LazyStat : Option { + LazyStat() : used( false ) {} + LazyStat& operator=( T const& _value ) { + Option::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option::reset(); + used = false; + } + bool used; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ) : name( _name ) {} + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + virtual ~AssertionStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = default; + AssertionStats& operator = ( AssertionStats && ) = default; +# endif + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + virtual ~SectionStats(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; +# endif + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + virtual ~TestCaseStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; +# endif + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + virtual ~TestGroupStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; +# endif + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + virtual ~TestRunStats(); + +# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestRunStats( TestRunStats const& _other ) + : runInfo( _other.runInfo ), + totals( _other.totals ), + aborting( _other.aborting ) + {} +# else + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; +# endif + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + class MultipleReporters; + + struct IStreamingReporter : IShared { + virtual ~IStreamingReporter(); + + // Implementing class must also provide the following static method: + // static std::string getDescription(); + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } + }; + + struct IReporterFactory : IShared { + virtual ~IReporterFactory(); + virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + + struct IReporterRegistry { + typedef std::map > FactoryMap; + typedef std::vector > Listeners; + + virtual ~IReporterRegistry(); + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + + Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); + +} + +#include +#include + +namespace Catch { + + inline std::size_t listTests( Config const& config ) { + + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::size_t matchedTests = 0; + TextAttributes nameAttr, tagsAttr; + nameAttr.setInitialIndent( 2 ).setIndent( 4 ); + tagsAttr.setIndent( 6 ); + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; + } + + if( !config.testSpec().hasFilters() ) + Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl; + else + Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl; + return matchedTests; + } + + inline std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( !config.testSpec().hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + std::size_t matchedTests = 0; + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + if( startsWith( testCaseInfo.name, "#" ) ) + Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl; + else + Catch::cout() << testCaseInfo.name << std::endl; + } + return matchedTests; + } + + struct TagInfo { + TagInfo() : count ( 0 ) {} + void add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + std::string all() const { + std::string out; + for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); + it != itEnd; + ++it ) + out += "[" + *it + "]"; + return out; + } + std::set spellings; + std::size_t count; + }; + + inline std::size_t listTags( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::map tagCounts; + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), + tagItEnd = it->getTestCaseInfo().tags.end(); + tagIt != tagItEnd; + ++tagIt ) { + std::string tagName = *tagIt; + std::string lcaseTagName = toLower( tagName ); + std::map::iterator countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( std::map::const_iterator countIt = tagCounts.begin(), + countItEnd = tagCounts.end(); + countIt != countItEnd; + ++countIt ) { + std::ostringstream oss; + oss << " " << std::setw(2) << countIt->second.count << " "; + Text wrapper( countIt->second.all(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( oss.str().size() ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); + Catch::cout() << oss.str() << wrapper << "\n"; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl; + return tagCounts.size(); + } + + inline std::size_t listReporters( Config const& /*config*/ ) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; + std::size_t maxNameLen = 0; + for(it = itBegin; it != itEnd; ++it ) + maxNameLen = (std::max)( maxNameLen, it->first.size() ); + + for(it = itBegin; it != itEnd; ++it ) { + Text wrapper( it->second->getDescription(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( 7+maxNameLen ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); + Catch::cout() << " " + << it->first + << ":" + << std::string( maxNameLen - it->first.size() + 2, ' ' ) + << wrapper << "\n"; + } + Catch::cout() << std::endl; + return factories.size(); + } + + inline Option list( Config const& config ) { + Option listedCount; + if( config.listTests() ) + listedCount = listedCount.valueOr(0) + listTests( config ); + if( config.listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); + if( config.listTags() ) + listedCount = listedCount.valueOr(0) + listTags( config ); + if( config.listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters( config ); + return listedCount; + } + +} // end namespace Catch + +// #included from: internal/catch_run_context.hpp +#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED + +// #included from: catch_test_case_tracker.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { +namespace TestCaseTracking { + + struct ITracker : SharedImpl<> { + virtual ~ITracker(); + + // static queries + virtual std::string name() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( Ptr const& child ) = 0; + virtual ITracker* findChild( std::string const& name ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + Ptr m_rootTracker; + ITracker* m_currentTracker; + RunState m_runState; + + public: + + static TrackerContext& instance() { + static TrackerContext s_instance; + return s_instance; + } + + TrackerContext() + : m_currentTracker( CATCH_NULL ), + m_runState( NotStarted ) + {} + + ITracker& startRun(); + + void endRun() { + m_rootTracker.reset(); + m_currentTracker = CATCH_NULL; + m_runState = NotStarted; + } + + void startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void completeCycle() { + m_runState = CompletedCycle; + } + + bool completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& currentTracker() { + return *m_currentTracker; + } + void setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + class TrackerHasName { + std::string m_name; + public: + TrackerHasName( std::string const& name ) : m_name( name ) {} + bool operator ()( Ptr const& tracker ) { + return tracker->name() == m_name; + } + }; + typedef std::vector > Children; + std::string m_name; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState; + public: + TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent ) + : m_name( name ), + m_ctx( ctx ), + m_parent( parent ), + m_runState( NotStarted ) + {} + virtual ~TrackerBase(); + + virtual std::string name() const CATCH_OVERRIDE { + return m_name; + } + virtual bool isComplete() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully; + } + virtual bool isOpen() const CATCH_OVERRIDE { + return m_runState != NotStarted && !isComplete(); + } + virtual bool hasChildren() const CATCH_OVERRIDE { + return !m_children.empty(); + } + + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + m_children.push_back( child ); + } + + virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE { + Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); + return( it != m_children.end() ) + ? it->get() + : CATCH_NULL; + } + virtual ITracker& parent() CATCH_OVERRIDE { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + virtual void openChild() CATCH_OVERRIDE { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } + virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } + + void open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + virtual void close() CATCH_OVERRIDE { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NotStarted: + case CompletedSuccessfully: + case Failed: + throw std::logic_error( "Illogical state" ); + + case NeedsAnotherRun: + break;; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + default: + throw std::logic_error( "Unexpected state" ); + } + moveToParent(); + m_ctx.completeCycle(); + } + virtual void fail() CATCH_OVERRIDE { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { + m_runState = NeedsAnotherRun; + } + private: + void moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void moveToThis() { + m_ctx.setCurrentTracker( this ); + } + }; + + class SectionTracker : public TrackerBase { + public: + SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( name, ctx, parent ) + {} + virtual ~SectionTracker(); + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } + + static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) { + SectionTracker* section = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( name ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = static_cast( childTracker ); + } + else { + section = new SectionTracker( name, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() && !section->isComplete() ) { + + section->open(); + } + return *section; + } + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index; + public: + IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( name, ctx, parent ), + m_size( size ), + m_index( -1 ) + {} + virtual ~IndexTracker(); + + virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } + + static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) { + IndexTracker* tracker = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( name ) ) { + assert( childTracker ); + assert( childTracker->isIndexTracker() ); + tracker = static_cast( childTracker ); + } + else { + tracker = new IndexTracker( name, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int index() const { return m_index; } + + void moveNext() { + m_index++; + m_children.clear(); + } + + virtual void close() CATCH_OVERRIDE { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + }; + + inline ITracker& TrackerContext::startRun() { + m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL ); + m_currentTracker = CATCH_NULL; + m_runState = Executing; + return *m_rootTracker; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +// #included from: catch_fatal_condition.hpp +#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED + +namespace Catch { + + // Report the error condition then exit the process + inline void fatal( std::string const& message, int exitCode ) { + IContext& context = Catch::getCurrentContext(); + IResultCapture* resultCapture = context.getResultCapture(); + resultCapture->handleFatalErrorCondition( message ); + + if( Catch::alwaysTrue() ) // avoids "no return" warnings + exit( exitCode ); + } + +} // namespace Catch + +#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// + +namespace Catch { + + struct FatalConditionHandler { + void reset() {} + }; + +} // namespace Catch + +#else // Not Windows - assumed to be POSIX compatible ////////////////////////// + +#include + +namespace Catch { + + struct SignalDefs { int id; const char* name; }; + extern SignalDefs signalDefs[]; + SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + + struct FatalConditionHandler { + + static void handleSignal( int sig ) { + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) + if( sig == signalDefs[i].id ) + fatal( signalDefs[i].name, -sig ); + fatal( "", -sig ); + } + + FatalConditionHandler() : m_isSet( true ) { + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) + signal( signalDefs[i].id, handleSignal ); + } + ~FatalConditionHandler() { + reset(); + } + void reset() { + if( m_isSet ) { + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) + signal( signalDefs[i].id, SIG_DFL ); + m_isSet = false; + } + } + + bool m_isSet; + }; + +} // namespace Catch + +#endif // not Windows + +#include +#include + +namespace Catch { + + class StreamRedirect { + + public: + StreamRedirect( std::ostream& stream, std::string& targetString ) + : m_stream( stream ), + m_prevBuf( stream.rdbuf() ), + m_targetString( targetString ) + { + stream.rdbuf( m_oss.rdbuf() ); + } + + ~StreamRedirect() { + m_targetString += m_oss.str(); + m_stream.rdbuf( m_prevBuf ); + } + + private: + std::ostream& m_stream; + std::streambuf* m_prevBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + RunContext( RunContext const& ); + void operator =( RunContext const& ); + + public: + + explicit RunContext( Ptr const& _config, Ptr const& reporter ) + : m_runInfo( _config->name() ), + m_context( getCurrentMutableContext() ), + m_activeTestCase( CATCH_NULL ), + m_config( _config ), + m_reporter( reporter ) + { + m_context.setRunner( this ); + m_context.setConfig( m_config ); + m_context.setResultCapture( this ); + m_reporter->testRunStarting( m_runInfo ); + } + + virtual ~RunContext() { + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); + } + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); + } + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); + } + + Totals runTest( TestCase const& testCase ) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + TestCaseInfo testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting( testInfo ); + + m_activeTestCase = &testCase; + + do { + m_trackerContext.startRun(); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name ); + runCurrentTest( redirectedCout, redirectedCerr ); + } + while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); + } + // !TBD: deprecated - this will be replaced by indexed trackers + while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); + + Totals deltaTotals = m_totals.delta( prevTotals ); + if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting() ) ); + + m_activeTestCase = CATCH_NULL; + m_testCaseTracker = CATCH_NULL; + + return deltaTotals; + } + + Ptr config() const { + return m_config; + } + + private: // IResultCapture + + virtual void assertionEnded( AssertionResult const& result ) { + if( result.getResultType() == ResultWas::Ok ) { + m_totals.assertions.passed++; + } + else if( !result.isOk() ) { + m_totals.assertions.failed++; + } + + if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) + m_messages.clear(); + + // Reset working state + m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_lastResult = result; + } + + virtual bool sectionStarted ( + SectionInfo const& sectionInfo, + Counts& assertions + ) + { + std::ostringstream oss; + oss << sectionInfo.name << "@" << sectionInfo.lineInfo; + + ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() ); + if( !sectionTracker.isOpen() ) + return false; + m_activeSections.push_back( §ionTracker ); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting( sectionInfo ); + + assertions = m_totals.assertions; + + return true; + } + bool testForMissingAssertions( Counts& assertions ) { + if( assertions.total() != 0 ) + return false; + if( !m_config->warnAboutMissingAssertions() ) + return false; + if( m_trackerContext.currentTracker().hasChildren() ) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + virtual void sectionEnded( SectionEndInfo const& endInfo ) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( !m_activeSections.empty() ) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); + m_messages.clear(); + } + + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { + if( m_unfinishedSections.empty() ) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back( endInfo ); + } + + virtual void pushScopedMessage( MessageInfo const& message ) { + m_messages.push_back( message ); + } + + virtual void popScopedMessage( MessageInfo const& message ) { + m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); + } + + virtual std::string getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : ""; + } + + virtual const AssertionResult* getLastResult() const { + return &m_lastResult; + } + + virtual void handleFatalErrorCondition( std::string const& message ) { + ResultBuilder resultBuilder = makeUnexpectedResultBuilder(); + resultBuilder.setResultType( ResultWas::FatalErrorCondition ); + resultBuilder << message; + resultBuilder.captureExpression(); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); + m_reporter->sectionEnded( testCaseSectionStats ); + + TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + "", + "", + false ) ); + m_totals.testCases.failed++; + testGroupEnded( "", m_totals, 1, 1 ); + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); + } + + public: + // !TBD We need to do this another way! + bool aborting() const { + return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); + } + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + m_reporter->sectionStarting( testCaseSection ); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + try { + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); + + seedRng( *m_config ); + + Timer timer; + timer.start(); + if( m_reporter->getPreferences().shouldRedirectStdOut ) { + StreamRedirect coutRedir( Catch::cout(), redirectedCout ); + StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); + invokeActiveTestCase(); + } + else { + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } + catch( TestFailureException& ) { + // This just means the test was aborted due to failure + } + catch(...) { + makeUnexpectedResultBuilder().useActiveException(); + } + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( testCaseInfo.okToFail() ) { + std::swap( assertions.failedButOk, assertions.failed ); + m_totals.assertions.failed -= assertions.failedButOk; + m_totals.assertions.failedButOk += assertions.failedButOk; + } + + SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); + m_reporter->sectionEnded( testCaseSectionStats ); + } + + void invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); + } + + private: + + ResultBuilder makeUnexpectedResultBuilder() const { + return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), + m_lastAssertionInfo.lineInfo, + m_lastAssertionInfo.capturedExpression.c_str(), + m_lastAssertionInfo.resultDisposition ); + } + + void handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it ) + sectionEnded( *it ); + m_unfinishedSections.clear(); + } + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase; + ITracker* m_testCaseTracker; + ITracker* m_currentSectionTracker; + AssertionResult m_lastResult; + + Ptr m_config; + Totals m_totals; + Ptr m_reporter; + std::vector m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; + }; + + IResultCapture& getResultCapture() { + if( IResultCapture* capture = getCurrentContext().getResultCapture() ) + return *capture; + else + throw std::logic_error( "No result capture instance" ); + } + +} // end namespace Catch + +// #included from: internal/catch_version.h +#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED + +namespace Catch { + + // Versioning information + struct Version { + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + std::string const& _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + std::string const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + + private: + void operator=( Version const& ); + }; + + extern Version libraryVersion; +} + +#include +#include +#include + +namespace Catch { + + Ptr createReporter( std::string const& reporterName, Ptr const& config ) { + Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); + if( !reporter ) { + std::ostringstream oss; + oss << "No reporter registered with name: '" << reporterName << "'"; + throw std::domain_error( oss.str() ); + } + return reporter; + } + + Ptr makeReporter( Ptr const& config ) { + std::vector reporters = config->getReporterNames(); + if( reporters.empty() ) + reporters.push_back( "console" ); + + Ptr reporter; + for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); + it != itEnd; + ++it ) + reporter = addReporter( reporter, createReporter( *it, config ) ); + return reporter; + } + Ptr addListeners( Ptr const& config, Ptr reporters ) { + IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); + for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); + it != itEnd; + ++it ) + reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); + return reporters; + } + + Totals runTests( Ptr const& config ) { + + Ptr iconfig = config.get(); + + Ptr reporter = makeReporter( config ); + reporter = addListeners( iconfig, reporter ); + + RunContext context( iconfig, reporter ); + + Totals totals; + + context.testGroupStarting( config->name(), 1, 1 ); + + TestSpec testSpec = config->testSpec(); + if( !testSpec.hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests + + std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); + for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); + it != itEnd; + ++it ) { + if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) + totals += context.runTest( *it ); + else + reporter->skipTest( *it ); + } + + context.testGroupEnded( iconfig->name(), totals, 1, 1 ); + return totals; + } + + void applyFilenamesAsTags( IConfig const& config ) { + std::vector const& tests = getAllTestCasesSorted( config ); + for(std::size_t i = 0; i < tests.size(); ++i ) { + TestCase& test = const_cast( tests[i] ); + std::set tags = test.tags; + + std::string filename = test.lineInfo.file; + std::string::size_type lastSlash = filename.find_last_of( "\\/" ); + if( lastSlash != std::string::npos ) + filename = filename.substr( lastSlash+1 ); + + std::string::size_type lastDot = filename.find_last_of( "." ); + if( lastDot != std::string::npos ) + filename = filename.substr( 0, lastDot ); + + tags.insert( "#" + filename ); + setTags( test, tags ); + } + } + + class Session : NonCopyable { + static bool alreadyInstantiated; + + public: + + struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; + + Session() + : m_cli( makeCommandLineParser() ) { + if( alreadyInstantiated ) { + std::string msg = "Only one instance of Catch::Session can ever be used"; + Catch::cerr() << msg << std::endl; + throw std::logic_error( msg ); + } + alreadyInstantiated = true; + } + ~Session() { + Catch::cleanUp(); + } + + void showHelp( std::string const& processName ) { + Catch::cout() << "\nCatch v" << libraryVersion << "\n"; + + m_cli.usage( Catch::cout(), processName ); + Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; + } + + int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { + try { + m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); + m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); + if( m_configData.showHelp ) + showHelp( m_configData.processName ); + m_config.reset(); + } + catch( std::exception& ex ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "\nError(s) in input:\n" + << Text( ex.what(), TextAttributes().setIndent(2) ) + << "\n\n"; + } + m_cli.usage( Catch::cout(), m_configData.processName ); + return (std::numeric_limits::max)(); + } + return 0; + } + + void useConfigData( ConfigData const& _configData ) { + m_configData = _configData; + m_config.reset(); + } + + int run( int argc, char const* const* const argv ) { + + int returnCode = applyCommandLine( argc, argv ); + if( returnCode == 0 ) + returnCode = run(); + return returnCode; + } + + int run() { + if( m_configData.showHelp ) + return 0; + + try + { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option listed = list( config() ) ) + return static_cast( *listed ); + + return static_cast( runTests( m_config ).assertions.failed ); + } + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return (std::numeric_limits::max)(); + } + } + + Clara::CommandLine const& cli() const { + return m_cli; + } + std::vector const& unusedTokens() const { + return m_unusedTokens; + } + ConfigData& configData() { + return m_configData; + } + Config& config() { + if( !m_config ) + m_config = new Config( m_configData ); + return *m_config; + } + private: + Clara::CommandLine m_cli; + std::vector m_unusedTokens; + ConfigData m_configData; + Ptr m_config; + }; + + bool Session::alreadyInstantiated = false; + +} // end namespace Catch + +// #included from: catch_registry_hub.hpp +#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED + +// #included from: catch_test_case_registry_impl.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED + +#include +#include +#include +#include +#include + +#ifdef CATCH_CPP14_OR_GREATER +#include +#endif + +namespace Catch { + + struct RandomNumberGenerator { + typedef int result_type; + + result_type operator()( result_type n ) const { return std::rand() % n; } + +#ifdef CATCH_CPP14_OR_GREATER + static constexpr result_type min() { return 0; } + static constexpr result_type max() { return 1000000; } + result_type operator()() const { return std::rand() % max(); } +#endif + template + static void shuffle( V& vector ) { + RandomNumberGenerator rng; +#ifdef CATCH_CPP14_OR_GREATER + std::shuffle( vector.begin(), vector.end(), rng ); +#else + std::random_shuffle( vector.begin(), vector.end(), rng ); +#endif + } + }; + + inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { + + std::vector sorted = unsortedTestCases; + + switch( config.runOrder() ) { + case RunTests::InLexicographicalOrder: + std::sort( sorted.begin(), sorted.end() ); + break; + case RunTests::InRandomOrder: + { + seedRng( config ); + RandomNumberGenerator::shuffle( sorted ); + } + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; + } + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); + } + + void enforceNoDuplicateTestCases( std::vector const& functions ) { + std::set seenFunctions; + for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); + it != itEnd; + ++it ) { + std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); + if( !prev.second ) { + std::ostringstream ss; + + ss << Colour( Colour::Red ) + << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" + << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; + + throw std::runtime_error(ss.str()); + } + } + } + + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector filtered; + filtered.reserve( testCases.size() ); + for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); + it != itEnd; + ++it ) + if( matchTest( *it, testSpec, config ) ) + filtered.push_back( *it ); + return filtered; + } + std::vector const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + class TestRegistry : public ITestCaseRegistry { + public: + TestRegistry() + : m_currentSortOrder( RunTests::InDeclarationOrder ), + m_unnamedCount( 0 ) + {} + virtual ~TestRegistry(); + + virtual void registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name == "" ) { + std::ostringstream oss; + oss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( oss.str() ) ); + } + m_functions.push_back( testCase ); + } + + virtual std::vector const& getAllTests() const { + return m_functions; + } + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + private: + std::vector m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder; + mutable std::vector m_sortedFunctions; + size_t m_unnamedCount; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class FreeFunctionTestCase : public SharedImpl { + public: + + FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} + + virtual void invoke() const { + m_fun(); + } + + private: + virtual ~FreeFunctionTestCase(); + + TestFunction m_fun; + }; + + inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { + std::string className = classOrQualifiedMethodName; + if( startsWith( className, "&" ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + + void registerTestCase + ( ITestCase* testCase, + char const* classOrQualifiedMethodName, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + getMutableRegistryHub().registerTest + ( makeTestCase + ( testCase, + extractClassName( classOrQualifiedMethodName ), + nameAndDesc.name, + nameAndDesc.description, + lineInfo ) ); + } + void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); + } + + /////////////////////////////////////////////////////////////////////////// + + AutoReg::AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCaseFunction( function, lineInfo, nameAndDesc ); + } + + AutoReg::~AutoReg() {} + +} // end namespace Catch + +// #included from: catch_reporter_registry.hpp +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED + +#include + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + virtual ~ReporterRegistry() CATCH_OVERRIDE {} + + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { + FactoryMap::const_iterator it = m_factories.find( name ); + if( it == m_factories.end() ) + return CATCH_NULL; + return it->second->create( ReporterConfig( config ) ); + } + + void registerReporter( std::string const& name, Ptr const& factory ) { + m_factories.insert( std::make_pair( name, factory ) ); + } + void registerListener( Ptr const& factory ) { + m_listeners.push_back( factory ); + } + + virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { + return m_factories; + } + virtual Listeners const& getListeners() const CATCH_OVERRIDE { + return m_listeners; + } + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +// #included from: catch_exception_translator_registry.hpp +#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED + +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry() { + deleteAll( m_translators ); + } + + virtual void registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( translator ); + } + + virtual std::string translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::toString( [exception description] ); + } +#else + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + throw; + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string tryTranslators() const { + if( m_translators.empty() ) + throw; + else + return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); + } + + private: + std::vector m_translators; + }; +} + +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub { + + RegistryHub( RegistryHub const& ); + void operator=( RegistryHub const& ); + + public: // IRegistryHub + RegistryHub() { + } + virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { + return m_reporterRegistry; + } + virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { + return m_testCaseRegistry; + } + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { + return m_exceptionTranslatorRegistry; + } + + public: // IMutableRegistryHub + virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerReporter( name, factory ); + } + virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerListener( factory ); + } + virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { + m_testCaseRegistry.registerTest( testInfo ); + } + virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + }; + + // Single, global, instance + inline RegistryHub*& getTheRegistryHub() { + static RegistryHub* theRegistryHub = CATCH_NULL; + if( !theRegistryHub ) + theRegistryHub = new RegistryHub(); + return theRegistryHub; + } + } + + IRegistryHub& getRegistryHub() { + return *getTheRegistryHub(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return *getTheRegistryHub(); + } + void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = CATCH_NULL; + cleanUpContext(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + +} // end namespace Catch + +// #included from: catch_notimplemented_exception.hpp +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED + +#include + +namespace Catch { + + NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) + : m_lineInfo( lineInfo ) { + std::ostringstream oss; + oss << lineInfo << ": function "; + oss << "not implemented"; + m_what = oss.str(); + } + + const char* NotImplementedException::what() const CATCH_NOEXCEPT { + return m_what.c_str(); + } + +} // end namespace Catch + +// #included from: catch_context_impl.hpp +#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED + +// #included from: catch_stream.hpp +#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + template + class StreamBufImpl : public StreamBufBase { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() CATCH_NOEXCEPT { + sync(); + } + + private: + int overflow( int c ) { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast( c ) ) ); + else + sputc( static_cast( c ) ); + } + return 0; + } + + int sync() { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + FileStream::FileStream( std::string const& filename ) { + m_ofs.open( filename.c_str() ); + if( m_ofs.fail() ) { + std::ostringstream oss; + oss << "Unable to open file: '" << filename << "'"; + throw std::domain_error( oss.str() ); + } + } + + std::ostream& FileStream::stream() const { + return m_ofs; + } + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + DebugOutStream::DebugOutStream() + : m_streamBuf( new StreamBufImpl() ), + m_os( m_streamBuf.get() ) + {} + + std::ostream& DebugOutStream::stream() const { + return m_os; + } + + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream::CoutStream() + : m_os( Catch::cout().rdbuf() ) + {} + + std::ostream& CoutStream::stream() const { + return m_os; + } + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { + return std::cout; + } + std::ostream& cerr() { + return std::cerr; + } +#endif +} + +namespace Catch { + + class Context : public IMutableContext { + + Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} + Context( Context const& ); + void operator=( Context const& ); + + public: // IContext + virtual IResultCapture* getResultCapture() { + return m_resultCapture; + } + virtual IRunner* getRunner() { + return m_runner; + } + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { + return getGeneratorsForCurrentTest() + .getGeneratorInfo( fileInfo, totalSize ) + .getCurrentIndex(); + } + virtual bool advanceGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + return generators && generators->moveNext(); + } + + virtual Ptr getConfig() const { + return m_config; + } + + public: // IMutableContext + virtual void setResultCapture( IResultCapture* resultCapture ) { + m_resultCapture = resultCapture; + } + virtual void setRunner( IRunner* runner ) { + m_runner = runner; + } + virtual void setConfig( Ptr const& config ) { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IGeneratorsForTest* findGeneratorsForCurrentTest() { + std::string testName = getResultCapture()->getCurrentTestName(); + + std::map::const_iterator it = + m_generatorsByTestName.find( testName ); + return it != m_generatorsByTestName.end() + ? it->second + : CATCH_NULL; + } + + IGeneratorsForTest& getGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + if( !generators ) { + std::string testName = getResultCapture()->getCurrentTestName(); + generators = createGeneratorsForTest(); + m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); + } + return *generators; + } + + private: + Ptr m_config; + IRunner* m_runner; + IResultCapture* m_resultCapture; + std::map m_generatorsByTestName; + }; + + namespace { + Context* currentContext = CATCH_NULL; + } + IMutableContext& getCurrentMutableContext() { + if( !currentContext ) + currentContext = new Context(); + return *currentContext; + } + IContext& getCurrentContext() { + return getCurrentMutableContext(); + } + + void cleanUpContext() { + delete currentContext; + currentContext = CATCH_NULL; + } +} + +// #included from: catch_console_colour_impl.hpp +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() {} + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = !isDebuggerActive() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0:34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + Catch::cout() << '\033' << _escapeCode; + } + }; + + IColourImpl* platformColourInstance() { + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } + Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + impl->use( _colourCode ); + } + +} // end namespace Catch + +// #included from: catch_generators_impl.hpp +#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct GeneratorInfo : IGeneratorInfo { + + GeneratorInfo( std::size_t size ) + : m_size( size ), + m_currentIndex( 0 ) + {} + + bool moveNext() { + if( ++m_currentIndex == m_size ) { + m_currentIndex = 0; + return false; + } + return true; + } + + std::size_t getCurrentIndex() const { + return m_currentIndex; + } + + std::size_t m_size; + std::size_t m_currentIndex; + }; + + /////////////////////////////////////////////////////////////////////////// + + class GeneratorsForTest : public IGeneratorsForTest { + + public: + ~GeneratorsForTest() { + deleteAll( m_generatorsInOrder ); + } + + IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { + std::map::const_iterator it = m_generatorsByName.find( fileInfo ); + if( it == m_generatorsByName.end() ) { + IGeneratorInfo* info = new GeneratorInfo( size ); + m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); + m_generatorsInOrder.push_back( info ); + return *info; + } + return *it->second; + } + + bool moveNext() { + std::vector::const_iterator it = m_generatorsInOrder.begin(); + std::vector::const_iterator itEnd = m_generatorsInOrder.end(); + for(; it != itEnd; ++it ) { + if( (*it)->moveNext() ) + return true; + } + return false; + } + + private: + std::map m_generatorsByName; + std::vector m_generatorsInOrder; + }; + + IGeneratorsForTest* createGeneratorsForTest() + { + return new GeneratorsForTest(); + } + +} // end namespace Catch + +// #included from: catch_assertionresult.hpp +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED + +namespace Catch { + + AssertionInfo::AssertionInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + std::string const& _capturedExpression, + ResultDisposition::Flags _resultDisposition ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + capturedExpression( _capturedExpression ), + resultDisposition( _resultDisposition ) + {} + + AssertionResult::AssertionResult() {} + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + AssertionResult::~AssertionResult() {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return !m_info.capturedExpression.empty(); + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string AssertionResult::getExpression() const { + if( isFalseTest( m_info.resultDisposition ) ) + return "!" + m_info.capturedExpression; + else + return m_info.capturedExpression; + } + std::string AssertionResult::getExpressionInMacro() const { + if( m_info.macroName.empty() ) + return m_info.capturedExpression; + else + return m_info.macroName + "( " + m_info.capturedExpression + " )"; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + return m_resultData.reconstructedExpression; + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + std::string AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + +} // end namespace Catch + +// #included from: catch_test_case_info.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED + +namespace Catch { + + inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, "." ) || + tag == "hide" || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else + return TestCaseInfo::None; + } + inline bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] ); + } + inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + if( isReservedTag( tag ) ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "Tag name [" << tag << "] not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n"; + } + { + Colour colourGuard( Colour::FileName ); + Catch::cerr() << _lineInfo << std::endl; + } + exit(1); + } + } + + TestCase makeTestCase( ITestCase* _testCase, + std::string const& _className, + std::string const& _name, + std::string const& _descOrTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden( startsWith( _name, "./" ) ); // Legacy support + + // Parse out tags + std::set tags; + std::string desc, tag; + bool inTag = false; + for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { + char c = _descOrTags[i]; + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( prop == TestCaseInfo::IsHidden ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + tags.insert( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + tags.insert( "hide" ); + tags.insert( "." ); + } + + TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, info ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) + { + testCaseInfo.tags = tags; + testCaseInfo.lcaseTags.clear(); + + std::ostringstream oss; + for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { + oss << "[" << *it << "]"; + std::string lcaseTag = toLower( *it ); + testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.insert( lcaseTag ); + } + testCaseInfo.tagsAsString = oss.str(); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) + : name( other.name ), + className( other.className ), + description( other.description ), + tags( other.tags ), + lcaseTags( other.lcaseTags ), + tagsAsString( other.tagsAsString ), + lineInfo( other.lineInfo ), + properties( other.properties ) + {} + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} + + TestCase::TestCase( TestCase const& other ) + : TestCaseInfo( other ), + test( other.test ) + {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::swap( TestCase& other ) { + test.swap( other.test ); + name.swap( other.name ); + className.swap( other.className ); + description.swap( other.description ); + tags.swap( other.tags ); + lcaseTags.swap( other.lcaseTags ); + tagsAsString.swap( other.tagsAsString ); + std::swap( TestCaseInfo::properties, static_cast( other ).properties ); + std::swap( lineInfo, other.lineInfo ); + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + TestCase& TestCase::operator = ( TestCase const& other ) { + TestCase temp( other ); + swap( temp ); + return *this; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch + +// #included from: catch_version.hpp +#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + std::string const& _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << "." + << version.minorVersion << "." + << version.patchNumber; + + if( !version.branchName.empty() ) { + os << "-" << version.branchName + << "." << version.buildNumber; + } + return os; + } + + Version libraryVersion( 1, 5, 7, "", 0 ); + +} + +// #included from: catch_message.hpp +#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED + +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ) + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + ScopedMessage::ScopedMessage( ScopedMessage const& other ) + : m_info( other.m_info ) + {} + + ScopedMessage::~ScopedMessage() { + getResultCapture().popScopedMessage( m_info ); + } + +} // end namespace Catch + +// #included from: catch_legacy_reporter_adapter.hpp +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED + +// #included from: catch_legacy_reporter_adapter.h +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED + +namespace Catch +{ + // Deprecated + struct IReporter : IShared { + virtual ~IReporter(); + + virtual bool shouldRedirectStdout() const = 0; + + virtual void StartTesting() = 0; + virtual void EndTesting( Totals const& totals ) = 0; + virtual void StartGroup( std::string const& groupName ) = 0; + virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; + virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; + virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; + virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; + virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; + virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; + virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; + virtual void Aborted() = 0; + virtual void Result( AssertionResult const& result ) = 0; + }; + + class LegacyReporterAdapter : public SharedImpl + { + public: + LegacyReporterAdapter( Ptr const& legacyReporter ); + virtual ~LegacyReporterAdapter(); + + virtual ReporterPreferences getPreferences() const; + virtual void noMatchingTestCases( std::string const& ); + virtual void testRunStarting( TestRunInfo const& ); + virtual void testGroupStarting( GroupInfo const& groupInfo ); + virtual void testCaseStarting( TestCaseInfo const& testInfo ); + virtual void sectionStarting( SectionInfo const& sectionInfo ); + virtual void assertionStarting( AssertionInfo const& ); + virtual bool assertionEnded( AssertionStats const& assertionStats ); + virtual void sectionEnded( SectionStats const& sectionStats ); + virtual void testCaseEnded( TestCaseStats const& testCaseStats ); + virtual void testGroupEnded( TestGroupStats const& testGroupStats ); + virtual void testRunEnded( TestRunStats const& testRunStats ); + virtual void skipTest( TestCaseInfo const& ); + + private: + Ptr m_legacyReporter; + }; +} + +namespace Catch +{ + LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) + : m_legacyReporter( legacyReporter ) + {} + LegacyReporterAdapter::~LegacyReporterAdapter() {} + + ReporterPreferences LegacyReporterAdapter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); + return prefs; + } + + void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} + void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { + m_legacyReporter->StartTesting(); + } + void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { + m_legacyReporter->StartGroup( groupInfo.name ); + } + void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { + m_legacyReporter->StartTestCase( testInfo ); + } + void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { + m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); + } + void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { + // Not on legacy interface + } + + bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); + rb << it->message; + rb.setResultType( ResultWas::Info ); + AssertionResult result = rb.build(); + m_legacyReporter->Result( result ); + } + } + } + m_legacyReporter->Result( assertionStats.assertionResult ); + return true; + } + void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { + if( sectionStats.missingAssertions ) + m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); + m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); + } + void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { + m_legacyReporter->EndTestCase + ( testCaseStats.testInfo, + testCaseStats.totals, + testCaseStats.stdOut, + testCaseStats.stdErr ); + } + void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { + if( testGroupStats.aborting ) + m_legacyReporter->Aborted(); + m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); + } + void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { + m_legacyReporter->EndTesting( testRunStats.totals ); + } + void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { + } +} + +// #included from: catch_timer.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#endif + +#ifdef CATCH_PLATFORM_WINDOWS +#include +#else +#include +#endif + +namespace Catch { + + namespace { +#ifdef CATCH_PLATFORM_WINDOWS + uint64_t getCurrentTicks() { + static uint64_t hz=0, hzo=0; + if (!hz) { + QueryPerformanceFrequency( reinterpret_cast( &hz ) ); + QueryPerformanceCounter( reinterpret_cast( &hzo ) ); + } + uint64_t t; + QueryPerformanceCounter( reinterpret_cast( &t ) ); + return ((t-hzo)*1000000)/hz; + } +#else + uint64_t getCurrentTicks() { + timeval t; + gettimeofday(&t,CATCH_NULL); + return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); + } +#endif + } + + void Timer::start() { + m_ticks = getCurrentTicks(); + } + unsigned int Timer::getElapsedMicroseconds() const { + return static_cast(getCurrentTicks() - m_ticks); + } + unsigned int Timer::getElapsedMilliseconds() const { + return static_cast(getElapsedMicroseconds()/1000); + } + double Timer::getElapsedSeconds() const { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +// #included from: catch_common.hpp +#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), ::tolower ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : ""; + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << " " << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << "s"; + return os; + } + + SourceLineInfo::SourceLineInfo() : line( 0 ){} + SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) + : file( _file ), + line( _line ) + {} + SourceLineInfo::SourceLineInfo( SourceLineInfo const& other ) + : file( other.file ), + line( other.line ) + {} + bool SourceLineInfo::empty() const { + return file.empty(); + } + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { + return line == other.line && file == other.file; + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { + return line < other.line || ( line == other.line && file < other.file ); + } + + void seedRng( IConfig const& config ) { + if( config.rngSeed() != 0 ) + std::srand( config.rngSeed() ); + } + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << "(" << info.line << ")"; +#else + os << info.file << ":" << info.line; +#endif + return os; + } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { + std::ostringstream oss; + oss << locationInfo << ": Internal Catch error: '" << message << "'"; + if( alwaysTrue() ) + throw std::logic_error( oss.str() ); + } +} + +// #included from: catch_section.hpp +#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description ) + : name( _name ), + description( _description ), + lineInfo( _lineInfo ) + {} + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); + if( std::uncaught_exception() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + +} // end namespace Catch + +// #included from: catch_debugger.hpp +#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED + +#include + +#ifdef CATCH_PLATFORM_MAC + + #include + #include + #include + #include + #include + + namespace Catch{ + + // The following function is taken directly from the following technical note: + // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + } // namespace Catch + +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + inline bool isDebuggerActive() { return false; } + } +#endif // Platform + +#ifdef CATCH_PLATFORM_WINDOWS + extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* ); + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } +#else + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } +#endif // Platform + +// #included from: catch_tostring.hpp +#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _{ + int asInt; + char asChar[sizeof (int)]; + } u; + + u.asInt = 1; + return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) + { + // Reverse order for little endian architectures + int i = 0, end = static_cast( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast(object); + std::ostringstream os; + os << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + os << std::setw(2) << static_cast(bytes[i]); + return os.str(); + } +} + +std::string toString( std::string const& value ) { + std::string s = value; + if( getCurrentContext().getConfig()->showInvisibles() ) { + for(size_t i = 0; i < s.size(); ++i ) { + std::string subs; + switch( s[i] ) { + case '\n': subs = "\\n"; break; + case '\t': subs = "\\t"; break; + default: break; + } + if( !subs.empty() ) { + s = s.substr( 0, i ) + subs + s.substr( i+1 ); + ++i; + } + } + } + return "\"" + s + "\""; +} +std::string toString( std::wstring const& value ) { + + std::string s; + s.reserve( value.size() ); + for(size_t i = 0; i < value.size(); ++i ) + s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; + return Catch::toString( s ); +} + +std::string toString( const char* const value ) { + return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); +} + +std::string toString( char* const value ) { + return Catch::toString( static_cast( value ) ); +} + +std::string toString( const wchar_t* const value ) +{ + return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); +} + +std::string toString( wchar_t* const value ) +{ + return Catch::toString( static_cast( value ) ); +} + +std::string toString( int value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ")"; + return oss.str(); +} + +std::string toString( unsigned long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ")"; + return oss.str(); +} + +std::string toString( unsigned int value ) { + return Catch::toString( static_cast( value ) ); +} + +template +std::string fpToString( T value, int precision ) { + std::ostringstream oss; + oss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = oss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +std::string toString( const double value ) { + return fpToString( value, 10 ); +} +std::string toString( const float value ) { + return fpToString( value, 5 ) + "f"; +} + +std::string toString( bool value ) { + return value ? "true" : "false"; +} + +std::string toString( char value ) { + return value < ' ' + ? toString( static_cast( value ) ) + : Detail::makeString( value ); +} + +std::string toString( signed char value ) { + return toString( static_cast( value ) ); +} + +std::string toString( unsigned char value ) { + return toString( static_cast( value ) ); +} + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ")"; + return oss.str(); +} +std::string toString( unsigned long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ")"; + return oss.str(); +} +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ) { + return "nullptr"; +} +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSObject* const& nsObject ) { + return toString( [nsObject description] ); + } +#endif + +} // end namespace Catch + +// #included from: catch_result_builder.hpp +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED + +namespace Catch { + + std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) { + return secondArg.empty() || secondArg == "\"\"" + ? capturedExpression + : capturedExpression + ", " + secondArg; + } + ResultBuilder::ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg ) + : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ), + m_shouldDebugBreak( false ), + m_shouldThrow( false ) + {} + + ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { + m_data.resultType = result; + return *this; + } + ResultBuilder& ResultBuilder::setResultType( bool result ) { + m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; + return *this; + } + ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { + m_exprComponents.lhs = lhs; + return *this; + } + ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { + m_exprComponents.rhs = rhs; + return *this; + } + ResultBuilder& ResultBuilder::setOp( std::string const& op ) { + m_exprComponents.op = op; + return *this; + } + + void ResultBuilder::endExpression() { + m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); + captureExpression(); + } + + void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { + m_assertionInfo.resultDisposition = resultDisposition; + m_stream.oss << Catch::translateActiveException(); + captureResult( ResultWas::ThrewException ); + } + + void ResultBuilder::captureResult( ResultWas::OfType resultType ) { + setResultType( resultType ); + captureExpression(); + } + void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { + if( expectedMessage.empty() ) + captureExpectedException( Matchers::Impl::Generic::AllOf() ); + else + captureExpectedException( Matchers::Equals( expectedMessage ) ); + } + + void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher const& matcher ) { + + assert( m_exprComponents.testFalse == false ); + AssertionResultData data = m_data; + data.resultType = ResultWas::Ok; + data.reconstructedExpression = m_assertionInfo.capturedExpression; + + std::string actualMessage = Catch::translateActiveException(); + if( !matcher.match( actualMessage ) ) { + data.resultType = ResultWas::ExpressionFailed; + data.reconstructedExpression = actualMessage; + } + AssertionResult result( m_assertionInfo, data ); + handleResult( result ); + } + + void ResultBuilder::captureExpression() { + AssertionResult result = build(); + handleResult( result ); + } + void ResultBuilder::handleResult( AssertionResult const& result ) + { + getResultCapture().assertionEnded( result ); + + if( !result.isOk() ) { + if( getCurrentContext().getConfig()->shouldDebugBreak() ) + m_shouldDebugBreak = true; + if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) + m_shouldThrow = true; + } + } + void ResultBuilder::react() { + if( m_shouldThrow ) + throw Catch::TestFailureException(); + } + + bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } + bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } + + AssertionResult ResultBuilder::build() const + { + assert( m_data.resultType != ResultWas::Unknown ); + + AssertionResultData data = m_data; + + // Flip bool results if testFalse is set + if( m_exprComponents.testFalse ) { + if( data.resultType == ResultWas::Ok ) + data.resultType = ResultWas::ExpressionFailed; + else if( data.resultType == ResultWas::ExpressionFailed ) + data.resultType = ResultWas::Ok; + } + + data.message = m_stream.oss.str(); + data.reconstructedExpression = reconstructExpression(); + if( m_exprComponents.testFalse ) { + if( m_exprComponents.op == "" ) + data.reconstructedExpression = "!" + data.reconstructedExpression; + else + data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; + } + return AssertionResult( m_assertionInfo, data ); + } + std::string ResultBuilder::reconstructExpression() const { + if( m_exprComponents.op == "" ) + return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs; + else if( m_exprComponents.op == "matches" ) + return m_exprComponents.lhs + " " + m_exprComponents.rhs; + else if( m_exprComponents.op != "!" ) { + if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && + m_exprComponents.lhs.find("\n") == std::string::npos && + m_exprComponents.rhs.find("\n") == std::string::npos ) + return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; + else + return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; + } + else + return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; + } + +} // end namespace Catch + +// #included from: catch_tag_alias_registry.hpp +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED + +// #included from: catch_tag_alias_registry.h +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED + +#include + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + virtual ~TagAliasRegistry(); + virtual Option find( std::string const& alias ) const; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; + void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + static TagAliasRegistry& get(); + + private: + std::map m_registry; + }; + +} // end namespace Catch + +#include +#include + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + Option TagAliasRegistry::find( std::string const& alias ) const { + std::map::const_iterator it = m_registry.find( alias ); + if( it != m_registry.end() ) + return it->second; + else + return Option(); + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); + it != itEnd; + ++it ) { + std::size_t pos = expandedTestSpec.find( it->first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + it->second.tag + + expandedTestSpec.substr( pos + it->first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + + if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) { + std::ostringstream oss; + oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; + throw std::domain_error( oss.str().c_str() ); + } + if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { + std::ostringstream oss; + oss << "error: tag alias, \"" << alias << "\" already registered.\n" + << "\tFirst seen at " << find(alias)->lineInfo << "\n" + << "\tRedefined at " << lineInfo; + throw std::domain_error( oss.str().c_str() ); + } + } + + TagAliasRegistry& TagAliasRegistry::get() { + static TagAliasRegistry instance; + return instance; + + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); } + + RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + try { + TagAliasRegistry::get().add( alias, tag, lineInfo ); + } + catch( std::exception& ex ) { + Colour colourGuard( Colour::Red ); + Catch::cerr() << ex.what() << std::endl; + exit(1); + } + } + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_multi.hpp +#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED + +namespace Catch { + +class MultipleReporters : public SharedImpl { + typedef std::vector > Reporters; + Reporters m_reporters; + +public: + void add( Ptr const& reporter ) { + m_reporters.push_back( reporter ); + } + +public: // IStreamingReporter + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporters[0]->getPreferences(); + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->noMatchingTestCases( spec ); + } + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunStarting( testRunInfo ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupStarting( groupInfo ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseStarting( testInfo ); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionStarting( sectionInfo ); + } + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->assertionStarting( assertionInfo ); + } + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + bool clearBuffer = false; + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + clearBuffer |= (*it)->assertionEnded( assertionStats ); + return clearBuffer; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionEnded( sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupEnded( testGroupStats ); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunEnded( testRunStats ); + } + + virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->skipTest( testInfo ); + } + + virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { + return this; + } + +}; + +Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { + Ptr resultingReporter; + + if( existingReporter ) { + MultipleReporters* multi = existingReporter->tryAsMulti(); + if( !multi ) { + multi = new MultipleReporters; + resultingReporter = Ptr( multi ); + if( existingReporter ) + multi->add( existingReporter ); + } + else + resultingReporter = existingReporter; + multi->add( additionalReporter ); + } + else + resultingReporter = additionalReporter; + + return resultingReporter; +} + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_xml.hpp +#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED + +// #included from: catch_reporter_bases.hpp +#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED + +#include + +namespace Catch { + + struct StreamingReporterBase : SharedImpl { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual ~StreamingReporterBase() CATCH_OVERRIDE; + + virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { + currentTestRunInfo = _testRunInfo; + } + virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { + currentGroupInfo = _groupInfo; + } + + virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { + currentTestCaseInfo = _testInfo; + } + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_sectionStack.push_back( _sectionInfo ); + } + + virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + } + virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { + currentGroupInfo.reset(); + } + virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + Ptr m_config; + std::ostream& stream; + + LazyStat currentTestRunInfo; + LazyStat currentGroupInfo; + LazyStat currentTestCaseInfo; + + std::vector m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + struct CumulativeReporterBase : SharedImpl { + template + struct Node : SharedImpl<> { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + typedef std::vector > ChildNodes; + T value; + ChildNodes children; + }; + struct SectionNode : SharedImpl<> { + explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} + virtual ~SectionNode(); + + bool operator == ( SectionNode const& other ) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == ( Ptr const& other ) const { + return operator==( *other ); + } + + SectionStats stats; + typedef std::vector > ChildSections; + typedef std::vector Assertions; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() ( Ptr const& node ) const { + return node->stats.sectionInfo.lineInfo == m_other.lineInfo; + } + private: + void operator=( BySectionInfo const& ); + SectionInfo const& m_other; + }; + + typedef Node TestCaseNode; + typedef Node TestGroupNode; + typedef Node TestRunNode; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + ~CumulativeReporterBase(); + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} + virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} + + virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + Ptr node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = new SectionNode( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + SectionNode::ChildSections::const_iterator it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = new SectionNode( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = node; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back( assertionStats ); + return true; + } + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + Ptr node = new TestCaseNode( testCaseStats ); + assert( m_sectionStack.size() == 0 ); + node->children.push_back( m_rootSection ); + m_testCases.push_back( node ); + m_rootSection.reset(); + + assert( m_deepestSection ); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + Ptr node = new TestGroupNode( testGroupStats ); + node->children.swap( m_testCases ); + m_testGroups.push_back( node ); + } + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + Ptr node = new TestRunNode( testRunStats ); + node->children.swap( m_testGroups ); + m_testRuns.push_back( node ); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} + + Ptr m_config; + std::ostream& stream; + std::vector m_assertions; + std::vector > > m_sections; + std::vector > m_testCases; + std::vector > m_testGroups; + + std::vector > m_testRuns; + + Ptr m_rootSection; + Ptr m_deepestSection; + std::vector > m_sectionStack; + ReporterPreferences m_reporterPrefs; + + }; + + template + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + struct TestEventListenerBase : StreamingReporterBase { + TestEventListenerBase( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { + return false; + } + }; + +} // end namespace Catch + +// #included from: ../internal/catch_reporter_registrars.hpp +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED + +namespace Catch { + + template + class LegacyReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new LegacyReporterAdapter( new T( config ) ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + LegacyReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ReporterRegistrar { + + class ReporterFactory : public SharedImpl { + + // *** Please Note ***: + // - If you end up here looking at a compiler error because it's trying to register + // your custom reporter class be aware that the native reporter interface has changed + // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via + // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. + // However please consider updating to the new interface as the old one is now + // deprecated and will probably be removed quite soon! + // Please contact me via github if you have any questions at all about this. + // In fact, ideally, please contact me anyway to let me know you've hit this - as I have + // no idea who is actually using custom reporters at all (possibly no-one!). + // The new interface is designed to minimise exposure to interface changes in the future. + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ListenerRegistrar { + + class ListenerFactory : public SharedImpl { + + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + virtual std::string getDescription() const { + return ""; + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( new ListenerFactory() ); + } + }; +} + +#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ + namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ + namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ + namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } + +// #included from: ../internal/catch_xmlwriter.hpp +#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void encodeTo( std::ostream& os ) const { + + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t i = 0; i < m_str.size(); ++ i ) { + char c = m_str[i]; + switch( c ) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) + os << ">"; + else + os << c; + break; + + case '\"': + if( m_forWhat == ForAttributes ) + os << """; + else + os << c; + break; + + default: + // Escape control chars - based on contribution by @espenalb in PR #465 and + // by @mrpi PR #588 + if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) + os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast( c ) << ';'; + else + os << c; + } + } + } + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + ScopedElement( ScopedElement const& other ) + : m_writer( other.m_writer ){ + other.m_writer = CATCH_NULL; + } + + ~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + ScopedElement& writeText( std::string const& text, bool indent = true ) { + m_writer->writeText( text, indent ); + return *this; + } + + template + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer; + }; + + XmlWriter() + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( &Catch::cout() ) + { + // We encode control characters, which requires + // XML 1.1 + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + *m_os << "\n"; + } + + XmlWriter( std::ostream& os ) + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( &os ) + { + *m_os << "\n"; + } + + ~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + stream() << m_indent << "<" << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + ScopedElement scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + stream() << "/>\n"; + m_tagIsOpen = false; + } + else { + stream() << m_indent << "\n"; + } + m_tags.pop_back(); + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\""; + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, bool attribute ) { + stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\""; + return *this; + } + + template + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + std::ostringstream oss; + oss << attribute; + return writeAttribute( name, oss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + stream() << m_indent; + stream() << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + XmlWriter& writeComment( std::string const& text ) { + ensureTagClosed(); + stream() << m_indent << ""; + m_needsNewline = true; + return *this; + } + + XmlWriter& writeBlankLine() { + ensureTagClosed(); + stream() << "\n"; + return *this; + } + + void setStream( std::ostream& os ) { + m_os = &os; + } + + private: + XmlWriter( XmlWriter const& ); + void operator=( XmlWriter const& ); + + std::ostream& stream() { + return *m_os; + } + + void ensureTagClosed() { + if( m_tagIsOpen ) { + stream() << ">\n"; + m_tagIsOpen = false; + } + } + + void newlineIfNecessary() { + if( m_needsNewline ) { + stream() << "\n"; + m_needsNewline = false; + } + } + + bool m_tagIsOpen; + bool m_needsNewline; + std::vector m_tags; + std::string m_indent; + std::ostream* m_os; + }; + +} +// #included from: catch_reenable_warnings.h + +#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + + +namespace Catch { + class XmlReporter : public StreamingReporterBase { + public: + XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_sectionDepth( 0 ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~XmlReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results as an XML document"; + } + + public: // StreamingReporterBase + + virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { + StreamingReporterBase::noMatchingTestCases( s ); + } + + virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testRunStarting( testInfo ); + m_xml.setStream( stream ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ) + .writeAttribute( "description", sectionInfo.description ); + } + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + const AssertionResult& assertionResult = assertionStats.assertionResult; + + // Print any info messages in tags. + if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + m_xml.scopedElement( "Info" ) + .writeText( it->message ); + } else if ( it->type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( it->message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) ) + return true; + + // Print the expression if there is one. + if( assertionResult.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", assertionResult.succeeded() ) + .writeAttribute( "type", assertionResult.getTestMacroName() ) + .writeAttribute( "filename", assertionResult.getSourceInfo().file ) + .writeAttribute( "line", assertionResult.getSourceInfo().line ); + + m_xml.scopedElement( "Original" ) + .writeText( assertionResult.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( assertionResult.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( assertionResult.getResultType() ) { + case ResultWas::ThrewException: + m_xml.scopedElement( "Exception" ) + .writeAttribute( "filename", assertionResult.getSourceInfo().file ) + .writeAttribute( "line", assertionResult.getSourceInfo().line ) + .writeText( assertionResult.getMessage() ); + break; + case ResultWas::FatalErrorCondition: + m_xml.scopedElement( "Fatal Error Condition" ) + .writeAttribute( "filename", assertionResult.getSourceInfo().file ) + .writeAttribute( "line", assertionResult.getSourceInfo().line ) + .writeText( assertionResult.getMessage() ); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( assertionResult.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.scopedElement( "Failure" ) + .writeText( assertionResult.getMessage() ); + break; + default: + break; + } + + if( assertionResult.hasExpression() ) + m_xml.endElement(); + + return true; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + m_xml.endElement(); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_junit.hpp +#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED + +#include + +namespace Catch { + + class JunitReporter : public CumulativeReporterBase { + public: + JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~JunitReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + suiteTimer.start(); + stdOutForSuite.str(""); + stdErrForSuite.str(""); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + stdOutForSuite << testCaseStats.stdOut; + stdErrForSuite << testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + virtual void testRunEndedCumulative() CATCH_OVERRIDE { + xml.endElement(); + } + + void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "timestamp", "tbd" ); // !TBD + + // Write test cases + for( TestGroupNode::ChildNodes::const_iterator + it = groupNode.children.begin(), itEnd = groupNode.children.end(); + it != itEnd; + ++it ) + writeTestCase( **it ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); + } + + void writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + if( rootSection.childSections.empty() ) + className = "global"; + } + writeSection( className, "", rootSection ); + } + + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode ) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + "/" + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); + } + for( SectionNode::ChildSections::const_iterator + it = sectionNode.childSections.begin(), + itEnd = sectionNode.childSections.end(); + it != itEnd; + ++it ) + if( className.empty() ) + writeSection( name, "", **it ); + else + writeSection( className, name, **it ); + } + + void writeAssertions( SectionNode const& sectionNode ) { + for( SectionNode::Assertions::const_iterator + it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); + it != itEnd; + ++it ) + writeAssertion( *it ); + } + void writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpandedExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + std::ostringstream oss; + if( !result.getMessage().empty() ) + oss << result.getMessage() << "\n"; + for( std::vector::const_iterator + it = stats.infoMessages.begin(), + itEnd = stats.infoMessages.end(); + it != itEnd; + ++it ) + if( it->type == ResultWas::Info ) + oss << it->message << "\n"; + + oss << "at " << result.getSourceInfo(); + xml.writeText( oss.str(), false ); + } + } + + XmlWriter xml; + Timer suiteTimer; + std::ostringstream stdOutForSuite; + std::ostringstream stdErrForSuite; + unsigned int unexpectedExceptions; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_console.hpp +#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED + +namespace Catch { + + struct ConsoleReporter : StreamingReporterBase { + ConsoleReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_headerPrinted( false ) + {} + + virtual ~ConsoleReporter() CATCH_OVERRIDE; + static std::string getDescription() { + return "Reports test results as plain lines of text"; + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + stream << "No test cases matched '" << spec << "'" << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { + } + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + lazyPrint(); + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + stream << std::endl; + return true; + } + + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting( _sectionInfo ); + } + virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { + if( _sectionStats.missingAssertions ) { + lazyPrint(); + Colour colour( Colour::ResultError ); + if( m_sectionStack.size() > 1 ) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if( m_headerPrinted ) { + if( m_config->showDurations() == ShowDurations::Always ) + stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl; + m_headerPrinted = false; + } + else { + if( m_config->showDurations() == ShowDurations::Always ) + stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl; + } + StreamingReporterBase::sectionEnded( _sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( _testCaseStats ); + m_headerPrinted = false; + } + virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { + if( currentGroupInfo.used ) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals( _testGroupStats.totals ); + stream << "\n" << std::endl; + } + StreamingReporterBase::testGroupEnded( _testGroupStats ); + } + virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { + printTotalsDivider( _testRunStats.totals ); + printTotals( _testRunStats.totals ); + stream << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ), + stats( _stats ), + result( _stats.assertionResult ), + colour( Colour::None ), + message( result.getMessage() ), + messages( _stats.infoMessages ), + printInfoMessages( _printInfoMessages ) + { + switch( result.getResultType() ) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } + else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with message"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if( _stats.infoMessages.size() == 1 ) + messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if( stats.totals.assertions.total() > 0 ) { + if( result.isOk() ) + stream << "\n"; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } + else { + stream << "\n"; + } + printMessage(); + } + + private: + void printResultType() const { + if( !passOrFail.empty() ) { + Colour colourGuard( colour ); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if( result.hasExpression() ) { + Colour colourGuard( Colour::OriginalExpression ); + stream << " "; + stream << result.getExpressionInMacro(); + stream << "\n"; + } + } + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + stream << "with expansion:\n"; + Colour colourGuard( Colour::ReconstructedExpression ); + stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n"; + } + } + void printMessage() const { + if( !messageLabel.empty() ) + stream << messageLabel << ":" << "\n"; + for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); + it != itEnd; + ++it ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || it->type != ResultWas::Info ) + stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n"; + } + } + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector messages; + bool printInfoMessages; + }; + + void lazyPrint() { + + if( !currentTestRunInfo.used ) + lazyPrintRunInfo(); + if( !currentGroupInfo.used ) + lazyPrintGroupInfo(); + + if( !m_headerPrinted ) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } + } + void lazyPrintRunInfo() { + stream << "\n" << getLineOfChars<'~'>() << "\n"; + Colour colour( Colour::SecondaryText ); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion << " host application.\n" + << "Run with -? for options\n\n"; + + if( m_config->rngSeed() != 0 ) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; + } + void lazyPrintGroupInfo() { + if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { + printClosedHeader( "Group: " + currentGroupInfo->name ); + currentGroupInfo.used = true; + } + } + void printTestCaseAndSectionHeader() { + assert( !m_sectionStack.empty() ); + printOpenHeader( currentTestCaseInfo->name ); + + if( m_sectionStack.size() > 1 ) { + Colour colourGuard( Colour::Headers ); + + std::vector::const_iterator + it = m_sectionStack.begin()+1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for( ; it != itEnd; ++it ) + printHeaderString( it->name, 2 ); + } + + SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; + + if( !lineInfo.empty() ){ + stream << getLineOfChars<'-'>() << "\n"; + Colour colourGuard( Colour::FileName ); + stream << lineInfo << "\n"; + } + stream << getLineOfChars<'.'>() << "\n" << std::endl; + } + + void printClosedHeader( std::string const& _name ) { + printOpenHeader( _name ); + stream << getLineOfChars<'.'>() << "\n"; + } + void printOpenHeader( std::string const& _name ) { + stream << getLineOfChars<'-'>() << "\n"; + { + Colour colourGuard( Colour::Headers ); + printHeaderString( _name ); + } + } + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { + std::size_t i = _string.find( ": " ); + if( i != std::string::npos ) + i+=2; + else + i = 0; + stream << Text( _string, TextAttributes() + .setIndent( indent+i) + .setInitialIndent( indent ) ) << "\n"; + } + + struct SummaryColumn { + + SummaryColumn( std::string const& _label, Colour::Code _colour ) + : label( _label ), + colour( _colour ) + {} + SummaryColumn addRow( std::size_t count ) { + std::ostringstream oss; + oss << count; + std::string row = oss.str(); + for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { + while( it->size() < row.size() ) + *it = " " + *it; + while( it->size() > row.size() ) + row = " " + row; + } + rows.push_back( row ); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector rows; + + }; + + void printTotals( Totals const& totals ) { + if( totals.testCases.total() == 0 ) { + stream << Colour( Colour::Warning ) << "No tests ran\n"; + } + else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { + stream << Colour( Colour::ResultSuccess ) << "All tests passed"; + stream << " (" + << pluralise( totals.assertions.passed, "assertion" ) << " in " + << pluralise( totals.testCases.passed, "test case" ) << ")" + << "\n"; + } + else { + + std::vector columns; + columns.push_back( SummaryColumn( "", Colour::None ) + .addRow( totals.testCases.total() ) + .addRow( totals.assertions.total() ) ); + columns.push_back( SummaryColumn( "passed", Colour::Success ) + .addRow( totals.testCases.passed ) + .addRow( totals.assertions.passed ) ); + columns.push_back( SummaryColumn( "failed", Colour::ResultError ) + .addRow( totals.testCases.failed ) + .addRow( totals.assertions.failed ) ); + columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) + .addRow( totals.testCases.failedButOk ) + .addRow( totals.assertions.failedButOk ) ); + + printSummaryRow( "test cases", columns, 0 ); + printSummaryRow( "assertions", columns, 1 ); + } + } + void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { + for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { + std::string value = it->rows[row]; + if( it->label.empty() ) { + stream << label << ": "; + if( value != "0" ) + stream << value; + else + stream << Colour( Colour::Warning ) << "- none -"; + } + else if( value != "0" ) { + stream << Colour( Colour::LightGrey ) << " | "; + stream << Colour( it->colour ) + << value << " " << it->label; + } + } + stream << "\n"; + } + + static std::size_t makeRatio( std::size_t number, std::size_t total ) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; + return ( ratio == 0 && number > 0 ) ? 1 : ratio; + } + static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { + if( i > j && i > k ) + return i; + else if( j > k ) + return j; + else + return k; + } + + void printTotalsDivider( Totals const& totals ) { + if( totals.testCases.total() > 0 ) { + std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); + std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); + std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); + while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )++; + while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )--; + + stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); + stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); + if( totals.testCases.allPassed() ) + stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); + else + stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); + } + else { + stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); + } + stream << "\n"; + } + void printSummaryDivider() { + stream << getLineOfChars<'-'>() << "\n"; + } + + private: + bool m_headerPrinted; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_compact.hpp +#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED + +namespace Catch { + + struct CompactReporter : StreamingReporterBase { + + CompactReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual ~CompactReporter(); + + static std::string getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + virtual ReporterPreferences getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + virtual void noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << "'" << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) { + } + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + virtual void testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( _testRunStats.totals ); + stream << "\n" << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ) + , stats( _stats ) + , result( _stats.assertionResult ) + , messages( _stats.infoMessages ) + , itMessage( _stats.infoMessages.begin() ) + , printInfoMessages( _printInfoMessages ) + {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch( result.getResultType() ) { + case ResultWas::Ok: + printResultType( Colour::ResultSuccess, passedString() ); + printOriginalExpression(); + printReconstructedExpression(); + if ( ! result.hasExpression() ) + printRemainingMessages( Colour::None ); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) + printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); + else + printResultType( Colour::Error, failedString() ); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType( Colour::Error, failedString() ); + printIssue( "unexpected exception with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType( Colour::Error, failedString() ); + printIssue( "fatal error condition with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType( Colour::Error, failedString() ); + printIssue( "expected exception, got none" ); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType( Colour::None, "info" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType( Colour::None, "warning" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType( Colour::Error, failedString() ); + printIssue( "explicitly" ); + printRemainingMessages( Colour::None ); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType( Colour::Error, "** internal error **" ); + break; + } + } + + private: + // Colour::LightGrey + + static Colour::Code dimColour() { return Colour::FileName; } + +#ifdef CATCH_PLATFORM_MAC + static const char* failedString() { return "FAILED"; } + static const char* passedString() { return "PASSED"; } +#else + static const char* failedString() { return "failed"; } + static const char* passedString() { return "passed"; } +#endif + + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ":"; + } + + void printResultType( Colour::Code colour, std::string passOrFail ) const { + if( !passOrFail.empty() ) { + { + Colour colourGuard( colour ); + stream << " " << passOrFail; + } + stream << ":"; + } + } + + void printIssue( std::string issue ) const { + stream << " " << issue; + } + + void printExpressionWas() { + if( result.hasExpression() ) { + stream << ";"; + { + Colour colour( dimColour() ); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if( result.hasExpression() ) { + stream << " " << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + { + Colour colour( dimColour() ); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if ( itMessage != messages.end() ) { + stream << " '" << itMessage->message << "'"; + ++itMessage; + } + } + + void printRemainingMessages( Colour::Code colour = dimColour() ) { + if ( itMessage == messages.end() ) + return; + + // using messages.end() directly yields compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + + { + Colour colourGuard( colour ); + stream << " with " << pluralise( N, "message" ) << ":"; + } + + for(; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || itMessage->type != ResultWas::Info ) { + stream << " '" << itMessage->message << "'"; + if ( ++itMessage != itEnd ) { + Colour colourGuard( dimColour() ); + stream << " and"; + } + } + } + } + + private: + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; + }; + + // Colour, message variants: + // - white: No tests ran. + // - red: Failed [both/all] N test cases, failed [both/all] M assertions. + // - white: Passed [both/all] N test cases (no assertions). + // - red: Failed N tests cases, failed M assertions. + // - green: Passed [both/all] N tests cases with M assertions. + + std::string bothOrAll( std::size_t count ) const { + return count == 1 ? "" : count == 2 ? "both " : "all " ; + } + + void printTotals( const Totals& totals ) const { + if( totals.testCases.total() == 0 ) { + stream << "No tests ran."; + } + else if( totals.testCases.failed == totals.testCases.total() ) { + Colour colour( Colour::ResultError ); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll( totals.assertions.failed ) : ""; + stream << + "Failed " << bothOrAll( totals.testCases.failed ) + << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << qualify_assertions_failed << + pluralise( totals.assertions.failed, "assertion" ) << "."; + } + else if( totals.assertions.total() == 0 ) { + stream << + "Passed " << bothOrAll( totals.testCases.total() ) + << pluralise( totals.testCases.total(), "test case" ) + << " (no assertions)."; + } + else if( totals.assertions.failed ) { + Colour colour( Colour::ResultError ); + stream << + "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << pluralise( totals.assertions.failed, "assertion" ) << "."; + } + else { + Colour colour( Colour::ResultSuccess ); + stream << + "Passed " << bothOrAll( totals.testCases.passed ) + << pluralise( totals.testCases.passed, "test case" ) << + " with " << pluralise( totals.assertions.passed, "assertion" ) << "."; + } + } + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch + +namespace Catch { + // These are all here to avoid warnings about not having any out of line + // virtual methods + NonCopyable::~NonCopyable() {} + IShared::~IShared() {} + IStream::~IStream() CATCH_NOEXCEPT {} + FileStream::~FileStream() CATCH_NOEXCEPT {} + CoutStream::~CoutStream() CATCH_NOEXCEPT {} + DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} + StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} + IContext::~IContext() {} + IResultCapture::~IResultCapture() {} + ITestCase::~ITestCase() {} + ITestCaseRegistry::~ITestCaseRegistry() {} + IRegistryHub::~IRegistryHub() {} + IMutableRegistryHub::~IMutableRegistryHub() {} + IExceptionTranslator::~IExceptionTranslator() {} + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} + IReporter::~IReporter() {} + IReporterFactory::~IReporterFactory() {} + IReporterRegistry::~IReporterRegistry() {} + IStreamingReporter::~IStreamingReporter() {} + AssertionStats::~AssertionStats() {} + SectionStats::~SectionStats() {} + TestCaseStats::~TestCaseStats() {} + TestGroupStats::~TestGroupStats() {} + TestRunStats::~TestRunStats() {} + CumulativeReporterBase::SectionNode::~SectionNode() {} + CumulativeReporterBase::~CumulativeReporterBase() {} + + StreamingReporterBase::~StreamingReporterBase() {} + ConsoleReporter::~ConsoleReporter() {} + CompactReporter::~CompactReporter() {} + IRunner::~IRunner() {} + IMutableContext::~IMutableContext() {} + IConfig::~IConfig() {} + XmlReporter::~XmlReporter() {} + JunitReporter::~JunitReporter() {} + TestRegistry::~TestRegistry() {} + FreeFunctionTestCase::~FreeFunctionTestCase() {} + IGeneratorInfo::~IGeneratorInfo() {} + IGeneratorsForTest::~IGeneratorsForTest() {} + WildcardPattern::~WildcardPattern() {} + TestSpec::Pattern::~Pattern() {} + TestSpec::NamePattern::~NamePattern() {} + TestSpec::TagPattern::~TagPattern() {} + TestSpec::ExcludedPattern::~ExcludedPattern() {} + + Matchers::Impl::StdString::Equals::~Equals() {} + Matchers::Impl::StdString::Contains::~Contains() {} + Matchers::Impl::StdString::StartsWith::~StartsWith() {} + Matchers::Impl::StdString::EndsWith::~EndsWith() {} + + void Config::dummy() {} + + namespace TestCaseTracking { + ITracker::~ITracker() {} + TrackerBase::~TrackerBase() {} + SectionTracker::~SectionTracker() {} + IndexTracker::~IndexTracker() {} + } +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif + +#ifdef CATCH_CONFIG_MAIN +// #included from: internal/catch_default_main.hpp +#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED + +#ifndef __OBJC__ + +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { + return Catch::Session().run( argc, argv ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char* const*)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return result; +} + +#endif // __OBJC__ + +#endif + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +////// + +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) +#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) + +#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" ) +#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) + +#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) +#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) +#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) +#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) +#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) + +#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" ) +#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) + +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) +#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) +#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) + #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) +#else + #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) + #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) + #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) +#endif +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) +#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) +#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) +#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) +#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) +#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) +#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) + +#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" ) +#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) + +#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) +#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) +#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) +#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) +#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) + +#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" ) +#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) + +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) + +#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) +#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) +#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) +#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) + #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) +#else + #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) + #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) + #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) +#endif +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) +#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) +#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) +#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) +#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) +#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) + +using Catch::Detail::Approx; + +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + diff --git a/tests/runTests.cpp b/tests/runTests.cpp new file mode 100644 index 00000000..dd58b009 --- /dev/null +++ b/tests/runTests.cpp @@ -0,0 +1,28 @@ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +//! central compiler flag whether or not debug mode is enabled +#define IN_DEBUG_MODE ((defined(_DEBUG)) || (!defined (NDEBUG))) + +//////////////// CENTRAL LOGGING LIB ////////////////// + +#include "easylogging++.h" + +// initialize logging for binary +INITIALIZE_EASYLOGGINGPP + + +//////////////// SETUP TESTING LIB ///////////////////// + +// make this the main test runner +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" + + + +// don't do anything else, its done via the compiler.. +