82 Commits

Author SHA1 Message Date
d4fa8b43a4 Actualiser src/global.mk 2025-06-12 14:22:23 +00:00
b7552200bd Actualiser tools/ecoPCRFormat.py 2025-06-12 13:58:59 +00:00
791aeb0ef9 Actualiser src/libecoPCR/ecotax.c 2025-06-12 13:33:51 +00:00
1e3f82bb51 Actualiser src/libecoPCR/ecorank.c 2025-06-12 13:32:53 +00:00
f1ef2caae6 Supprimer tools/ecoPCRFormat23.py 2025-06-12 13:29:57 +00:00
680cc4d7a2 Actualiser tools/ecoPCRFormat.py 2025-06-12 13:29:46 +00:00
09f3e19f32 Ajouter tools/ecoPCRFormat23.py 2025-06-12 08:53:59 +00:00
08debff2ac Actualiser src/Makefile 2025-06-12 08:35:23 +00:00
e16e9bfa0c Actualiser src/global.mk 2025-06-12 08:34:54 +00:00
7fbea9d63f adds the binary to the gitignore 2024-05-24 14:27:17 +02:00
9a9fb383ad standardize uint type names 2024-05-24 14:26:22 +02:00
8c1668faa4 patch some compile warnings 2024-05-23 17:46:00 +02:00
92826de147 Update to consider evolution of the language 2023-06-29 12:12:46 +02:00
73236c72a8 version 0.5: ecoPrimers can now read *.ldx files (local taxa) 2019-01-22 15:51:43 +01:00
eb8d44528d Switch to version 0.4 2017-11-29 14:38:23 +01:00
2b3a331602 Changed the behaviour if trying to realloc a memory chunk of size 0 to
be consistent across systems (an error would be generated on Ubuntu when
no primers found)
2017-11-29 14:25:14 +01:00
a75191bbe6 Moved the print of an error so the program does not abort before it is
printed
2017-11-29 10:46:48 +01:00
3cfbf8ba42 clean *.P with Makefile 2015-07-17 15:48:35 +02:00
efb4fba78c Convert svn:ignore properties to .gitignore. 2015-05-16 23:45:29 +02:00
66c0511f09 MOD : error in the stop condition in a for loop when printing results (may lead to a segv)
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@420 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-05-14 13:02:44 +00:00
ea1ca1b6d9 Modified LIBPATH
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@413 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-04-27 06:53:47 +00:00
58a65f7ff4 REMOVE libapat
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@412 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-04-27 06:50:22 +00:00
4315aecbf0 ADD libapat so that everything is included when fetching the project from svn
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@411 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-04-26 16:23:35 +00:00
aedee0c154 Added some comments
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@400 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-02-29 14:12:17 +00:00
9e36754fef Added some comments
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@399 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-02-27 14:57:03 +00:00
9262e954cf added "include <stdlib.h>"
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@398 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-02-22 11:25:30 +00:00
1f5a30b0df My complete changes on my laptop, with specificity bug fix + ahocorasick + sets
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@393 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2012-01-03 21:05:31 +00:00
19887e9a46 updated makefile, changed project name
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@295 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2011-05-09 13:13:24 +00:00
e77c6e5339 updated version
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@291 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2011-02-04 23:46:02 +00:00
4c9c8382fe fixed segmentation fault reported by Pierre.
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@289 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-12-16 20:56:57 +00:00
5d8103f4b4 added check for filtering pairs having specificity below a given threshold given using -T option
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@288 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-12-13 17:09:54 +00:00
ca1e9d8899 fixed specificity and pairing bugs
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@287 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-11-29 22:57:56 +00:00
dd08d73dda Added code for building sets of primers and -p command line option
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@279 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-09-13 09:44:53 +00:00
e483b17e18 Patch average size of amplicon computation
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@275 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-08-30 12:14:40 +00:00
396d6e2028 Patch average size of amplicon computation
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@274 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-08-30 12:13:54 +00:00
3f488baa6f Patch stat output
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@273 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-08-30 12:13:28 +00:00
fd13788289 Add sequence length in database list output (option -A)
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@270 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-08-25 12:59:30 +00:00
82d5e21471 Add sequence length in database list output (option -A)
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@269 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-08-25 12:55:58 +00:00
0f4f2a74fe Revert previous commit
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@261 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2010-06-15 05:03:20 +00:00
b3d6acae76 git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@256 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2010-04-07 11:32:41 +00:00
89576b96fa Patch taxon example/counterexample selection
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@237 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-11-09 14:50:35 +00:00
9e6b924c92 Add a new option -E to considere some example sequences as counterexamples
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@236 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-10-19 17:27:51 +00:00
2737cf0606 Add a new option -E to considere some example sequences as counterexamples
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@235 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-10-19 17:24:46 +00:00
6f5f2a16f3 Change 1 : patch the help message to take into account option added and the new output format.
Change 2 : Change the used rules to define example and counter example taxon sets.
			By default all taxa are example taxa and no counterexample taxa are used.
			By using -r option (one or several time) you could restict example taxa to a subset of taxa
			In old version all taxa not in example set are in the counterexample set.
			Now restrict example set with -r option doesn't define the counter example set.
			You must use -i to define the conterexample set in a similar way or -r option for example taxa.  

git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@234 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-10-12 13:31:41 +00:00
088b5c09d0 fixed a small problem of operator precedence in "if (w1 ^ w1a != 0) continue;" by adding parentheses.
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@233 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-31 09:52:04 +00:00
f1f8562918 corrected mask bits for base pairs
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@232 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-30 22:30:04 +00:00
1911880bb9 Added Code to make sure that if -3 option is given then 3' end must match upto given number of base pairs
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@231 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-30 22:20:07 +00:00
494791d133 Reintroduce -3 options to allow strict match at 3' end
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@230 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-28 21:07:27 +00:00
79cadf0809 Patch minimum tm computation to limit estimation on example sequences
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@229 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-18 22:33:18 +00:00
419bda966d Patch minimum tm computation
Add -A option to list all id present in the DB for helping in -R usage

git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@228 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-18 22:16:18 +00:00
455bf63949 Deleted some supurious files
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@227 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-17 22:29:19 +00:00
b625941d72 Committed thermostats.c
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@226 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-17 22:11:40 +00:00
ba26734e9b committed thermostats.h
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@225 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-17 15:02:12 +00:00
50c26e81b9 Added command line options for:
a. 'salt method' like "-m 1" or "-m 2" here 1 is for SANTALUCIA and 2 is for OWCZARZY
b. 'salt concentration' "-a 0.01" valid range is from 0.01 to 0.3. if not specified then we use default 0.05

git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@224 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-14 22:23:18 +00:00
e79738e170 commit -m "Cleaned code for thermodynamics properties and added Melting Temperature for approximate version of strict repeats. Also cleaned printing code.
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@223 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-13 09:26:19 +00:00
91753ace82 Added thermodynamics properties
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@222 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-07 12:35:55 +00:00
f142d0e904 Added thermodynamics properties
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@221 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-07-07 12:35:17 +00:00
b4d8842f31 Add minus -R option to localize aplicon over one of the sequence database.
This option add two column on the right of the output table with the primers location 
and the barcode sequence (small patch)

git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@220 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-06-24 08:12:50 +00:00
1cae92e963 Add minus -R option to localize aplicon over one of the sequence database.
This option add two column on the right of the output table with the primers location 
and the barcode sequence    

git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@219 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-06-24 08:09:39 +00:00
3a617890ca New option for reference sequence
and bug correction for insequence count

git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@218 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-06-23 14:11:39 +00:00
40644bc85f git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@216 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2009-05-13 09:26:57 +00:00
c192908469 git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@215 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2009-05-13 09:18:24 +00:00
b0521a7e15 Accept to deal with sequence in lower case
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@214 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-13 07:33:39 +00:00
b7c1640042 New version 0.3 with filtering on short words
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@213 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-13 06:51:25 +00:00
5dc55c7f53 Some linux patch
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@212 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-12 15:48:59 +00:00
04ee4e531c remove final binary from archive
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@211 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-12 09:17:52 +00:00
b092497eaf add property to ignore *.P files
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@210 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-12 09:16:09 +00:00
6624181788 remove *.P files
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@209 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-12 09:13:13 +00:00
81ada091bf Add option to log memory statistics during primer identifications
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@208 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-05-12 09:06:43 +00:00
c5a430ea80 git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@207 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2009-04-28 21:20:20 +00:00
c308fb2edc Patch eco_malloc functions to allow more than 4Gb allocation on 64bits version
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@206 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-04-28 08:19:50 +00:00
796274d746 some patches to compile on linux
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@205 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-04-23 22:22:27 +00:00
c36bc5e838 Second run of patch
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@204 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-04-23 11:38:52 +00:00
313dd59f5a First run of patch
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@203 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-04-22 08:15:18 +00:00
e869d6daed git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@202 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2009-04-20 08:40:32 +00:00
93b327285a git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@201 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2009-04-20 08:40:14 +00:00
e3d922e103 Merge of eric-test branche to the trunk
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@200 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-04-20 08:38:41 +00:00
b8af5dd65f Merge of eric-test branche to the trunk
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@199 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-04-20 08:31:30 +00:00
4f9d76f0f2 New version based on sort them merge algorithm
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@182 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-03-04 22:37:58 +00:00
b5b0ca7e9d git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@181 60f365c0-8329-0410-b2a4-ec073aeeaa1d 2009-03-04 22:35:06 +00:00
64838c1cdf New version based on sort them merge algorithm
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@180 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-03-04 22:32:55 +00:00
6d8bb449d5 delete old version
git-svn-id: https://www.grenoble.prabi.fr/svn/LECASofts/ecoPrimers/trunk@179 60f365c0-8329-0410-b2a4-ec073aeeaa1d
2009-03-04 22:22:48 +00:00
75 changed files with 9350 additions and 5170 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject>
@ -11,15 +11,16 @@
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="ecoPrimers" buildProperties="" id="cdt.managedbuild.toolchain.gnu.macosx.base.2134184396" name="MacOSX GCC" parent="org.eclipse.cdt.build.core.emptycfg">
<configuration artifactName="ecoPrimers" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.macosx.base.2134184396" name="MacOSX GCC" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.macosx.base.2134184396.1840911077" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.macosx.base.766054112" name="cdt.managedbuild.toolchain.gnu.macosx.base" superClass="cdt.managedbuild.toolchain.gnu.macosx.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.MachO" id="cdt.managedbuild.target.gnu.platform.macosx.base.2057035265" name="Debug Platform" osList="macosx" superClass="cdt.managedbuild.target.gnu.platform.macosx.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.macosx.base.783726363" managedBuildOn="false" name="Gnu Make Builder.MacOSX GCC" superClass="cdt.managedbuild.target.gnu.builder.macosx.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.macosx.base.783726363" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.macosx.base"/>
<tool id="cdt.managedbuild.tool.macosx.c.linker.macosx.base.914103467" name="MacOS X C Linker" superClass="cdt.managedbuild.tool.macosx.c.linker.macosx.base">
<inputType id="cdt.managedbuild.tool.macosx.c.linker.input.62980206" superClass="cdt.managedbuild.tool.macosx.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
@ -28,17 +29,23 @@
</tool>
<tool id="cdt.managedbuild.tool.macosx.cpp.linker.macosx.base.691108439" name="MacOS X C++ Linker" superClass="cdt.managedbuild.tool.macosx.cpp.linker.macosx.base"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.macosx.base.695639877" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.macosx.base">
<option id="gnu.both.asm.option.include.paths.1544375094" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1507665054" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.macosx.base.1786370580" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.macosx.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.base.454329831" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.base"/>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.macosx.base.1928774909" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.macosx.base">
<option id="gnu.c.compiler.option.include.paths.823251305" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="/usr/include"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.330854350" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
@ -121,28 +128,91 @@
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfile">
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.macosx.base.2134184396;cdt.managedbuild.toolchain.gnu.macosx.base.2134184396.1840911077;cdt.managedbuild.tool.gnu.c.compiler.macosx.base.1928774909;cdt.managedbuild.tool.gnu.c.compiler.input.330854350">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -v ${plugin_state_location}/${specs_file}" command="${XL_compilerRoot}/xlc" useDefault="true"/>
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.xlc.core.XLCManagedMakePerProjectProfileCPP">
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="false"/>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -v ${plugin_state_location}/${specs_file}" command="${XL_compilerRoot}/xlC" useDefault="true"/>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
*.o
/src/*.P
/src/*.a
/src/ecoPrimer
/src/libecoPCR/*.P
/src/libecoPCR/*.a
/src/libecoPCR/*.o
/src/libecoprimer/*.P
/src/libecoprimer/*.a
/src/libecoprimer/*.o
/src/libthermo/*.P
/src/libthermo/*.a
/src/libthermo/*.o
phylonorway.*
src/ecoPrimers

View File

@ -5,45 +5,26 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
@ -54,13 +35,37 @@
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
@ -73,5 +78,6 @@
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

7
.pydevproject Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Python 2.6</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
</pydev_project>

1
VERSION Normal file
View File

@ -0,0 +1 @@
0.5

View File

@ -1,4 +1,4 @@
EXEC=ecoPrimer
EXEC=ecoPrimers
PRIMER_SRC= ecoprimer.c
PRIMER_OBJ= $(patsubst %.c,%.o,$(PRIMER_SRC))
@ -6,11 +6,12 @@ PRIMER_OBJ= $(patsubst %.c,%.o,$(PRIMER_SRC))
SRCS= $(PRIMER_SRC)
LIB= -lecoPCR -lapat -lKMRK -lz -lm
LIB= -lecoprimer -lecoPCR -lthermo -lz -lm
LIBFILE= libecoPCR/libecoPCR.a \
libecoprimer/libecoprimer.a \
libthermo/libthermo.a \
LIBFILE= libapat/libapat.a \
libecoPCR/libecoPCR.a \
libKMRK/libKMRK.a
include global.mk
@ -26,8 +27,8 @@ all: $(EXEC)
# executable compilation and link
ecoPrimer: $(PRIMER_OBJ) $(LIBFILE)
$(CC) $(LDFLAGS) -o $@ $< $(LIBPATH) $(LIB)
ecoPrimers: $(PRIMER_OBJ) $(LIBFILE)
$(CC) $(LDFLAGS) -O5 -o $@ $< $(LIBPATH) $(LIB)
########
@ -36,15 +37,14 @@ ecoPrimer: $(PRIMER_OBJ) $(LIBFILE)
#
########
libapat/libapat.a:
$(MAKE) -C libapat
libecoPCR/libecoPCR.a:
$(MAKE) -C libecoPCR
libKMRK/libKMRK.a:
$(MAKE) -C libKMRK
libecoprimer/libecoprimer.a:
$(MAKE) -C libecoprimer
libthermo/libthermo.a:
$(MAKE) -C libthermo
########
#
@ -54,10 +54,26 @@ libKMRK/libKMRK.a:
clean:
rm -f *.o
rm -f *.P
rm -f $(EXEC)
$(MAKE) -C libapat clean
$(MAKE) -C libecoPCR clean
$(MAKE) -C libKMRK clean
$(MAKE) -C libecoprimer clean
$(MAKE) -C libthermo clean
########
#
# clean for k2 to remove .o and .P files
#
########
k2clean:
rm -f *.o
rm -f *.P
rm -f libecoPCR/*.o
rm -f libecoPCR/*.P
rm -f libecoprimer/*.o
rm -f libecoprimer/*.P
rm -f libthermo/*.o
rm -f libthermo/*.P

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,12 @@
MACHINE=MAC_OS_X
LIBPATH= -Llibapat -LlibecoPCR -LlibKMRK
MACHINE=LINUX
LIBPATH= -LlibecoPCR -Llibecoprimer -Llibthermo -L/usr/local/lib
MAKEDEPEND = gcc -D$(MACHINE) -M $(CPPFLAGS) -o $*.d $<
CC=gcc
CFLAGS= -W -Wall -O2 -g
CFLAGS= -W -Wall -O5
#CFLAGS= -W -Wall -O5 -m64 -g
#CFLAGS= -W -Wall -O0 -m64 -g
#CFLAGS= -W -Wall -O5 -fast -g
default: all

File diff suppressed because it is too large Load Diff

View File

@ -1,309 +0,0 @@
#ifndef _KMRK_H_
#define _KMRK_H_
/********************************************
********************************************
**
** Declaration of struct
**
********************************************
********************************************/
#include <stdint.h>
#include "repseek_types.h"
#include "KMRK_mask.h"
/**
* Structure used to manipulate simultanously
* the v and n vector
*
*/
typedef struct {
int32_t size; /**< size of vectors */
int32_t seqCount; /**< count of concatenated sequences */
int32_t complement; /**< if seqCount > 1 and complement !=0
* then second sequence is the inverted complement
* strand of first one */
int32_t symbmax;
int32_t* v; /**< sequence vector */
int32_t* n; /**< linked list vector */
int32_t limits[1]; /**< array of end limits of concatenated
* sequences in v (array size is seqCount) */
} vn_type;
/********************************************
********************************************
**
** Declaration of public macro
**
********************************************
********************************************/
// Return a pointer to a vector from a vn_type structure
#define GETVECTOR(x,vector) (((x)->vector) - 1)
#define IS_MARKED(x,i) ((x)[i] < 0)
#define MARK(x,i) ((x)[i]) = -ABS((x)[i])
#define UNMARK(x,i) ((x)[i]) = ABS((x)[i])
#define SET(x,i,v) ((x)[i]) = (v)
// set and mark in one operation
#define SETMARKED(x,i,v) ((x)[i]) = -(v)
//internal macro
#define GET(x,i) ABS((x)[i])
// get symbole at position i in vector x
#define SYMBOLE(x,i) ((IS_MARKED((x),(i))) ? (i): (GET(x,i)))
/**
* Macro used to declare a pointer to a quorum function.
*
* @param name name of the pointer
*
*/
#define KMRK_QUORUM_FUNC_PTR(name) int32_t (*name)(vn_type* x, \
int32_t pos, \
int32_t count, \
int32_t countSeq)
/**
* Macro used to declare a pointer to an initialisation function.
*
* @param name name of the pointer
* @param quorum name used for the quorum assiciated function
*
* @see KMRK_QUORUM_FUNC_PTR
*
*/
#define KMRK_INIT_FUNC_PTR(name,quorum) vn_type* (*name)(char *sequence, \
int32_t complement, \
int32_t count, \
int32_t countSeq, \
int32_t *k, \
KMRK_QUORUM_FUNC_PTR(quorum),\
masked_area_table_t *mask)
/********************************************
********************************************
**
** Declaration of public functions
**
********************************************
********************************************/
/**
* Initialise a vn_type record from one sequence to run KMRK algorithm
*
* @param sequence pointer to a C string containing the sequence
* @param complement != 0 means that seq one and two are the two strands of
* the same sequence.
* @param count parameter count passed to the quorun function
* @param countSeq parametter countSeq passed to the quorun function
* @param k length of the word represented by each symbole of v.
* k is an output parametter
* @param quorum pointer to a quorum function
*
* @return a pointer to vn_type structure correctly initialized
* to be used by KMRK_RunKMRK
*
* @see KMRK_HashOneSequence
*/
vn_type* KMRK_InitOneSequence(char *sequence,
int32_t complement,
int32_t count,
int32_t countSeq,
int32_t *k,
KMRK_QUORUM_FUNC_PTR(quorum),
masked_area_table_t *mask);
/**
* Initialise a vn_type record from one sequence to run KMRK algorithme.
* In more than KMRK_InitOneSequence, KMRK_HashOneSequence construct
* word of len k with an hash algorithm. k used is a function of
* sequence size and alphabet size. If calculed k is superior to lmax
* then k = lmax.
*
* @param sequence pointer to a C string containing the sequence
* @param complement != 0 means that seq one and two are the two strands of
* the same sequence.
* @param count parametter count passed to the quorun function
* @param countSeq parametter countSeq passed to the quorun function
* @param k maximum length of the created word (input)
* length of the word represented by each symbole
* of v (output).
* @param quorum pointer to a quorum function
*
* @return a pointer to vn_type structure correctly initialized
* to be used by KMRK_RunKMRK
*
* @see KMRK_InitOneSequence
*/
vn_type* KMRK_HashOneSequence(char *sequence,
int32_t complement,
int32_t count,
int32_t countSeq,
int32_t *k,
KMRK_QUORUM_FUNC_PTR(quorum),
masked_area_table_t *mask);
/**
* An example of quorum function testing than a factor is
* present a least two times. Because of definition of this
* quorum function count and countSeq parametter have no meanning
* in this instance of quorum function
*
* @param x a pointer to vn_type structure to check
* @param pos position in n of the beginning of the linked list to test
* @param count minimal number of occurence of factor
* @param countSeq minimal number of sequences concerned
*
* @return 1 if quorum is ok 0 otherwise.
*/
int32_t KMRK_CoupleQuorum(vn_type* x,
int32_t pos,
int32_t count,
int32_t countSeq);
/**
* An example of quorum function testing than a factor is
* present a least two times in the direct strand of a sequence or
* at least one time in the direct strand and one time in the reverse
* strand. Because of definition of this
* quorum function count and countSeq parametter have no meanning
* in this instance of quorum function
*
* @param x a pointer to vn_type structure to check
* @param pos position in n of the beginning of the linked list to test
* @param count minimal number of occurence of factor
* @param countSeq minimal number of sequences concerned
*
* @return 1 if quorum is ok 0 otherwise.
*/
int32_t KMRK_DirInvQuorum(vn_type* x,
int32_t pos,
int32_t count,
int32_t countSeq);
/**
* An example of quorum function testing than a factor is
* present a least one time in the direct strand and one time in the reverse
* strand. Because of definition of this
* quorum function count and countSeq parametter have no meanning
* in this instance of quorum function
*
* @param x a pointer to vn_type structure to check
* @param pos position in n of the beginning of the linked list to test
* @param count minimal number of occurence of factor
* @param countSeq minimal number of sequences concerned
*
* @return 1 if quorum is ok 0 otherwise.
*/
int32_t KMRK_InvQuorum(vn_type* x,
int32_t pos,
int32_t count,
int32_t countSeq);
int32_t KMRK_Int12Quorum(vn_type* x,
int32_t pos,
int32_t count,
int32_t countSeq);
int32_t KMRK_IntInv12Quorum(vn_type* x,
int32_t pos,
int32_t count,
int32_t countSeq);
int32_t KMRK_IntDirInv12Quorum(vn_type* x,
int32_t pos,
int32_t count,
int32_t countSeq);
/**
* realize one cycle of KMR.
*
* @param x a pointer to vn_type created by an intialisation
* function or returned by this function.
* @param k step used to join two words
* @param count parametter count passed to the quorun function
* @param countSeq parametter countSeq passed to the quorun function
* @param KMRK_QUORUM_FUNC_PTR quorum pointer to a quorum function
*/
void KMRK_RunKMRK(vn_type *x,
int32_t k,
int32_t count,
int32_t countSeq,
KMRK_QUORUM_FUNC_PTR(quorum));
/**
* realises serveral run of KMR cycle to make from a sequence
* a vn_type structure describing sequences of factors of a precise size.
*
* @param sequence pointer to a C string containing the sequence
* @param size word size to construct
* @param count parametter count passed to the quorun function
* @param countSeq parametter countSeq passed to the quorun function
* @param quorum pointer to a quorum function
* @param init pointer to a initialisation function
*
* @return a vn_type pointer to a structure containing sequences of factors
*/
vn_type *KMRK_RunTo(char *sequence,
int32_t size,
int32_t complement,
int32_t count,
int32_t countSeq,
KMRK_QUORUM_FUNC_PTR(quorum),
KMRK_INIT_FUNC_PTR(init,quorum),
masked_area_table_t *mask);
/**
* free memory associated to a vn_type pointer
*
* @param x a pointer to vn_type structure
*/
void KMRK_FreeVN(vn_type *x);
int32_t KMRK_upperCoupleCount(vn_type *x);
int32_t KMRK_upperInvertedCount(vn_type* x,int32_t wordsize);
int32_t KMRK_upperInterCount(vn_type* x,int32_t seq1,int32_t seq2,int32_t wordsize);
void KMRK_markStart(vn_type* x);
#endif //_KMRK_H_

View File

@ -1,908 +0,0 @@
#include "KMRK_Seeds.h"
#include "memory.h"
#include <stdlib.h>
#include <string.h>
#include "sequence.h"
static void SetMultipleLenInvSeeds(SmallSeed_type* seeds,
int32_t nseeds,
int32_t wordSize,
int8_t same,
AllSeeds_type *PtrAllSeeds);
/*
Concatenate
DirSeq\0InvSeq\0
*/
static char* makeDirInvSeq(char* seq, int32_t size)
{
char *SeqInv;
seq = (char *)MyRealloc( (void *)seq, (size*2+2)*sizeof(char),
(size+1)* sizeof(char), "Cannot allocate space for reverse sequence");
SeqInv= seq + size + 1;
seq[size]=0;
invseq(seq, SeqInv);
seq[size]='@';
SeqInv[size]=0;
return seq;
}
/*
Merge the seq1 with seq2
*/
static char *merge2seq(char* seq1, char* seq2,
int32_t size1, int32_t size2)
{
char * dest;
seq1 = (char *)MyRealloc((void *)seq1, (size1+size2+2) *sizeof(char),
(size1+1)*sizeof(char), "Cannot allocate space for reverse sequence");
dest = seq1 + size1 + 1;
seq1[size1]='@';
memcpy(dest,seq2,size2);
dest[size2]=0;
return seq1;
}
static int32_t dirDelta(SmallSeed_type* seed)
{
return seed->pos2 - seed->pos1;
}
void KMRK_SetMultipleLenDirSeeds(SmallSeed_type* seeds,
int32_t nseeds,
int32_t wordSize,
AllSeeds_type *PtrAllSeeds)
{
int32_t i,j; /* dummy counters j=kept seeds ; i = current seed */
int32_t curLen=wordSize; /* Length of the current seed */
int32_t delta;
SmallSeed_type *mainSeed;
SmallSeed_type *curSeed;
int32_t add;
/* fprintf(stderr,"New Version\n");*/
KMRK_sortSeeds(seeds,nseeds,KMRK_cmpDeltaSeedsPos);
for(j=0,mainSeed=seeds ;
j < nseeds;
j=i,mainSeed=curSeed)
{
/* foreach seed */
delta = dirDelta(mainSeed);
curLen=wordSize;
for (i=j+1,curSeed=mainSeed+1;
i < nseeds &&
dirDelta(curSeed)==delta &&
(curSeed->pos1 - mainSeed->pos1) <= curLen;
i++,curSeed++)
{
add=wordSize - mainSeed->pos1 - curLen + curSeed->pos1;
if (add < 0) add = 0;
curLen+=add;
}
KMRK_pushSeed(PtrAllSeeds,
seeds[j].pos1,seeds[j].pos2,
curLen,
1);
}
}
static int32_t invDelta(SmallSeed_type* seed)
{
return seed->pos2 + seed->pos1;
}
static void SetMultipleLenInvSeeds(SmallSeed_type* seeds,
int32_t nseeds,
int32_t wordSize,
int8_t same,
AllSeeds_type *PtrAllSeeds)
{
int32_t i,j; /* dummy counters j=kept seeds ; i = current seed */
int32_t curLen=wordSize; /* Length of the current seed */
int32_t delta;
int32_t pos2;
SmallSeed_type *mainSeed;
SmallSeed_type *curSeed;
int32_t add;
/* fprintf(stderr,"New Version\n");*/
KMRK_sortSeeds(seeds,nseeds,KMRK_cmpDeltaInvSeedsPos);
for(j=0,mainSeed=seeds ;
j < nseeds;
j=i,mainSeed=curSeed)
{
/* foreach seed */
delta = invDelta(mainSeed);
curLen=wordSize;
for (i=j+1,curSeed=mainSeed+1;
i < nseeds &&
invDelta(curSeed)==delta &&
(curSeed->pos1 - mainSeed->pos1) <= curLen;
i++,curSeed++)
{
add=wordSize - mainSeed->pos1 - curLen + curSeed->pos1;
if (add < 0) add = 0;
curLen+=add;
}
if ( same && (seeds[j].pos1+curLen>= seeds[i-1].pos2))
{
curLen = (seeds[i-1].pos2 - seeds[j].pos1 + 1) * 2;
pos2 = seeds[j].pos1;
}
else
pos2 = seeds[i-1].pos2;
KMRK_pushSeed(PtrAllSeeds,
seeds[j].pos1,pos2,
curLen,
0);
}
}
AllSeeds_type *KMRK_allocSeeds(AllSeeds_type *AllSeeds,
int32_t size,
int8_t opt_dir,
int8_t opt_inv)
{
AllSeeds_type *reponse;
if(opt_inv != 1 && opt_dir != 1)
{
fprintf(stderr,"AllocSeeds: requiere at least "
"one of opt_dir and opt_inv to be 1\n");
exit(4);
}
reponse = AllSeeds;
if (!reponse)
reponse = MyCalloc( 1, sizeof(AllSeeds_type),"KMRK_allocSeeds: cannot allocate new data structure");
if(opt_dir)
{
if (reponse->dirSeeds==NULL)
reponse->dirSeeds = (Seed_type *)MyCalloc( size,sizeof(Seed_type),"KMRK_allocSeeds: cannot allocate new data structure");
else
{
if(size)
reponse->dirSeeds = (Seed_type *)MyRealloc( (void *)reponse->dirSeeds,
size*sizeof(Seed_type), reponse->cDirSeeds*sizeof(Seed_type),
"allocSeeds: cannot reallocate data structure" );
else
{
MyFree(reponse->dirSeeds, reponse->cDirSeeds*sizeof(Seed_type));
reponse->dirSeeds=NULL;
reponse->cDirSeeds=0;
}
}
reponse->cDirSeeds=size;
}
if(opt_inv)
{
if (reponse->invSeeds==NULL)
reponse->invSeeds = (Seed_type *)MyCalloc( size, sizeof(Seed_type),"KMRK_allocSeeds: cannot allocate new data structure");
else
{
if(size)
reponse->invSeeds = (Seed_type *)MyRealloc( (void *)reponse->invSeeds,
size*sizeof(Seed_type), reponse->cInvSeeds*sizeof(Seed_type),
"allocSeeds: cannot reallocate data structure" );
else
{
MyFree(reponse->invSeeds, reponse->cInvSeeds*sizeof(Seed_type));
reponse->invSeeds=NULL;
reponse->cInvSeeds=0;
}
}
reponse->cInvSeeds=size;
}
return reponse;
}
void KMRK_freeSeeds(AllSeeds_type *AllSeeds)
{
if (!AllSeeds)
return;
if (AllSeeds->dirSeeds)
MyFree(AllSeeds->dirSeeds, AllSeeds->cDirSeeds*sizeof(Seed_type) );
AllSeeds->dirSeeds=NULL;
if (AllSeeds->invSeeds)
MyFree(AllSeeds->invSeeds, AllSeeds->cInvSeeds*sizeof(Seed_type) );
AllSeeds->dirSeeds=NULL;
MyFree(AllSeeds, 1*sizeof( AllSeeds_type ) );
}
void KMRK_compactSeeds(AllSeeds_type *AllSeeds)
{
if (AllSeeds)
{
if (AllSeeds->dirSeeds)
KMRK_allocSeeds(AllSeeds,
AllSeeds->nDirSeeds,
1,
0);
if (AllSeeds->invSeeds)
KMRK_allocSeeds(AllSeeds,
AllSeeds->nInvSeeds,
0,
1);
}
}
void KMRK_pushSeed(AllSeeds_type *AllSeeds,
int32_t pos1,
int32_t pos2,
int32_t length,
int8_t dir)
{
Seed_type* stack;
int32_t maxcount;
int32_t index;
if (dir)
{
dir = 1;
stack = AllSeeds->dirSeeds;
maxcount = AllSeeds->cDirSeeds;
index = AllSeeds->nDirSeeds;
}
else
{
dir = 0;
stack = AllSeeds->invSeeds;
maxcount = AllSeeds->cInvSeeds;
index = AllSeeds->nInvSeeds;
}
if (index == maxcount)
{
(void) KMRK_allocSeeds(AllSeeds,
maxcount * 2,
dir,
!dir);
if (dir)
stack = AllSeeds->dirSeeds;
else
stack = AllSeeds->invSeeds;
}
stack+=index;
stack->pos1 = pos1;
stack->pos2 = pos2;
stack->length = length;
if (dir)
AllSeeds->nDirSeeds++;
else
AllSeeds->nInvSeeds++;
}
AllSeeds_type* KMRK_enumerateDirectCouple(AllSeeds_type* Seeds,
int32_t expected,
int32_t wordSize,
vn_type* stack,
int32_t seq)
{
int32_t xmin;
int32_t xmax;
int32_t i;
int32_t j;
int32_t k;
int32_t next;
int32_t* n;
int32_t nseeds;
SmallSeed_type *list;
list = (SmallSeed_type *)MyCalloc( expected, sizeof(SmallSeed_type) ,
"KMRK_enumerateDirectCouple: cannot allocate DirectCouple memory");
nseeds = 0;
n = GETVECTOR(stack,n);
if (seq)
xmin = stack->limits[seq-1];
else
xmin = 0;
xmax = stack->limits[seq];
for (i=1; i <= xmax; i++)
if (IS_MARKED(n,i)) /* Check begining of chained list */
{
/* Look for begining of sequence of interest */
for( ;(i <= xmin) && (i != GET(n,i));
i=GET(n,i));
/* for each factor in sequence of interest */
for (j=i;
(j != GET(n,j)) && (j <= xmax);
j = GET(n,j))
{
next = GET(n,j);
if (next <= xmax)
do
{
k = next;
next = GET(n,k);
list[nseeds].pos1 = j-1;
list[nseeds].pos2 = k-1;
nseeds++;
} while ((k!=next) && (next <= xmax));
}
} ;
Seeds = KMRK_allocSeeds(Seeds,
expected/20+1,
1,0);
/* fprintf(stderr,"Expected direct couple : %d\n",expected);*/
KMRK_SetMultipleLenDirSeeds(list,nseeds,wordSize,Seeds);
MyFree(list, expected*sizeof(SmallSeed_type) );
KMRK_compactSeeds(Seeds);
return Seeds;
}
/*
From KMR-K Stacks to SmallSeeds
*/
AllSeeds_type* KMRK_enumerateInvertedCouple(AllSeeds_type* Seeds,
int32_t expected,
int32_t wordSize,
vn_type* stack)
{
int32_t xmax;
int32_t invmax;
int32_t posinv;
int32_t i;
int32_t j;
int32_t k;
int32_t memk;
int32_t* n;
int32_t next;
int32_t nseeds; /* number of seeds */
SmallSeed_type *list; /* seed list with only pos1 and pos2 --simple output from kmrk */
list = (SmallSeed_type *)MyCalloc( expected, sizeof(SmallSeed_type) ,
"KMRK_enumerateInvertedCouple: cannot allocate InvertedCouple memory");
nseeds = 0;
n = GETVECTOR(stack,n);
xmax = stack->limits[0];
invmax = stack->limits[1];
for (i=1; i <= xmax; i++)
if (IS_MARKED(n,i))
{
for(memk=i ;
(memk < xmax) &&
memk != GET(n,memk) &&
(memk <= invmax);
memk=GET(n,memk));
if ((memk > xmax) && (memk <= invmax))
for (j=i;
(j <= xmax) && (j != GET(n,j));
j=GET(n,j))
{
next = memk;
do
{
k = next;
next = GET(n,k);
posinv = 2 * xmax - k -wordSize + 3;
if (j <= posinv)
{
list[nseeds].pos1=j-1;
list[nseeds].pos2=posinv-1;
nseeds++;
}
} while ((next <= invmax) && (k != next));
}
}
Seeds = KMRK_allocSeeds(Seeds,
expected/20+1,
0,1);
/* fprintf(stderr,"Expected inverted couple : %d\n",expected);*/
SetMultipleLenInvSeeds(list,nseeds,wordSize,1,Seeds); /* turn the Small seeds into merged seeds */
MyFree(list, expected*sizeof(SmallSeed_type) );
KMRK_compactSeeds(Seeds);
return Seeds;
}
AllSeeds_type* KMRK_enumerateInterCouple(AllSeeds_type* Seeds,
int32_t seq1,
int32_t seq2,
int32_t expected,
int32_t wordSize,
vn_type* stack)
{
int32_t xmin;
int32_t xmax;
int32_t ymax;
int32_t ymin;
int32_t pos1;
int32_t pos2;
int32_t i;
int32_t j;
int32_t k;
int32_t memj;
int32_t memk;
int32_t* n;
int32_t next;
int32_t nseeds;
SmallSeed_type *list;
nseeds=0;
list = (SmallSeed_type *)MyCalloc( expected, sizeof(SmallSeed_type) ,
"KMRK_enumerateInterCouple: cannot allocate InterCouple memory");
n = GETVECTOR(stack,n);
if (seq1==0)
xmin=0;
else
xmin = stack->limits[seq1-1];
xmax = stack->limits[seq1];
ymin = stack->limits[seq2-1];
ymax = stack->limits[seq2];
for (i=1; i <= xmax; i++)
if (IS_MARKED(n,i))
{
for(memj=i ;
(memj < xmin) &&
memj != GET(n,memj);
memj=GET(n,memj));
if ((memj > xmin) && (memj <= xmax))
{
for(memk=memj ;
(memk < ymin) &&
memk != GET(n,memk);
memk=GET(n,memk));
if ((memk > ymin) && (memk <= ymax))
for (j=memj;
(j <= xmax) && (j != GET(n,j));
j=GET(n,j))
{
next = memk;
do
{
k = next;
next = GET(n,k);
if (seq1 > 0)
pos1 = j - xmin - 1;
else
pos1 = j;
pos2 = k - ymin - 1;
list[nseeds].pos1 = pos1 - 1;
list[nseeds].pos2 = pos2 - 1;
nseeds++;
} while ((next <= ymax) && (k != next));
}
}
}
Seeds = KMRK_allocSeeds(Seeds,
expected/20+1,
1,0);
/* fprintf(stderr,"Expected inter-direct couple : %d\n",expected);*/
KMRK_SetMultipleLenDirSeeds(list,nseeds,wordSize,Seeds);
MyFree(list, expected*sizeof(SmallSeed_type) );
KMRK_compactSeeds(Seeds);
return Seeds;
}
AllSeeds_type* KMRK_enumerateInterInvertedCouple(AllSeeds_type* Seeds,
int32_t seq2,
int32_t expected,
int32_t wordSize,
vn_type* stack)
{
int32_t xmin;
int32_t xmax;
int32_t ymax;
int32_t ymin;
int32_t posinv;
int32_t pos2;
int32_t i;
int32_t j;
int32_t k;
int32_t memj;
int32_t memk;
int32_t* n;
int32_t next;
int32_t nseeds;
SmallSeed_type *list;
list = (SmallSeed_type *)MyCalloc( expected, sizeof(SmallSeed_type) ,
"KMRK_enumerateInterCouple: cannot allocate InterCouple memory");
nseeds = 0;
n = GETVECTOR(stack,n);
if (seq2 < 2)
{
fprintf(stderr,"enumerateInterInvertedCouple: seq2 must be differente to 0");
exit(4);
}
xmin = stack->limits[0];
xmax = stack->limits[1];
ymin = stack->limits[seq2-1];
ymax = stack->limits[seq2];
Seeds = KMRK_allocSeeds(Seeds,
expected,
0,1);
for (i=1; i <= xmax; i++)
if (IS_MARKED(n,i))
{
for(memj=i ;
(memj < xmin) &&
memj != GET(n,memj);
memj=GET(n,memj));
if ((memj > xmin) && (memj <= xmax))
{
for(memk=memj ;
(memk < ymin) &&
memk != GET(n,memk);
memk=GET(n,memk));
if ((memk > ymin) && (memk <= ymax))
for (j=memj;
(j <= xmax) && (j != GET(n,j));
j=GET(n,j))
{
next = memk;
do
{
k = next;
next = GET(n,k);
posinv = 2 * xmin - j -wordSize + 3;
pos2 = k - ymin - 1;
list[nseeds].pos1=posinv-1;
list[nseeds].pos2=pos2-1;
nseeds++;
} while ((next <= ymax) && (k != next));
}
}
}
Seeds = KMRK_allocSeeds(Seeds,
expected/20+1,
0,1);
/* fprintf(stderr,"Expected inter-inverted couple : %d\n",expected);*/
SetMultipleLenInvSeeds(list,nseeds,wordSize,0,Seeds);
MyFree(list, expected* sizeof(SmallSeed_type) );
KMRK_compactSeeds(Seeds);
return Seeds;
}
int32_t KMRK_cmpSeedsPos(SmallSeed_type *s1, SmallSeed_type *s2)
{
if (s1->pos1==s2->pos1)
return s1->pos2 - s2->pos2;
else
return s1->pos1 - s2->pos1;
}
int32_t KMRK_cmpDeltaSeedsPos(SmallSeed_type *s1, SmallSeed_type *s2)
{
int32_t delta1 = s1->pos2-s1->pos1;
int32_t delta2 = s2->pos2-s2->pos1;
if (delta1==delta2)
return s1->pos1 - s2->pos1;
else
return delta1 - delta2;
}
int32_t KMRK_cmpDeltaInvSeedsPos(SmallSeed_type *s1, SmallSeed_type *s2)
{
int32_t delta1 = s1->pos2+s1->pos1;
int32_t delta2 = s2->pos2+s2->pos1;
if (delta1==delta2)
return s1->pos1 - s2->pos1;
else
return delta1 - delta2;
}
void KMRK_sortSeeds(SmallSeed_type* seeds,
int32_t nseeds,
KMRK_SORT_SEEDS_FUNC_PTR(compare))
{
qsort(seeds,
nseeds,
sizeof(SmallSeed_type),
(int (*)(const void *, const void *))compare);
}
AllSeeds_type* KMRK_get_seeds(char **seq,
int32_t SimpleSeqLen,
int16_t Lmin,
int8_t opt_dir,
int8_t opt_inv,
int8_t opt_verbose,
masked_area_table_t *mask)
{
AllSeeds_type* AllSeeds;
char *SeqDir = *seq;
vn_type * stacks;
int32_t dirExpect=0;
int32_t invExpect=0;
KMRK_QUORUM_FUNC_PTR(quorum);
if(opt_inv != 1 &&
opt_dir != 1)
{
fprintf(stderr,
"get_seeds: requiered at least "
"opt_dir or opt_inv to be 1\n");
exit(4);
}
if(opt_inv)
SeqDir = makeDirInvSeq(SeqDir,SimpleSeqLen); /* create a sequence with "DirSeq\0InvSeq\0" */
if (opt_inv){ /* Are we interested in dir, inv or both ? */
if (opt_dir)
quorum = KMRK_DirInvQuorum;
else
quorum = KMRK_InvQuorum;
}
else
quorum = KMRK_CoupleQuorum;
stacks = KMRK_RunTo(SeqDir,
Lmin,
opt_inv,
2,
1,
quorum,
KMRK_HashOneSequence,
mask);
invExpect =0;
KMRK_markStart(stacks);
if (opt_inv)
{
SeqDir = (char *)MyRealloc( (void *)SeqDir, (SimpleSeqLen+1)*sizeof(char),
(2*SimpleSeqLen+2)*sizeof(char) , "KRMK_get_seeds: Cannot shrink memory"); /* reset mem to a sigle sequence */
SeqDir[SimpleSeqLen]=0;
}
if(opt_inv)
invExpect = KMRK_upperInvertedCount(stacks,Lmin);
if(opt_dir)
dirExpect = KMRK_upperCoupleCount(stacks);
AllSeeds = NULL;
MyFree(stacks->v, stacks->size * sizeof(int32_t));
stacks->v=NULL;
if (opt_dir)
AllSeeds = KMRK_enumerateDirectCouple(AllSeeds,dirExpect,Lmin ,stacks,0);
if (opt_inv)
AllSeeds = KMRK_enumerateInvertedCouple(AllSeeds,invExpect,Lmin,stacks);
KMRK_FreeVN(stacks);
*seq = SeqDir;
return AllSeeds;
}
AllSeeds_type* KMRK_get_seeds_2seqs(char **seq1,
char **seq2,
int32_t size1,
int32_t size2,
int16_t Lmin,
int8_t opt_dir,
int8_t opt_inv,
int8_t opt_verbose,
masked_area_table_t *mask)
{
AllSeeds_type* AllSeeds;
char *sequence1 = *seq1;
char *sequence2 = *seq2;
vn_type * stacks;
int32_t dirExpect=0;
int32_t invExpect=0;
KMRK_QUORUM_FUNC_PTR(quorum);
int32_t sizef;
if(opt_inv != 1 &&
opt_dir != 1)
{
fprintf(stderr,
"get_seeds_2seqs: requiered at least "
"opt_dir or opt_inv to be 1\n");
exit(4);
}
sizef = size1;
if(opt_inv)
{
sequence1 = makeDirInvSeq(sequence1,size1);
sizef+=(1+size1);
}
sequence1 = merge2seq(sequence1,sequence2,sizef,size2);
if (opt_inv)
if (opt_dir)
quorum = KMRK_IntDirInv12Quorum;
else
quorum = KMRK_IntInv12Quorum;
else
quorum = KMRK_Int12Quorum;
stacks = KMRK_RunTo(sequence1,
Lmin,
opt_inv,
2,
2,
quorum,
KMRK_HashOneSequence,
mask);
KMRK_markStart(stacks);
sequence1= (char *)MyRealloc(
(void *)sequence1,
(size1+1)*sizeof(char),
(sizef+size2+2)*sizeof(char),
"KMRK_get_seeds_2seqs: shrink memory from 3N to 1N... ???");
sequence1[size1]=0;
if (opt_dir){
if (opt_inv)
dirExpect = KMRK_upperInterCount(stacks,0,2,Lmin);
else
dirExpect = KMRK_upperInterCount(stacks,0,1,Lmin);
}
if (opt_inv)
invExpect = KMRK_upperInterCount(stacks,1,2,Lmin);
AllSeeds = NULL;
MyFree(stacks->v, stacks->size*sizeof(int32_t));
stacks->v=NULL;
if (opt_dir){
if (opt_inv)
AllSeeds = KMRK_enumerateInterCouple(AllSeeds,
0,2,
dirExpect,
Lmin ,
stacks);
else
AllSeeds = KMRK_enumerateInterCouple(AllSeeds,
0,1,
dirExpect,
Lmin ,
stacks);
}
if (opt_inv)
AllSeeds = KMRK_enumerateInterInvertedCouple(AllSeeds,
2,
invExpect,
Lmin ,
stacks);
KMRK_FreeVN(stacks);
*seq1 = sequence1;
return AllSeeds;
}
#define SIGN(x) (((x)<0) ? -1:(((x)>0) ? 1:0))
static int32_t compareSeedsByPos(Seed_type* s1,Seed_type* s2)
{
if (s1->pos1 == s2->pos1)
return SIGN(s1->pos2 - s2->pos2);
else
return SIGN(s1->pos1 - s2->pos1);
}
void KMRK_sortSeedsByPos(Seed_type* seeds, int32_t count)
{
qsort(seeds,
count,
sizeof(Seed_type),
(int (*)(const void *, const void *))compareSeedsByPos);
};

View File

@ -1,126 +0,0 @@
#ifndef KMRK_Seeds_h
#define KMRK_Seeds_h
/********************************************
********************************************
**
** Declaration of struct
**
********************************************
********************************************/
#include <stdint.h>
#include <stdio.h>
#include "KMRK.h"
#define KMRK_SORT_SEEDS_FUNC_PTR(name) int32_t (*name)(SmallSeed_type*, \
SmallSeed_type*)
#define KMRK_DELTA_SEEDS_FUNC_PTR(name) int32_t (*name)(SmallSeed_type*)
/********************************************
********************************************
**
** Declaration of public functions
**
********************************************
********************************************/
AllSeeds_type *KMRK_allocSeeds(AllSeeds_type *AllSeeds,
int32_t size,
int8_t opt_dir,
int8_t opt_inv);
void KMRK_SetMultipleLenDirSeeds(SmallSeed_type* seeds,
int32_t nseeds,
int32_t wordSize,
AllSeeds_type *PtrAllSeeds);
void KMRK_freeSeeds(AllSeeds_type *AllSeeds);
void KMRK_compactSeeds(AllSeeds_type *AllSeeds);
void KMRK_pushSeed(AllSeeds_type *AllSeeds,
int32_t pos1,
int32_t pos2,
int32_t length,
int8_t dir);
AllSeeds_type* KMRK_enumerateDirectCouple(AllSeeds_type* Seeds,
int32_t expected,
int32_t wordSize,
vn_type* stack,
int32_t seq);
AllSeeds_type* KMRK_enumerateInvertedCouple(AllSeeds_type* Seeds,
int32_t expected,
int32_t wordSize,
vn_type* stack);
AllSeeds_type* KMRK_enumerateInterCouple(AllSeeds_type* Seeds,
int32_t seq1,
int32_t seq2,
int32_t expected,
int32_t wordSize,
vn_type* stack);
AllSeeds_type* KMRK_enumerateInterInvertedCouple(AllSeeds_type* Seeds,
int32_t seq2,
int32_t expected,
int32_t wordSize,
vn_type* stack);
/**
* Compare two seeds and return an integer less than, equal to or greater
* than zero considering the relative order of the two seeds. This
* version take into account only pos1 and pos2 of seeds without taking
* account of the sequences or of the relative direction
*
* @param s1 pointer to seed one
* @param s2 pointer to seed two
*
* @return a integer less than, equal to or greater than zero
*/
int32_t KMRK_cmpSeedsPos(SmallSeed_type *s1, SmallSeed_type *s2);
int32_t KMRK_cmpDeltaSeedsPos(SmallSeed_type *s1, SmallSeed_type *s2);
int32_t KMRK_cmpDeltaInvSeedsPos(SmallSeed_type *s1, SmallSeed_type *s2);
void KMRK_sortSeeds(SmallSeed_type* seeds,
int32_t nseeds,
KMRK_SORT_SEEDS_FUNC_PTR(compare));
AllSeeds_type* KMRK_get_seeds(char **seq,
int32_t SimpleSeqLen,
int16_t Lmin,
int8_t opt_dir,
int8_t opt_inv,
int8_t opt_verbose,
masked_area_table_t *mask);
AllSeeds_type* KMRK_get_seeds_2seqs(char **seq1,
char **seq2,
int32_t size1,
int32_t size2,
int16_t Lmin,
int8_t opt_dir,
int8_t opt_inv,
int8_t opt_verbose,
masked_area_table_t *mask);
/**
* Order an array of seeds by pos1,pos2
*
* @param seeds pointer to an array of Seed_type object to sort
* @param count count of element in the array
*/
void KMRK_sortSeedsByPos(Seed_type* seeds, int32_t count);
#endif /* KMRK_Seeds_h */

View File

@ -1,259 +0,0 @@
/*
* KMRK_mask.c
* repseek
*
* Created by Eric Coissac on 04/12/04.
* Copyright 2004 __MyCompanyName__. All rights reserved.
*
*/
#include "KMRK_mask.h"
#include <stdio.h>
#include <stdlib.h>
#include "memory.h"
#define MASKED_AREA_TABLE_SIZE(seqcount) (sizeof(masked_area_table_t) + (sizeof(masked_area_list_t*) * ((seqcount)-1)))
#define MASKED_AREA_LIST_SIZE(areacount) (sizeof(masked_area_list_t) + (sizeof(masked_area_t) * ((areacount)-1)))
#define AREA_COUNT_INIT (1000)
static masked_area_table_t *new_masked_area_table(int32_t seqcount, int32_t areacount);
static masked_area_list_t *new_masked_area_list(int32_t areacount);
static masked_area_list_t *realloc_masked_area_list(masked_area_list_t *list,int32_t areacount);
static int32_t push_area(masked_area_table_t* table,int32_t sequence,int32_t begin,int32_t end);
static void sort_area_table(masked_area_table_t* table);
static int32_t compare_area(const masked_area_t* v1,const masked_area_t* v2);
static int32_t search_area(const masked_area_t* v1,const masked_area_t* v2);
static masked_area_list_t *strip_area_list(masked_area_list_t* list);
static void strip_area_table(masked_area_table_t* table);
static masked_area_list_t *new_masked_area_list(int32_t areacount)
{
masked_area_list_t *list;
list = MyCalloc(1,MASKED_AREA_LIST_SIZE(areacount),"Not enougth memory for mask table");
list->reserved=areacount;
return list;
}
static masked_area_list_t *realloc_masked_area_list(masked_area_list_t *list,int32_t areacount)
{
list = MyRealloc(list,
MASKED_AREA_LIST_SIZE(areacount),
MASKED_AREA_LIST_SIZE(list->reserved),
"Not enougth memory for mask table");
list->reserved=areacount;
return list;
}
static masked_area_table_t *new_masked_area_table(int32_t seqcount, int32_t areacount)
{
masked_area_table_t *table;
int32_t i;
table = MyCalloc(1,MASKED_AREA_TABLE_SIZE(seqcount),"Not enougth memory for mask table");
table->seqcount=seqcount;
for (i=0;i<seqcount;i++)
table->sequence[i]=new_masked_area_list(areacount);
return table;
}
static int32_t push_area(masked_area_table_t* table,int32_t sequence,int32_t begin,int32_t end)
{
masked_area_list_t * list;
if (sequence >= table->seqcount)
return -1;
list = table->sequence[sequence];
if (list->reserved == list->count)
{
list = realloc_masked_area_list(list,list->reserved*2);
table->sequence[sequence]=list;
}
list->area[list->count].begin=begin;
list->area[list->count].end=end;
list->count++;
table->total++;
return table->total;
}
static int32_t compare_area(const masked_area_t* v1,const masked_area_t* v2)
{
return v1->begin - v2->begin;
}
static void sort_area_table(masked_area_table_t* table)
{
int32_t i;
for (i=0; i<table->seqcount;i++)
{
qsort(table->sequence[i]->area,
table->sequence[i]->count,
sizeof(masked_area_t),
(int (*)(const void *, const void *))compare_area);
}
}
static masked_area_list_t *strip_area_list(masked_area_list_t* list)
{
int32_t i;
int32_t j;
int32_t count;
int32_t newcount;
count = list->count;
newcount=count;
for (i=1;i<count;i++)
{
/* fprintf(stderr,"\n%d->%d %d->%d ==>",list->area[i-1].begin,list->area[i-1].end,list->area[i].begin,list->area[i].end); */
if ((list->area[i].begin-1) <= list->area[i-1].end)
{
/* fprintf(stderr," joined"); */
list->area[i].begin=list->area[i-1].begin;
list->area[i-1].begin=-1;
newcount--;
}
}
list->count=newcount;
for (i=0,j=0;i<count;i++)
{
if (list->area[i].begin>=0)
{
if (i!=j)
list->area[j]=list->area[i];
j++;
}
}
return realloc_masked_area_list(list,newcount);
}
static void strip_area_table(masked_area_table_t* table)
{
int32_t seq;
int32_t oldcount;
masked_area_list_t* list;
sort_area_table(table);
for (seq=0; seq < table->seqcount;seq++)
{
list = table->sequence[seq];
oldcount = list->count;
table->sequence[seq]=strip_area_list(list);
table->total-=oldcount - table->sequence[seq]->count;
}
}
static int32_t search_area(const masked_area_t* v1,const masked_area_t* v2)
{
int32_t pos;
pos = v1->begin;
if (pos < v2->begin)
return -1;
if (pos > v2->end)
return 1;
return 0;
}
masked_area_table_t *KMRK_ReadMaskArea(char *areafile,int32_t seqcount,int32_t complement)
{
FILE* area;
char buffer[1000];
char *ok;
int32_t begin;
int32_t end;
int32_t sequence;
int32_t column;
int32_t linecount;
masked_area_table_t *table;
if (complement > 0)
seqcount++;
else
complement=0;
area = fopen(areafile,"r");
linecount=0;
table=new_masked_area_table(seqcount,AREA_COUNT_INIT);
do {
linecount++;
ok = fgets(buffer,999,area);
if (ok)
{
column = sscanf(buffer,"%d %d %d",&begin,&end,&sequence);
if (column > 1 && begin <= end)
{
begin--;
end--;
if (column==3)
sequence--;
else
sequence=0;
if (sequence && complement)
sequence++;
push_area(table,sequence,begin,end);
if (!sequence && complement)
push_area(table,1,complement -1 - end,complement -1 -begin);
}
if (column==1)
fprintf(stderr,"WARNING in mask file reading line %d\n",linecount);
}
} while (ok);
fprintf(stderr,"\nread %d masked areas from file\n",table->total);
strip_area_table(table);
fprintf(stderr,"strip to %d non overlaping areas\n",table->total);
return table;
}
char KMRK_isMasked(masked_area_table_t *mask,int32_t seq, int32_t position)
{
masked_area_t input;
int32_t result;
masked_area_list_t *list;
if (! mask || (seq >= mask->seqcount))
return 0;
list = mask->sequence[seq];
input.begin=position;
result = bsearch(&input,
list->area,
list->count,
sizeof(masked_area_t),
(int (*)(const void *, const void *))search_area) != NULL;
return result;
}

View File

@ -1,37 +0,0 @@
/*
* KMRK_mask.h
* repseek
*
* Created by Eric Coissac on 04/12/04.
* Copyright 2004 __MyCompanyName__. All rights reserved.
*
*/
#include <stdint.h>
#ifndef _KMRK_MASK_H_
#define _KMRK_MASK_H_
typedef struct {
int32_t begin;
int32_t end;
} masked_area_t;
typedef struct {
int32_t reserved;
int32_t count;
masked_area_t area[1];
} masked_area_list_t;
typedef struct {
int32_t seqcount;
int32_t total;
masked_area_list_t *sequence[1];
} masked_area_table_t;
masked_area_table_t *KMRK_ReadMaskArea(char *areafile,int32_t seqcount,int32_t complement);
char KMRK_isMasked(masked_area_table_t *mask,int32_t seq, int32_t position);
#endif

View File

@ -1,123 +0,0 @@
/**
* @file KMRK_merge_seeds.c
* @author Eric Coissac <coissac@inrialpes.fr>
* @date Wed Mar 3 11:15:57 2004
*
* @brief Merge function of overlapping seeds
*
*
*/
#include "KMRK_merge_seeds.h"
void KMRK_MergeSeeds(AllSeeds_type *AllSeeds,
int8_t opt_dir,
int8_t opt_inv)
{
int32_t i; /* the current seed */
int32_t j; /* the checked seed */
int32_t N; /* the kept ones */
Seed_type* seeds;
if(opt_dir){
seeds = AllSeeds->dirSeeds;
for(i=0, N=0 ;i<AllSeeds->nDirSeeds; i++){
if(seeds[i].pos1==-1) /* any seed at -1 is removed */
continue;
j=i+1;
while( (seeds[j].pos1!=-1) &&
(seeds[i].pos1!=-1) &&
(j < AllSeeds->nDirSeeds) &&
(seeds[j].pos1 < seeds[i].pos1+ seeds[i].length))
{
if(
((seeds[j].pos2 >= seeds[i].pos2) &&
(seeds[j].pos2 < seeds[i].pos2 + seeds[i].length)) || /* if the seeds are overlapping */
((seeds[j].pos2 + seeds[j].length >= seeds[i].pos2) &&
(seeds[j].pos2 + seeds[j].length < seeds[i].pos2 + seeds[i].length)))
{
if(seeds[j].length <= seeds[i].length)
seeds[j].pos1=seeds[j].pos2=seeds[j].length=-1; /* removed the smallest */
else
seeds[i].pos1=seeds[i].pos2=seeds[i].length=-1;
}
j++;
}
if(seeds[i].pos1 !=-1)
{ /* if this seed is not out, store it */
seeds[N].pos1 = seeds[i].pos1;
seeds[N].pos2 = seeds[i].pos2;
seeds[N].length = seeds[i].length;
N++;
}
}
AllSeeds->nFilteredDirSeeds += AllSeeds->nDirSeeds-N;
AllSeeds->nDirSeeds=N;
}
if(opt_inv){
seeds = AllSeeds->invSeeds;
for(i=0, N=0 ;i<AllSeeds->nInvSeeds; i++){
if(seeds[i].pos1==-1)
continue;
j=i+1;
while( (seeds[j].pos1!=-1 ) &&
(seeds[i].pos1!=-1 ) &&
(j < AllSeeds->nInvSeeds) &&
(seeds[j].pos1 < seeds[i].pos1+seeds[i].length))
{
if(
((seeds[j].pos2 >= seeds[i].pos2) && /* if the seeds are overlapping */
(seeds[j].pos2 < seeds[i].pos2+seeds[i].length)) ||
((seeds[j].pos2 + seeds[j].length >= seeds[i].pos2) &&
(seeds[j].pos2 + seeds[j].length < seeds[i].pos2+seeds[i].length)))
{
if(seeds[j].length <= seeds[i].length)
seeds[j].pos1=seeds[j].pos2=seeds[j].length=-1; /* removed the smallest */
else
seeds[i].pos1=seeds[i].pos2=seeds[i].length=-1;
}
j++;
}
if(seeds[i].pos1!=-1)
{ /* if this seed is not out, store it */
seeds[N].pos1 = seeds[i].pos1;
seeds[N].pos2 = seeds[i].pos2;
seeds[N].length = seeds[i].length;
N++;
}
}
AllSeeds->nFilteredInvSeeds += AllSeeds->nInvSeeds-N;
AllSeeds->nInvSeeds=N;
}
KMRK_compactSeeds(AllSeeds);
}

View File

@ -1,11 +0,0 @@
#ifndef KMRK_merge_seeds_h
#define KMRK_merge_seeds_h
#include "KMRK_Seeds.h"
void KMRK_MergeSeeds(AllSeeds_type *AllSeeds,
int8_t opt_dir,
int8_t opt_inv);
#endif /* KMRK_MergeSeeds */

View File

@ -1,224 +0,0 @@
/******
file : memory.c
function : All about memory of the KMR, Seeds and Repeats
All MyMalloc() series is about follwoing how mauch memory has been used
created : 19 Sep 2003
modif : Oct 2003, Feb 2004
modif : Dec 2004 <EC> ; Corrected Memory declaration
author : amikezor
*****/
#include <stdio.h>
#include <stdlib.h>
#include "repseek_types.h"
#include "memory.h"
MemUsage Memory;
/*
Functions to count the memory usage all along
dybamic allocation and free
*/
void PrintMem(char *Comment){
extern MemUsage Memory;
fprintf(stderr,"\n%s\nMemory Usage\n\t* Max is: %d bytes, %.2f Kb, %.2f Mb\n\t* Cur is: %d bytes, %.2f Kb, %.2f Mb\n",
Comment,
Memory.Max, (float)Memory.Max/1024, (float)Memory.Max/(1024*1024),
Memory.Current, (float)Memory.Current/1024, (float)Memory.Current/(1024*1024));
}
void PrintMaxMem( void ){
extern MemUsage Memory;
if(Memory.Max < 1024)
fprintf(stderr,"Max Memory Usage.. %d bytes\n", Memory.Max);
else if(Memory.Max < 1024*1024)
fprintf(stderr,"Max Memory Usage.. %.2f Kilobytes\n", (float)Memory.Max/1024);
else if(Memory.Max < 1024*1024*1024)
fprintf(stderr,"Max Memory Usage.. %.2f Megabytes\n", (float)Memory.Max/(1024*1024));
else
fprintf(stderr,"Max Memory Usage.. %.2f Gigabytes\n", (float)Memory.Max/(1024*1024*1024));
}
void Update_Mem(int32_t Value){
extern MemUsage Memory;
Memory.Current += Value;
Memory.Max = (Memory.Current>Memory.Max)?Memory.Current:Memory.Max;
}
void Init_Mem(int32_t Value){
extern MemUsage Memory;
Memory.Current = Value;
Memory.Max = Value;
}
/*
Replace functions of dynamic allocation
to allow the tracking of memory usage
*/
void *MyMalloc( int32_t size , char *Error ){
void *pointer;
pointer = malloc(size);
if(!pointer)fprintf(stderr,"%s\n",Error),exit(3);
Update_Mem(size);
return pointer;
}
void *MyCalloc( int32_t number, int32_t TypeSize , char *Error ){
void *pointer;
pointer = calloc(number, TypeSize);
if(!pointer)fprintf(stderr,"%s\n",Error),exit(3);
Update_Mem(number*TypeSize );
return pointer;
}
void MyFree( void *Pointer, int32_t size){
free(Pointer);
Pointer=NULL;
Update_Mem(-size);
}
void *MyRealloc( void *Pointer, int32_t newsize, int32_t oldsize, char *Error){
Pointer = realloc(Pointer,newsize);
if(!Pointer)fprintf(stderr,"%s\n",Error),exit(3);
Update_Mem( newsize-oldsize );
return Pointer;
}
/*
Deal with Stacks structure for KMR
void MallocStack(Stacks *s, int32_t number, int32_t *histo, int32_t AllValues){
int32_t i;
s->nStacks = number;
s->nValues = AllValues;
s->ppStacks = (int32_t **)MyMalloc( number * sizeof(int32_t *),
"MallocStack: ppStacks malloc error, bye\n");
s->lenStacks = (int32_t *)MyMalloc( number * sizeof(int32_t),
"MallocStack: lenStacks malloc error, bye\n");
s->ppStacks[0] = (int32_t *)MyMalloc( AllValues * sizeof(int32_t),
"MallocStack: ppStacks[0] malloc error, bye\n");
s->lenStacks[0]=0;
for(i=1;i < number; i++){
s->lenStacks[i]=0;
s->ppStacks[i] = s->ppStacks[i-1] + histo[i] ;
}
}
void FreeStack( Stacks *p){
MyFree(p->ppStacks[0] , p->nValues*sizeof(int32_t) );
MyFree(p->ppStacks , p->nStacks*sizeof(int32_t *) );
MyFree(p->lenStacks , p->nStacks*sizeof(int32_t));
}
*/
/*
Deal with the Seeds part
void free_Seeds(Seeds AllSeeds)
{
if( AllSeeds.nDirSeeds ){
MyFree(AllSeeds.DirPos1, AllSeeds.nDirSeeds*sizeof(int32_t));
MyFree(AllSeeds.DirPos2, AllSeeds.nDirSeeds*sizeof(int32_t));
MyFree(AllSeeds.DirLen, AllSeeds.nDirSeeds*sizeof(int32_t));
MyFree(AllSeeds.DirMeanR, AllSeeds.nDirSeeds*sizeof(float));
}
if(AllSeeds.nInvSeeds ){
MyFree(AllSeeds.InvPos1, AllSeeds.nInvSeeds*sizeof(int32_t));
MyFree(AllSeeds.InvPos2, AllSeeds.nInvSeeds*sizeof(int32_t));
MyFree(AllSeeds.InvLen, AllSeeds.nInvSeeds*sizeof(int32_t));
MyFree(AllSeeds.InvMeanR, AllSeeds.nInvSeeds*sizeof(float));
}
}
*/
/*
Malloc if it is the first time otherwise readjust
void AllocSeeds(Seeds *AllSeeds, int32_t size, int32_t old_size, int8_t opt_dir, int8_t opt_inv){
if(opt_inv != 1 && opt_dir != 1)
fprintf(stderr,"AllocSeeds: requiere at least one of opt_dir and opt_inv to be 1\n"),exit(4);
if(opt_dir == 1){
if( AllSeeds->DirPos1 == NULL){
AllSeeds->DirPos1 = (int32_t *)MyCalloc(size , sizeof(int32_t),"AllocSeeds: Alloc for DirPos1 failed, bye");
AllSeeds->DirPos2 = (int32_t *)MyCalloc(size , sizeof(int32_t),"AllocSeeds: Alloc for DirPos2 failed, bye");
}
else{
AllSeeds->DirPos1 = (int32_t *)MyRealloc(AllSeeds->DirPos1, size * sizeof(int32_t), old_size* sizeof(int32_t),
"AllocSeeds: realloc for DirPos1 failed, bye");
AllSeeds->DirPos2 = (int32_t *)MyRealloc(AllSeeds->DirPos2, size * sizeof(int32_t), old_size* sizeof(int32_t),
"AllocSeeds: realloc for DirPos2 failed, bye");
}
}
if(opt_inv == 1){
if( AllSeeds->InvPos1 == NULL){
AllSeeds->InvPos1 = (int32_t *)MyCalloc(size , sizeof(int32_t), "AllocSeeds: Alloc for InvPos1 failed, bye");
AllSeeds->InvPos2 = (int32_t *)MyCalloc(size , sizeof(int32_t), "AllocSeeds: Alloc for InvPos2 failed, bye");
}
else{
AllSeeds->InvPos1 = (int32_t *)MyRealloc(AllSeeds->InvPos1, size * sizeof(int32_t), old_size* sizeof(int32_t),
"AllocSeeds: realloc for InvPos1 failed, bye");
AllSeeds->InvPos2 = (int32_t *)MyRealloc(AllSeeds->InvPos2, size * sizeof(int32_t), old_size* sizeof(int32_t),
"AllocSeeds: realloc for InvPos2 failed, bye");
}
}
}
*/
/*
Deal with the Repeats structure
*/
Repeats mem_Repeats(int32_t Ndir, int32_t Ninv){
Repeats AllRepeats; /* All Repeats structure */
AllRepeats.nDirRep = Ndir; /* set the number of repeats to the number of seeds */
AllRepeats.nInvRep = Ninv;
AllRepeats.nDirBadRep = 0; /* set the "bad" repet (included into another rep) as 0 */
AllRepeats.nInvBadRep = 0;
if(AllRepeats.nDirRep)
AllRepeats.DirRep = (Rep *)MyMalloc( (AllRepeats.nDirRep)*sizeof(Rep), "init_Repeats: repdir malloc error" );
else
AllRepeats.DirRep = NULL;
if(AllRepeats.nInvRep)
AllRepeats.InvRep = (Rep *)MyMalloc( (AllRepeats.nInvRep)*sizeof(Rep), "init_Repeats: repinv malloc error" );
else
AllRepeats.InvRep = NULL;
return AllRepeats;
}
void free_Repeats(Repeats AllRep)
{
if(AllRep.nDirRep)
MyFree(AllRep.DirRep, AllRep.nDirRep*sizeof(Rep));
if(AllRep.nInvRep)
MyFree(AllRep.InvRep, AllRep.nInvRep*sizeof(Rep));
}

View File

@ -1,105 +0,0 @@
/**
* @file memory.h
* @author Achaz G
* @date April 2004
*
* @brief header for memory alloc/dealloc
* modif : Dec 2004 <EC> ; Corrected Memory declaration
*
*
*/
#ifndef _MEMORY_H_
#define _MEMORY_H_
#include "repseek_types.h"
typedef struct { /********** Memory Usage structure **************/
int32_t Max;
int32_t Current;
} MemUsage;
#include <stdint.h>
/********** **********
Global Variable(s)
********** **********/
extern MemUsage Memory; /* Instance of the global variable for memory tracking */
/*
Follow memory usage
*/
void PrintMem(char *Comment);
void PrintMaxMem( void );
void Update_Mem(int32_t Value);
void Init_Mem(int32_t Value);
/*
All Alloc/Free to follow of memory usage
*/
void *MyMalloc( int32_t size , char *Error );
void *MyCalloc( int32_t number, int32_t TypeSize , char *Error );
void MyFree( void *Pointer, int32_t size);
void *MyRealloc( void *Pointer, int32_t newsize, int32_t oldsize, char *Error);
/*
For Stacks
void MallocStack(Stacks *s, int32_t number, int32_t *histo, int32_t AllValues);
void FreeStack( Stacks *p);
For Seeds
void free_Seeds(Seeds AllSeeds);
void AllocSeeds(Seeds *AllSeeds, int32_t size, int32_t old_size, int8_t opt_dir, int8_t opt_inv);
*/
/*
For Repeats
*/
Repeats mem_Repeats(int32_t Ndir, int32_t Ninv);
void free_Repeats(Repeats AllRep);
/*
Not used anymore, but just in case
*/
#include <stdio.h>
#include <stdlib.h>
#define KMRK_MALLOC(var,type,size,message) { \
var = (type*) malloc(size); \
if (!var) \
{ \
fprintf(stderr,"%s\n",message); \
exit(4); \
} \
}
#define KMRK_CALLOC(var,type,length,message) { \
var = (type*) calloc(length,sizeof(type)); \
if (!var) \
{ \
fprintf(stderr,"%s\n",message); \
exit(4); \
} \
}
#define KMRK_REALLOC(var,type,size,message) { \
var = (type*) realloc(var,size); \
if (!var) \
{ \
fprintf(stderr,"%s\n",message); \
exit(4); \
} \
}
#endif /* _MEMORY_H_*/

View File

@ -1,197 +0,0 @@
/**
* @file repseek_types.h
* @author Guillaume Achaz <gachaz@oeb.harvard.edu>
* @date April 2004
* @modif July 2004 turn scores into doubles
* @brief definition of general types and macros for repseek
*
*
*/
#ifndef _REPSEEK_TYPES_
#define _REPSEEK_TYPES_
/*
Version of the program
*/
#define REPSEEK_VERSION "4.2"
#define REPSEEK_DATE "Nov 2004"
/********** **********
General Macros
********** **********/
/*
Macros to compare 2 or three values
*/
#define MAX2( A, B ) ( ((A)>(B))?(A):(B) )
#define MAX3( A, B, C ) ( ((MAX2(A,B))>(C))?(MAX2(A,B)):(C) )
#define MIN2( A, B ) ( ((A)<(B))?(A):(B) )
#define MAX( A, B ) MAX2( A, B )
#define MIN( A, B ) MIN2( A, B )
/*
Absolute values
*/
#define ABS(x) (( (x)>=0 )? (x) : -(x))
/********** **********
All types used in repseek
********** **********/
#include <stdio.h> /* The type FILE * is defined here */
#include <stdint.h> /* all, the int??_t are defined in there */
/**
* Store informations about one STRICT repeat (seeds)
*
*/
typedef struct { /* the complete seed structure */
int32_t pos1; /**< position of the first copy */
int32_t pos2; /**< position of the second copy */
int32_t length; /**< length of the strict repeats */
float rmean; /**< mean repeat leavel */
} Seed_type;
typedef struct { /* Just after a KMRK length X, only the 2 pos matter */
int32_t pos1; /**< postion of the first copy */
int32_t pos2; /**< postion of the second copy */
} SmallSeed_type;
/**
* Store informations about all strict repeat (seeds)
*
*/
typedef struct {
int32_t cDirSeeds; /**< currently allocated space in dirSeeds array */
int32_t nDirSeeds; /**< count of direct strict repeats */
int32_t nFilteredDirSeeds; /**< ??? */
Seed_type* dirSeeds; /**< array of direct repeats */
int32_t cInvSeeds; /**< currently allocated space in invSeeds array */
int32_t nInvSeeds; /**< count of inverted strict repeats */
int32_t nFilteredInvSeeds; /**< ??? */
Seed_type* invSeeds; /**< array of inverted repeats */
} AllSeeds_type;
/**
* Store informations about one GENERIC repeat
*
*/
typedef struct{
char type[20]; /* its name; i.e. Tandem, Palindrome, etc... */
int32_t pos1, pos2, /* both copies postions */
len1, len2, /* both copies length */
seed_pos1,seed_pos2, /* pos1 and pos2 of the originate seed */
seed_len, /* len of the seed */
match, align_len; /* number of match and length of alignment */
double score; /* the alignment score */
float seed_meanR; /* the seed meanR */
float meanR; /* The mean R-level of the repeat */
int32_t mainR; /* its Mode R */
float fraction_mainR; /* the fraction of length containing the Mode R */
} Rep;
/**
* Store informations about All GENERIC repeats
*
*/
typedef struct {
int32_t nDirRep; /* Total Number of Direct Repats in Mem */
int32_t nDirBadRep; /* Direct repeats set to -1 -- filtered out and co. */
Rep *DirRep; /* The array of Dir Rep */
int32_t nInvRep; /* Total Number of Inverted Repats in Mem */
int32_t nInvBadRep; /* Inverted Repeats set to -1 -- filtered out and co. */
Rep *InvRep; /* The array of Inverted Rep */
} Repeats;
#define MATRIX_SIZE 26
typedef struct { /******* The scoring Matrix ************/
double matrix[MATRIX_SIZE][MATRIX_SIZE]; /* the matrix of match/missmatch */
double gap_open; /* value of gap-open */
double gap_ext; /* value of gap_ext */
double expect;
} SCORING;
typedef struct { /******* The Results of Alignement by Dynamik programming ************/
double *scores; /* the score strings (+/- 'matrix') */
double *pscore; /* pointer to the current score */
char *traces; /* the path matrix - could take values 'l'eft, 'd'iagonal, or 'a'bove or 'u'nknown */
double *F; /* *Above -- needed for memorizing deletion in seq2 */
double *pBestScore; /* pointer to it */
int32_t BestScore_row; /* its row and col */
int32_t BestScore_col;
char *traceback; /* all you need for bactracking */
char *traceback_f; /* memory for forward traceback and then check other seeds */
char *traceback_b; /* memory needed for backward traceback - to avoid erasing the forward one */
int32_t alignment_len; /* guess ?? */
int32_t matches; /* number of match (score>0 in scoring matrix) */
int32_t nSegment; /* number of segment */
int32_t *Segment_begin; /* begin and end of each segment */
int32_t *Segment_end;
int32_t max_scores; /* size of the matrices only for memory purposes */
int32_t max_col;
int32_t max_row;
int32_t max_alignlen;
} RESULTS;
#endif /* _REPSEEK_TYPES_ */

View File

@ -1,25 +0,0 @@
/**
* @file KMRK_sequence.h
* @author Eric Coissac <coissac@inrialpes.fr>
* @date Tue Feb 24 22:22:57 2004
*
* @brief Header file for sequence utilities
*
*
*/
#ifndef KMRK_sequence_h
#define KMRK_sequence_h
#include <stdint.h>
int8_t CheckSeq(char *seq, char *alpha);
void nonACGTXtoN(char *seq);
void UpperSequence(char *seq);
void invseq(char *seqsrc, char *seqdest);
#endif /* KMRK_sequence_h */

View File

@ -1,14 +0,0 @@
/* ----------------------------------------------- */
/* dft_pat_seq_code.h */
/* default alphabet encoding for alpha */
/* ----------------------------------------------- */
0x00000001 /* A */, 0x00000002 /* B */, 0x00000004 /* C */,
0x00000008 /* D */, 0x00000010 /* E */, 0x00000020 /* F */,
0x00000040 /* G */, 0x00000080 /* H */, 0x00000100 /* I */,
0x00000200 /* J */, 0x00000400 /* K */, 0x00000800 /* L */,
0x00001000 /* M */, 0x00002000 /* N */, 0x00004000 /* O */,
0x00008000 /* P */, 0x00010000 /* Q */, 0x00020000 /* R */,
0x00040000 /* S */, 0x00080000 /* T */, 0x00100000 /* U */,
0x00200000 /* V */, 0x00400000 /* W */, 0x00800000 /* X */,
0x01000000 /* Y */, 0x02000000 /* Z */

View File

@ -1,71 +0,0 @@
/* ----------------------------------------------- */
/* dna_code.h */
/* alphabet encoding for dna/rna */
/* ----------------------------------------- */
/* IUPAC encoding */
/* ----------------------------------------- */
/* G/A/T/C */
/* U=T */
/* R=AG */
/* Y=CT */
/* M=AC */
/* K=GT */
/* S=CG */
/* W=AT */
/* H=ACT */
/* B=CGT */
/* V=ACG */
/* D=AGT */
/* N=ACGT */
/* X=ACGT */
/* EFIJLOPQZ not recognized */
/* ----------------------------------------- */
/* dual encoding */
/* ----------------------------------------- */
/* A=ADHMNRVW */
/* B=BCDGHKMNRSTUVWY */
/* C=BCHMNSVY */
/* D=ABDGHKMNRSTUVWY */
/* G=BDGKNRSV */
/* H=ABCDHKMNRSTUVWY */
/* K=BDGHKNRSTUVWY */
/* M=ABCDHMNRSVWY */
/* N=ABCDGHKMNRSTUVWY */
/* R=ABDGHKMNRSVW */
/* S=BCDGHKMNRSVY */
/* T=BDHKNTUWY */
/* U=BDHKNTUWY */
/* V=ABCDGHKMNRSVWY */
/* W=ABDHKMNRTUVWY */
/* X=ABCDGHKMNRSTUVWY */
/* Y=BCDHKMNSTUVWY */
/* EFIJLOPQZ not recognized */
/* ----------------------------------------------- */
#ifndef USE_DUAL
/* IUPAC */
0x00000001 /* A */, 0x00080044 /* B */, 0x00000004 /* C */,
0x00080041 /* D */, 0x00000000 /* E */, 0x00000000 /* F */,
0x00000040 /* G */, 0x00080005 /* H */, 0x00000000 /* I */,
0x00000000 /* J */, 0x00080040 /* K */, 0x00000000 /* L */,
0x00000005 /* M */, 0x00080045 /* N */, 0x00000000 /* O */,
0x00000000 /* P */, 0x00000000 /* Q */, 0x00000041 /* R */,
0x00000044 /* S */, 0x00080000 /* T */, 0x00080000 /* U */,
0x00000045 /* V */, 0x00080001 /* W */, 0x00080045 /* X */,
0x00080004 /* Y */, 0x00000000 /* Z */
#else
/* DUAL */
0x00623089 /* A */, 0x017e34ce /* B */, 0x01243086 /* C */,
0x017e34cb /* D */, 0x00000000 /* E */, 0x00000000 /* F */,
0x0026244a /* G */, 0x017e348f /* H */, 0x00000000 /* I */,
0x00000000 /* J */, 0x017e24ca /* K */, 0x00000000 /* L */,
0x0166308f /* M */, 0x017e34cf /* N */, 0x00000000 /* O */,
0x00000000 /* P */, 0x00000000 /* Q */, 0x006634cb /* R */,
0x012634ce /* S */, 0x0158248a /* T */, 0x0158248a /* U */,
0x016634cf /* V */, 0x017a348b /* W */, 0x017e34cf /* X */,
0x017c348e /* Y */, 0x00000000 /* Z */
#endif

View File

@ -1,51 +0,0 @@
/* ----------------------------------------------- */
/* prot_code.h */
/* alphabet encoding for proteins */
/* ----------------------------------------- */
/* IUPAC encoding */
/* ----------------------------------------- */
/* B=DN */
/* Z=EQ */
/* X=any - {X} */
/* JOU not recognized */
/* ----------------------------------------- */
/* dual encoding */
/* ----------------------------------------- */
/* B=BDN */
/* D=BD */
/* E=EZ */
/* N=BN */
/* Q=QZ */
/* X=any - {X} */
/* Z=EQZ */
/* JOU not recognized */
/* ----------------------------------------------- */
#ifndef USE_DUAL
/* IUPAC */
0x00000001 /* A */, 0x00002008 /* B */, 0x00000004 /* C */,
0x00000008 /* D */, 0x00000010 /* E */, 0x00000020 /* F */,
0x00000040 /* G */, 0x00000080 /* H */, 0x00000100 /* I */,
0x00000000 /* J */, 0x00000400 /* K */, 0x00000800 /* L */,
0x00001000 /* M */, 0x00002000 /* N */, 0x00000000 /* O */,
0x00008000 /* P */, 0x00010000 /* Q */, 0x00020000 /* R */,
0x00040000 /* S */, 0x00080000 /* T */, 0x00000000 /* U */,
0x00200000 /* V */, 0x00400000 /* W */, 0x037fffff /* X */,
0x01000000 /* Y */, 0x00010010 /* Z */
#else
/* DUAL */
0x00000001 /* A */, 0x0000200a /* B */, 0x00000004 /* C */,
0x0000000a /* D */, 0x02000010 /* E */, 0x00000020 /* F */,
0x00000040 /* G */, 0x00000080 /* H */, 0x00000100 /* I */,
0x00000000 /* J */, 0x00000400 /* K */, 0x00000800 /* L */,
0x00001000 /* M */, 0x00002002 /* N */, 0x00000000 /* O */,
0x00008000 /* P */, 0x02010000 /* Q */, 0x00020000 /* R */,
0x00040000 /* S */, 0x00080000 /* T */, 0x00000000 /* U */,
0x00200000 /* V */, 0x00400000 /* W */, 0x037fffff /* X */,
0x01000000 /* Y */, 0x02010010 /* Z */
#endif

View File

@ -1,97 +0,0 @@
/* ---------------------------------------------------------------- */
/* Copyright (c) Atelier de BioInformatique */
/* @file: Gmach.h */
/* @desc: machine dependant setup */
/* @+ *should* be included in all ABI softs */
/* */
/* @history: */
/* @+ <Gloup> : Jul 95 : MWC first draft */
/* @+ <Gloup> : Jan 96 : adapted to Pwg */
/* @+ <Gloup> : Nov 00 : adapted to Mac_OS_X */
/* ---------------------------------------------------------------- */
#ifndef _H_Gmach
/* OS names */
#define _H_Gmach
/* Macintosh Classic */
/* Think C environment */
#ifdef THINK_C
#define MACINTOSH
#define MAC_OS_C
#endif
/* Macintosh Classic */
/* Code-Warrior */
#ifdef __MWERKS__
#define MACINTOSH
#define MAC_OS_C
#endif
/* Macintosh OS-X */
#ifdef MAC_OS_X
#define MACINTOSH
#define UNIX
#define UNIX_BSD
#endif
/* LINUX */
#ifdef LINUX
#define UNIX
#define UNIX_BSD
#endif
/* other Unix Boxes */
/* SunOS / Solaris */
#ifdef SUN
#define UNIX
#ifdef SOLARIS
#define UNIX_S7
#else
#define UNIX_BSD
#endif
#endif
/* SGI Irix */
#ifdef SGI
#define UNIX
#define UNIX_S7
#endif
/* ansi setup */
/* for unix machines see makefile */
#ifndef PROTO
#define PROTO 1
#endif
#ifndef ANSI_PROTO
#define ANSI_PROTO PROTO
#endif
#ifndef ANSI_STR
#define ANSI_STR 1
#endif
/* unistd.h header file */
#ifdef UNIX
#define HAS_UNISTD_H <unistd.h>
#endif
/* getopt.h header file */
#ifdef MAC_OS_C
#define HAS_GETOPT_H "getopt.h"
#endif
#ifdef SGI
#define HAS_GETOPT_H <getopt.h>
#endif
#endif

View File

@ -1,104 +0,0 @@
/* ---------------------------------------------------------------- */
/* Copyright (c) Atelier de BioInformatique */
/* @file: Gtypes.h */
/* @desc: general & machine dependant types */
/* @+ *should* be included in all ABI softs */
/* */
/* @history: */
/* @+ <Gloup> : Jan 91 : MWC first draft */
/* @+ <Gloup> : Jul 95 : Gmach addition */
/* ---------------------------------------------------------------- */
#define _H_Gtypes
#ifndef _H_Gmach
#include "Gmach.h"
#endif
#ifndef NULL
#include <stdio.h> /* is the official NULL here ? */
#endif
/* ==================================================== */
/* constantes */
/* ==================================================== */
#ifndef PROTO
#define PROTO 1 /* prototypes flag */
#endif
#ifdef MAC_OS_C
#define Vrai true /* TC boolean values */
#define Faux false /* */
#else
#define Vrai 0x1 /* bool values = TRUE */
#define Faux 0x0 /* = FALSE */
#endif
#define Nil NULL /* nil pointer */
#define kBigInt16 0x7fff /* plus grand 16 bits signe */
#define kBigInt32 0x7fffffff /* plus grand 32 bits signe */
#define kBigUInt16 0xffff /* plus grand 16 bits ~signe */
#define kBigUInt32 0xffffffff /* plus grand 32 bits ~signe */
#ifdef MAC_OS_C
/* ==================================================== */
/* Types (for Macintosh ThinK C || MWerks) */
/* ==================================================== */
/* --- specific sizes --------- */
typedef long Int32; /* Int32 = 32 bits signe */
typedef unsigned long UInt32; /* UInt32 = 32 bits ~signe */
typedef short Int16; /* Int16 = 16 bits signe */
typedef unsigned short UInt16; /* UInt32 = 16 bits ~signe */
typedef char Int8; /* Int8 = 8 bits signe */
typedef unsigned char UInt8; /* UInt8 = 8 bits ~signe */
/* --- default types ---------- */
typedef Boolean Bool; /* booleen */
typedef long Int; /* 'natural' int (>= 32 bits) */
typedef void *Ptr; /* pointeur */
#elif ((defined SUN) || (defined SGI) || (defined UNIX))
/* ==================================================== */
/* Types (for Sun & Iris - 32 bits machines) */
/* ==================================================== */
/* --- specific sizes --------- */
typedef int Int32; /* Int32 = 32 bits signe */
typedef unsigned int UInt32; /* UInt32 = 32 bits ~signe */
typedef short Int16; /* Int16 = 16 bits signe */
typedef unsigned short UInt16; /* UInt32 = 16 bits ~signe */
typedef char Int8; /* Int8 = 8 bits signe */
typedef unsigned char UInt8; /* UInt8 = 8 bits ~signe */
/* --- default types ---------- */
typedef int Bool; /* booleen (int for ANSI) */
typedef int Int; /* 'natural' int (>= 32 bits) */
typedef void *Ptr; /* pointeur */
#else
/* ==================================================== */
/* Types (for undefined machines) */
/* ==================================================== */
#error undefined MACHINE <please edit Gmach.h>
#endif
/* ==================================================== */
/* special macro for prototypes */
/* ==================================================== */
#if PROTO
#define P(s) s
#else
#define P(s) ()
#endif

View File

@ -1,24 +0,0 @@
SOURCES = apat_parse.c \
apat_search.c \
libstki.c
SRCS=$(SOURCES)
OBJECTS= $(patsubst %.c,%.o,$(SOURCES))
LIBFILE= libapat.a
RANLIB=ranlib
include ../global.mk
all: $(LIBFILE)
clean:
rm -rf $(OBJECTS) $(LIBFILE)
$(LIBFILE): $(OBJECTS)
ar -cr $@ $?
$(RANLIB) $@

View File

@ -1,173 +0,0 @@
/* ==================================================== */
/* Copyright (c) Atelier de BioInformatique */
/* Dec. 94 */
/* File: apat.h */
/* Purpose: pattern scan */
/* History: */
/* 28/12/94 : <Gloup> ascan first version */
/* 14/05/99 : <Gloup> last revision */
/* ==================================================== */
#ifndef _H_Gtypes
#include "Gtypes.h"
#endif
#ifndef _H_libstki
#include "libstki.h"
#endif
#define H_apat
/* ----------------------------------------------- */
/* constantes */
/* ----------------------------------------------- */
#ifndef BUFSIZ
#define BUFSIZ 1024 /* io buffer size */
#endif
#define MAX_NAME_LEN BUFSIZ /* max length of sequence name */
#define ALPHA_LEN 26 /* alphabet length */
/* *DO NOT* modify */
#define MAX_PATTERN 4 /* max # of patterns */
/* *DO NOT* modify */
#define MAX_PAT_LEN 32 /* max pattern length */
/* *DO NOT* modify */
#define MAX_PAT_ERR 32 /* max # of errors */
/* *DO NOT* modify */
#define PATMASK 0x3ffffff /* mask for 26 symbols */
/* *DO NOT* modify */
#define OBLIBIT 0x4000000 /* bit 27 to 1 -> oblig. pos */
/* *DO NOT* modify */
/* mask for position */
#define ONEMASK 0x80000000 /* mask for highest position */
/* masks for Levenhstein edit */
#define OPER_IDT 0x00000000 /* identity */
#define OPER_INS 0x40000000 /* insertion */
#define OPER_DEL 0x80000000 /* deletion */
#define OPER_SUB 0xc0000000 /* substitution */
#define OPER_SHFT 30 /* <unused> shift */
/* Levenhstein Opcodes */
#define SOPER_IDT 0x0 /* identity */
#define SOPER_INS 0x1 /* insertion */
#define SOPER_DEL 0x2 /* deletion */
#define SOPER_SUB 0x3 /* substitution */
/* Levenhstein Opcodes masks */
#define OPERMASK 0xc0000000 /* mask for Opcodes */
#define NOPERMASK 0x3fffffff /* negate of previous */
/* special chars in pattern */
#define PATCHARS "[]!#"
/* 26 letter alphabet */
/* in alphabetical order */
#define ORD_ALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
/* protein alphabet */
#define PROT_ALPHA "ACDEFGHIKLMNPQRSTVWY"
/* dna/rna alphabet */
#define DNA_ALPHA "ABCDGHKMNRSTUVWXY"
/* ----------------------------------------------- */
/* data structures */
/* ----------------------------------------------- */
/* -------------------- */
typedef enum { /* data encoding */
/* -------------------- */
alpha = 0, /* [A-Z] */
dna, /* IUPAC DNA */
protein /* IUPAC proteins */
} CodType;
/* -------------------- */
typedef struct { /* sequence */
/* -------------------- */
char *name; /* sequence name */
Int32 seqlen; /* sequence length */
Int32 seqsiz; /* sequence buffer size */
Int32 datsiz; /* data buffer size */
Int32 circular;
UInt8 *data; /* data buffer */
char *cseq; /* sequence buffer */
StackiPtr hitpos[MAX_PATTERN]; /* stack of hit pos. */
StackiPtr hiterr[MAX_PATTERN]; /* stack of errors */
} Seq, *SeqPtr;
/* -------------------- */
typedef struct { /* pattern */
/* -------------------- */
int patlen; /* pattern length */
int maxerr; /* max # of errors */
char *cpat; /* pattern string */
Int32 *patcode; /* encoded pattern */
UInt32 *smat; /* S matrix */
UInt32 omask; /* oblig. bits mask */
Bool hasIndel; /* are indels allowed */
Bool ok; /* is pattern ok */
} Pattern, *PatternPtr;
/* ----------------------------------------------- */
/* macros */
/* ----------------------------------------------- */
#ifndef NEW
#define NEW(typ) (typ*)malloc(sizeof(typ))
#define NEWN(typ, dim) (typ*)malloc((unsigned long)(dim) * sizeof(typ))
#define REALLOC(typ, ptr, dim) (typ*)realloc((void *) (ptr), (unsigned long)(dim) * sizeof(typ))
#define FREE(ptr) free((void *) ptr)
#endif
/* ----------------------------------------------- */
/* prototypes */
/* ----------------------------------------------- */
/* apat_seq.c */
SeqPtr FreeSequence (SeqPtr pseq);
SeqPtr NewSequence (void);
int ReadNextSequence (SeqPtr pseq);
int WriteSequence (FILE *filou , SeqPtr pseq);
/* apat_parse.c */
Int32 *GetCode (CodType ctype);
int CheckPattern (Pattern *ppat);
int EncodePattern (Pattern *ppat, CodType ctype);
int ReadPattern (Pattern *ppat);
void PrintDebugPattern (Pattern *ppat);
/* apat_search.c */
int CreateS (Pattern *ppat, Int32 lalpha);
Int32 ManberNoErr (Seq *pseq , Pattern *ppat, int patnum,int begin,int length);
Int32 ManberSub (Seq *pseq , Pattern *ppat, int patnum,int begin,int length);
Int32 ManberIndel (Seq *pseq , Pattern *ppat, int patnum,int begin,int length);
Int32 ManberAll (Seq *pseq , Pattern *ppat, int patnum,int begin,int length);
Int32 NwsPatAlign (Seq *pseq , Pattern *ppat, Int32 nerr ,
Int32 *reslen , Int32 *reserr);
/* apat_sys.c */
float UserCpuTime (int reset);
float SysCpuTime (int reset);
char *StrCpuTime (int reset);
void Erreur (char *msg , int stat);
int AccessFile (char *path, char *mode);

View File

@ -1,369 +0,0 @@
/* ==================================================== */
/* Copyright (c) Atelier de BioInformatique */
/* Mar. 92 */
/* File: apat_parse.c */
/* Purpose: Codage du pattern */
/* History: */
/* 00/07/94 : <Gloup> first version (stanford) */
/* 00/11/94 : <Gloup> revised for DNA/PROTEIN */
/* 30/12/94 : <Gloup> modified EncodePattern */
/* for manber search */
/* 14/05/99 : <Gloup> indels added */
/* ==================================================== */
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Gtypes.h"
#include "apat.h"
/* -------------------- */
/* default char */
/* encodings */
/* -------------------- */
static Int32 sDftCode[] = {
#include "CODES/dft_code.h"
};
/* -------------------- */
/* char encodings */
/* IUPAC */
/* -------------------- */
/* IUPAC Proteins */
static Int32 sProtCode[] = {
#include "CODES/prot_code.h"
};
/* IUPAC Dna/Rna */
static Int32 sDnaCode[] = {
#include "CODES/dna_code.h"
};
/* -------------------------------------------- */
/* internal replacement of gets */
/* -------------------------------------------- */
static char *sGets(char *buffer, int size) {
char *ebuf;
if (! fgets(buffer, size-1, stdin))
return NULL;
/* remove trailing line feed */
ebuf = buffer + strlen(buffer);
while (--ebuf >= buffer) {
if ((*ebuf == '\n') || (*ebuf == '\r'))
*ebuf = '\000';
else
break;
}
return buffer;
}
/* -------------------------------------------- */
/* returns actual code associated to type */
/* -------------------------------------------- */
Int32 *GetCode(CodType ctype)
{
Int32 *code = sDftCode;
switch (ctype) {
case dna : code = sDnaCode ; break;
case protein : code = sProtCode ; break;
default : code = sDftCode ; break;
}
return code;
}
/* -------------------------------------------- */
#define BAD_IF(tst) if (tst) return 0
int CheckPattern(Pattern *ppat)
{
int lev;
char *pat;
pat = ppat->cpat;
BAD_IF (*pat == '#');
for (lev = 0; *pat ; pat++)
switch (*pat) {
case '[' :
BAD_IF (lev);
BAD_IF (*(pat+1) == ']');
lev++;
break;
case ']' :
lev--;
BAD_IF (lev);
break;
case '!' :
BAD_IF (lev);
BAD_IF (! *(pat+1));
BAD_IF (*(pat+1) == ']');
break;
case '#' :
BAD_IF (lev);
BAD_IF (*(pat-1) == '[');
break;
default :
if (! isupper(*pat))
return 0;
break;
}
return (lev ? 0 : 1);
}
#undef BAD_IF
/* -------------------------------------------- */
static char *skipOblig(char *pat)
{
return (*(pat+1) == '#' ? pat+1 : pat);
}
/* -------------------------------------------- */
static char *splitPattern(char *pat)
{
switch (*pat) {
case '[' :
for (; *pat; pat++)
if (*pat == ']')
return skipOblig(pat);
return NULL;
break;
case '!' :
return splitPattern(pat+1);
break;
}
return skipOblig(pat);
}
/* -------------------------------------------- */
static Int32 valPattern(char *pat, Int32 *code)
{
Int32 val;
switch (*pat) {
case '[' :
return valPattern(pat+1, code);
break;
case '!' :
val = valPattern(pat+1, code);
return (~val & PATMASK);
break;
default :
val = 0x0;
while (isupper(*pat)) {
val |= code[*pat - 'A'];
pat++;
}
return val;
}
return 0x0;
}
/* -------------------------------------------- */
static Int32 obliBitPattern(char *pat)
{
return (*(pat + strlen(pat) - 1) == '#' ? OBLIBIT : 0x0);
}
/* -------------------------------------------- */
static int lenPattern(char *pat)
{
int lpat;
lpat = 0;
while (*pat) {
if (! (pat = splitPattern(pat)))
return 0;
pat++;
lpat++;
}
return lpat;
}
/* -------------------------------------------- */
/* Interface */
/* -------------------------------------------- */
/* -------------------------------------------- */
/* encode un pattern */
/* -------------------------------------------- */
int EncodePattern(Pattern *ppat, CodType ctype)
{
int pos, lpat;
Int32 *code;
char *pp, *pa, c;
ppat->ok = Faux;
code = GetCode(ctype);
ppat->patlen = lpat = lenPattern(ppat->cpat);
if (lpat <= 0)
return 0;
if (! (ppat->patcode = NEWN(Int32, lpat)))
return 0;
pa = pp = ppat->cpat;
pos = 0;
while (*pa) {
pp = splitPattern(pa);
c = *++pp;
*pp = '\000';
ppat->patcode[pos++] = valPattern(pa, code) | obliBitPattern(pa);
*pp = c;
pa = pp;
}
ppat->ok = Vrai;
return lpat;
}
/* -------------------------------------------- */
/* remove blanks */
/* -------------------------------------------- */
static char *RemBlanks(char *s)
{
char *sb, *sc;
for (sb = sc = s ; *sb ; sb++)
if (! isspace(*sb))
*sc++ = *sb;
return s;
}
/* -------------------------------------------- */
/* count non blanks */
/* -------------------------------------------- */
static Int32 CountAlpha(char *s)
{
Int32 n;
for (n = 0 ; *s ; s++)
if (! isspace(*s))
n++;
return n;
}
/* -------------------------------------------- */
/* lit un pattern */
/* <pattern> #mis */
/* ligne starting with '/' are comments */
/* -------------------------------------------- */
int ReadPattern(Pattern *ppat)
{
int val;
char *spac;
char buffer[BUFSIZ];
ppat->ok = Vrai;
if (! sGets(buffer, sizeof(buffer)))
return 0;
if (*buffer == '/')
return ReadPattern(ppat);
if (! CountAlpha(buffer))
return ReadPattern(ppat);
for (spac = buffer ; *spac ; spac++)
if ((*spac == ' ') || (*spac == '\t'))
break;
ppat->ok = Faux;
if (! *spac)
return 0;
if (sscanf(spac, "%d", &val) != 1)
return 0;
ppat->hasIndel = (val < 0);
ppat->maxerr = ((val >= 0) ? val : -val);
*spac = '\000';
(void) RemBlanks(buffer);
if ((ppat->cpat = NEWN(char, strlen(buffer)+1)))
strcpy(ppat->cpat, buffer);
ppat->ok = (ppat->cpat != NULL);
return (ppat->ok ? 1 : 0);
}
/* -------------------------------------------- */
/* ecrit un pattern - Debug - */
/* -------------------------------------------- */
void PrintDebugPattern(Pattern *ppat)
{
int i;
printf("Pattern : %s\n", ppat->cpat);
printf("Encoding : \n\t");
for (i = 0 ; i < ppat->patlen ; i++) {
printf("0x%8.8x ", ppat->patcode[i]);
if (i%4 == 3)
printf("\n\t");
}
printf("\n");
}

View File

@ -1,339 +0,0 @@
/* ==================================================== */
/* Copyright (c) Atelier de BioInformatique */
/* Dec. 94 */
/* File: apat_search.c */
/* Purpose: recherche du pattern */
/* algorithme de Baeza-Yates/Gonnet */
/* Manber (agrep) */
/* History: */
/* 07/12/94 : <MFS> first version */
/* 28/12/94 : <Gloup> revised version */
/* 14/05/99 : <Gloup> last revision */
/* ==================================================== */
#if 0
#ifndef THINK_C
#include <sys/types.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Gtypes.h"
#include "libstki.h"
#include "apat.h"
#define POP PopiOut
#define PUSH PushiIn
#define TOPCURS CursiToTop
#define DOWNREAD ReadiDown
#define KRONECK(x, msk) ((~x & msk) ? 0 : 1)
#define MIN(x, y) ((x) < (y) ? (x) : (y))
/* -------------------------------------------- */
/* Construction de la matrice S */
/* -------------------------------------------- */
int CreateS(Pattern *ppat, Int32 lalpha)
{
Int32 i, j, indx;
UInt32 pindx, amask, omask, *smat;
ppat->ok = Faux;
omask = 0x0L;
if (! (smat = NEWN(UInt32, lalpha)))
return 0;
for (i = 0 ; i < lalpha ; i++)
smat[i] = 0x0;
for (i = ppat->patlen - 1, amask = 0x1L ; i >= 0 ; i--, amask <<= 1) {
indx = ppat->patcode[i];
if (ppat->patcode[i] & OBLIBIT)
omask |= amask;
for (j = 0, pindx = 0x1L ; j < lalpha ; j++, pindx <<= 1)
if (indx & pindx)
smat[j] |= amask;
}
ppat->smat = smat;
ppat->omask = omask;
ppat->ok = Vrai;
return 1;
}
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* NoError */
/* -------------------------------------------- */
Int32 ManberNoErr(Seq *pseq, Pattern *ppat, int patnum,int begin,int length)
{
UInt32 pos;
UInt32 smask, r;
UInt8 *data;
StackiPtr *stkpos, *stkerr;
UInt32 end;
end = begin + length;
end = (end <= (size_t)(pseq->seqlen+pseq->circular)) ? end:(size_t)(pseq->seqlen+pseq->circular);
/* create local masks */
smask = r = 0x1L << ppat->patlen;
/* init. scan */
data = pseq->data + begin;
stkpos = pseq->hitpos + patnum;
stkerr = pseq->hiterr + patnum;
/* loop on text data */
for (pos = begin ; pos < end ; pos++) {
r = (r >> 1) & ppat->smat[*data++];
if (r & 0x1L) {
PUSH(stkpos, pos - ppat->patlen + 1);
PUSH(stkerr, 0);
}
r |= smask;
}
return (*stkpos)->top; /* aka # of hits */
}
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* Substitution only */
/* */
/* Note : r array is stored as : */
/* 0 0 r(0,j) r(0,j+1) r(1,j) r(1,j+1) ... */
/* */
/* -------------------------------------------- */
Int32 ManberSub(Seq *pseq, Pattern *ppat, int patnum,int begin,int length)
{
int e, emax, found;
UInt32 pos;
UInt32 smask, cmask, sindx;
UInt32 *pr, r[2 * MAX_PAT_ERR + 2];
UInt8 *data;
StackiPtr *stkpos, *stkerr;
UInt32 end;
end = begin + length;
end = (end <= (size_t)(pseq->seqlen+pseq->circular)) ? end:(size_t)(pseq->seqlen+pseq->circular);
/* create local masks */
emax = ppat->maxerr;
r[0] = r[1] = 0x0;
cmask = smask = 0x1L << ppat->patlen;
for (e = 0, pr = r + 3 ; e <= emax ; e++, pr += 2)
*pr = cmask;
cmask = ~ ppat->omask;
/* init. scan */
data = pseq->data + begin;
stkpos = pseq->hitpos + patnum;
stkerr = pseq->hiterr + patnum;
/* loop on text data */
for (pos = begin ; pos < end ; pos++) {
sindx = ppat->smat[*data++];
for (e = found = 0, pr = r ; e <= emax ; e++, pr += 2) {
pr[2] = pr[3] | smask;
pr[3] = ((pr[0] >> 1) & cmask) /* sub */
| ((pr[2] >> 1) & sindx); /* ident */
if (pr[3] & 0x1L) { /* found */
if (! found) {
PUSH(stkpos, pos - ppat->patlen + 1);
PUSH(stkerr, e);
}
found++;
}
}
}
return (*stkpos)->top; /* aka # of hits */
}
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* Substitution + Indels */
/* */
/* Note : r array is stored as : */
/* 0 0 r(0,j) r(0,j+1) r(1,j) r(1,j+1) ... */
/* */
/* Warning: may return shifted pos. */
/* */
/* -------------------------------------------- */
Int32 ManberIndel(Seq *pseq, Pattern *ppat, int patnum,int begin,int length)
{
int e, emax, found;
UInt32 pos;
UInt32 smask, cmask, sindx;
UInt32 *pr, r[2 * MAX_PAT_ERR + 2];
UInt8 *data;
StackiPtr *stkpos, *stkerr;
UInt32 end;
end = begin + length;
end = (end <= (size_t)(pseq->seqlen+pseq->circular)) ? end:(size_t)(pseq->seqlen+pseq->circular);
/* create local masks */
emax = ppat->maxerr;
r[0] = r[1] = 0x0;
cmask = smask = 0x1L << ppat->patlen;
for (e = 0, pr = r + 3 ; e <= emax ; e++, pr += 2) {
*pr = cmask;
cmask = (cmask >> 1) | smask;
}
cmask = ~ ppat->omask;
/* init. scan */
data = pseq->data + begin;
stkpos = pseq->hitpos + patnum;
stkerr = pseq->hiterr + patnum;
/* loop on text data */
for (pos = begin ; pos < end ; pos++) {
sindx = ppat->smat[*data++];
for (e = found = 0, pr = r ; e <= emax ; e++, pr += 2) {
pr[2] = pr[3] | smask;
pr[3] = (( pr[0] /* ins */
| (pr[0] >> 1) /* sub */
| (pr[1] >> 1)) /* del */
& cmask)
| ((pr[2] >> 1) & sindx); /* ident */
if (pr[3] & 0x1L) { /* found */
if (! found) {
PUSH(stkpos, pos - ppat->patlen + 1);
PUSH(stkerr, e);
}
found++;
}
}
}
return (*stkpos)->top; /* aka # of hits */
}
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* API call to previous functions */
/* -------------------------------------------- */
Int32 ManberAll(Seq *pseq, Pattern *ppat, int patnum,int begin,int length)
{
if (ppat->maxerr == 0)
return ManberNoErr(pseq, ppat, patnum, begin, length);
else if (ppat->hasIndel)
return ManberIndel(pseq, ppat, patnum, begin, length);
else
return ManberSub(pseq, ppat, patnum, begin, length);
}
/* -------------------------------------------- */
/* Alignement NWS */
/* pour edition des hits */
/* (avec substitution obligatoire aux bords) */
/* -------------------------------------------- */
Int32 NwsPatAlign(pseq, ppat, nerr, reslen, reserr)
Seq *pseq;
Pattern *ppat;
Int32 nerr, *reslen, *reserr;
{
UInt8 *sseq, *px;
Int32 i, j, lseq, lpat, npos, dindel, dsub,
*pc, *pi, *pd, *ps;
UInt32 amask;
static Int32 sTab[(MAX_PAT_LEN+MAX_PAT_ERR+1) * (MAX_PAT_LEN+1)];
lseq = pseq->seqlen;
pc = sTab; /* |----|----| --> i */
pi = pc - 1; /* | ps | pd | | */
pd = pi - lseq; /* |----|----| | */
ps = pd - 1; /* | pi | pc | v j */
/* |---------| */
lseq = pseq->seqlen;
lpat = ppat->patlen;
sseq = pseq->data - 1;
amask = ONEMASK >> lpat;
for (j = 0 ; j <= lpat ; j++) {
for (i = 0 , px = sseq ; i <= lseq ; i++, px++) {
if (i && j) {
dindel = MIN(*pi, *pd) + 1;
dsub = *ps + KRONECK(ppat->smat[*px], amask);
*pc = MIN(dindel, dsub);
}
else if (i) /* j == 0 */
*pc = *pi + 1;
else if (j) /* i == 0 */
*pc = *pd + 1;
else /* root */
*pc = 0;
pc++;
pi++;
pd++;
ps++;
}
amask <<= 1;
}
pc--;
for (i = lseq, npos = 0 ; i >= 0 ; i--, pc--) {
if (*pc <= nerr) {
*reslen++ = i;
*reserr++ = *pc;
npos++;
}
}
return npos;
}

View File

@ -1,6 +1,5 @@
SOURCES = ecoapat.c \
ecodna.c \
SOURCES = ecodna.c \
ecoError.c \
ecoIOUtils.c \
ecoMalloc.c \

View File

@ -2,6 +2,8 @@
#include <stdlib.h>
static int eco_log_malloc = 0;
//static size_t eco_amount_malloc=0;
static size_t eco_chunk_malloc=0;
void eco_trace_memory_allocation()
{
@ -13,8 +15,12 @@ void eco_untrace_memory_allocation()
eco_log_malloc=0;
}
void ecoMallocedMemory()
{
//eco_amount_malloc;
}
void *eco_malloc(int32_t chunksize,
void *eco_malloc(int64_t chunksize,
const char *error_message,
const char *filename,
int32_t line)
@ -23,12 +29,15 @@ void *eco_malloc(int32_t chunksize,
chunk = calloc(1,chunksize);
if (!chunk)
ecoError(ECO_MEM_ERROR,error_message,filename,line);
eco_chunk_malloc++;
if (eco_log_malloc)
fprintf(stderr,
"Memory segment located at %p of size %d is allocated (file : %s [%d])",
"Memory segment located at %p of size %lld is allocated (file : %s [%d])",
chunk,
chunksize,
filename,
@ -38,21 +47,33 @@ void *eco_malloc(int32_t chunksize,
}
void *eco_realloc(void *chunk,
int32_t newsize,
int64_t newsize,
const char *error_message,
const char *filename,
int32_t line)
{
void *newchunk;
if (newsize == 0)
{
if (chunk)
free(chunk);
return NULL;
}
newchunk = realloc(chunk,newsize);
if (!newchunk)
{
fprintf(stderr,"Requested memory : %lld\n",newsize);
ecoError(ECO_MEM_ERROR,error_message,filename,line);
}
if (!chunk)
eco_chunk_malloc++;
if (eco_log_malloc)
fprintf(stderr,
"Old memory segment %p is reallocated at %p with a size of %d (file : %s [%d])",
"Old memory segment %p is reallocated at %p with a size of %lld (file : %s [%d])",
chunk,
newchunk,
newsize,
@ -76,4 +97,6 @@ void eco_free(void *chunk,
error_message,
filename,
line);
eco_chunk_malloc--;
}

View File

@ -4,10 +4,6 @@
#include <stdio.h>
#include <inttypes.h>
#ifndef H_apat
#include "../libapat/apat.h"
#endif
/*****************************************************
*
* Data type declarations
@ -25,8 +21,8 @@ typedef struct {
int32_t taxid;
char AC[20];
int32_t DE_length;
int32_t SQ_length;
int32_t CSQ_length;
uint32_t SQ_length;
uint32_t CSQ_length; /*what is this CSQ_length ? */
char data[1];
@ -34,11 +30,14 @@ typedef struct {
typedef struct {
int32_t taxid;
int32_t SQ_length;
uint32_t SQ_length;
int32_t isexample;
char *AC;
char *DE;
char *SQ;
} ecoseq_t;
int32_t ranktaxonid;/*TR: taxon id to which the sequence belongs*/
} ecoseq_t, *pecoseq_t;
/*
*
@ -131,14 +130,14 @@ typedef struct {
int32_t is_big_endian();
int32_t swap_int32_t(int32_t);
void *eco_malloc(int32_t chunksize,
void *eco_malloc(int64_t chunksize,
const char *error_message,
const char *filename,
int32_t line);
void *eco_realloc(void *chunk,
int32_t chunksize,
int64_t chunksize,
const char *error_message,
const char *filename,
int32_t line);
@ -220,12 +219,14 @@ econameidx_t *read_nameidx(const char *filename,ecotaxonomy_t *taxonomy);
* @return pointer to a taxonomy index structure
*/
ecotxidx_t *read_taxonomyidx(const char *filename);
ecotxidx_t *read_taxonomyidx(const char *filename,const char *filename2);
ecotaxonomy_t *read_taxonomy(const char *prefix,int32_t readAlternativeName);
ecotx_t *eco_findtaxonbytaxid(ecotaxonomy_t *taxonomy, int32_t taxid);
ecotx_t *eco_findtaxonatrank(ecotx_t *taxon, int32_t rankidx);
int eco_isundertaxon(ecotx_t *taxon, int other_taxid);
ecoseq_t *ecoseq_iterator(const char *prefix);
@ -247,11 +248,11 @@ int32_t delete_taxonomy(ecotxidx_t *index);
int32_t rank_index(const char* label,ecorankidx_t* ranks);
int32_t delete_apatseq(SeqPtr pseq);
PatternPtr buildPattern(const char *pat, int32_t error_max);
PatternPtr complementPattern(PatternPtr pat);
SeqPtr ecoseq2apatseq(ecoseq_t *in,SeqPtr out,int32_t circular);
//int32_t delete_apatseq(SeqPtr pseq);
//PatternPtr buildPattern(const char *pat, int32_t error_max);
//PatternPtr complementPattern(PatternPtr pat);
//
//SeqPtr ecoseq2apatseq(ecoseq_t *in,SeqPtr out,int32_t circular);
char *ecoComplementPattern(char *nucAcSeq);
char *ecoComplementSequence(char *nucAcSeq);

View File

@ -133,6 +133,8 @@ int32_t delete_apatseq(SeqPtr pseq)
return 1;
}
/*
PatternPtr buildPattern(const char *pat, int32_t error_max)
{
PatternPtr pattern;
@ -197,3 +199,4 @@ PatternPtr complementPattern(PatternPtr pat)
return pattern;
}
*/

View File

@ -17,3 +17,4 @@ int eco_is_taxid_included( ecotaxonomy_t *taxonomy,
return 0;
}

View File

@ -34,14 +34,11 @@ ecorankidx_t *read_rankidx(const char *filename)
int32_t rank_index(const char* label,ecorankidx_t* ranks)
{
char **rep;
fprintf(stderr,"Looking for rank -%s-... ",label);
rep = bsearch(label,ranks->label,ranks->count,sizeof(char*),compareRankLabel);
if (rep)
return rep-ranks->label;
else
ECOERROR(ECO_NOTFOUND_ERROR,"Rank label not found");
return -1;
}

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
@ -75,6 +76,9 @@ ecoseq_t *new_ecoseq_with_data( char *AC,
"Allocate sequence data");
strcpy(tmp->SQ,SQ);
}
tmp->isexample=1;
return tmp;
}
@ -97,6 +101,8 @@ ecoseq_t *readnext_ecoseq(FILE *f)
int32_t comp_status;
unsigned long int seqlength;
int32_t rs;
char *c;
int32_t i;
raw = read_ecorecord(f,&rs);
@ -131,6 +137,8 @@ ecoseq_t *readnext_ecoseq(FILE *f)
seq->SQ = ECOMALLOC(seqlength+1,
"Allocate sequence buffer");
seq->isexample=1;
comp_status = uncompress((unsigned char*)seq->SQ,
&seqlength,
(unsigned char*)compressed,
@ -139,6 +147,10 @@ ecoseq_t *readnext_ecoseq(FILE *f)
if (comp_status != Z_OK)
ECOERROR(ECO_IO_ERROR,"I cannot uncompress sequence data");
for (c=seq->SQ,i=0;i<seqlength;c++,i++)
*c=toupper(*c);
// fprintf(stderr,"seq name : %30s seq size : %d\n",seq->DE,seq->SQ_length);
return seq;
}
@ -162,7 +174,6 @@ FILE *open_seqfile(const char *prefix,int32_t index)
prefix,
index);
fprintf(stderr,"# Coucou %s\n",filename_buffer);
if (filename_length >= 1024)
@ -184,7 +195,7 @@ ecoseq_t *ecoseq_iterator(const char *prefix)
{
static FILE *current_seq_file= NULL;
static int32_t current_file_idx = 1;
static char current_prefix[1024];
static char current_prefix[1025];
ecoseq_t *seq;
if (prefix)

View File

@ -10,23 +10,41 @@ static ecotx_t *readnext_ecotaxon(FILE *f,ecotx_t *taxon);
* @param pointer to the database (.tdx file)
* @return a ecotxidx_t structure
*/
ecotxidx_t *read_taxonomyidx(const char *filename)
ecotxidx_t *read_taxonomyidx(const char *filename,const char *filename2)
{
int32_t count;
int32_t count2;
FILE *f;
FILE *f2;
ecotxidx_t *index;
int32_t i;
f = open_ecorecorddb(filename,&count,1);
f2 = open_ecorecorddb(filename2,&count2,0);
index = (ecotxidx_t*) ECOMALLOC(sizeof(ecotxidx_t) + sizeof(ecotx_t) * (count-1),
index = (ecotxidx_t*) ECOMALLOC(sizeof(ecotxidx_t) + sizeof(ecotx_t) * (count+count2-1),
"Allocate taxonomy");
index->count=count;
index->count=count+count2;
fprintf(stderr,"Reading %d taxa...\n",count);
for (i=0; i < count; i++){
readnext_ecotaxon(f,&(index->taxon[i]));
index->taxon[i].parent=index->taxon + (int32_t)index->taxon[i].parent;
}
if (count2>0)
fprintf(stderr,"Reading %d local taxa...\n",count2);
else
fprintf(stderr,"No local taxon\n");
for (i=0; i < count2; i++){
readnext_ecotaxon(f2,&(index->taxon[count+i]));
index->taxon[count+i].parent=index->taxon + (int32_t)index->taxon[count+i].parent;
}
return index;
}
@ -111,6 +129,7 @@ ecotaxonomy_t *read_taxonomy(const char *prefix,int32_t readAlternativeName)
{
ecotaxonomy_t *tax;
char *filename;
char *filename2;
int buffsize;
tax = ECOMALLOC(sizeof(ecotaxonomy_t),
@ -120,14 +139,17 @@ ecotaxonomy_t *read_taxonomy(const char *prefix,int32_t readAlternativeName)
filename = ECOMALLOC(buffsize,
"Allocate filename");
filename2= ECOMALLOC(buffsize,
"Allocate filename");
snprintf(filename,buffsize,"%s.rdx",prefix);
tax->ranks = read_rankidx(filename);
snprintf(filename,buffsize,"%s.tdx",prefix);
snprintf(filename2,buffsize,"%s.ldx",prefix);
tax->taxons = read_taxonomyidx(filename);
tax->taxons = read_taxonomyidx(filename,filename2);
if (readAlternativeName)
{
@ -319,6 +341,9 @@ ecotx_t *eco_getsuperkingdom(ecotx_t *taxon,
if (taxonomy && tax!=taxonomy)
{
rankindex = rank_index("superkingdom",taxonomy->ranks);
if (rankindex < 0) {
rankindex = rank_index("domain",taxonomy->ranks);
}
tax=taxonomy;
}

39
src/libecoprimer/Makefile Normal file
View File

@ -0,0 +1,39 @@
SOURCES = goodtaxon.c \
readdnadb.c \
smothsort.c \
sortword.c \
hashsequence.c \
strictprimers.c \
aproxpattern.c \
merge.c \
queue.c \
libstki.c \
sortmatch.c \
pairtree.c \
pairs.c \
taxstats.c \
apat_search.c \
filtering.c \
PrimerSets.c \
ahocorasick.c
SRCS=$(SOURCES)
OBJECTS= $(patsubst %.c,%.o,$(SOURCES))
LIBFILE= libecoprimer.a
RANLIB= ranlib
include ../global.mk
all: $(LIBFILE)
clean:
rm -rf $(OBJECTS) $(LIBFILE)
$(LIBFILE): $(OBJECTS)
ar -cr $@ $?
$(RANLIB) $@

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
#ifndef PRIMERSETS_H_
#define PRIMERSETS_H_
#include "ecoprimer.h"
#define PRIMERS_IN_SET_COUNT 10
typedef struct {
int *set_wellIdentifiedTaxa;
int32_t set_pairs[PRIMERS_IN_SET_COUNT];
float set_specificity;
float set_coverage;
float set_lmean;
float set_lcov;
float set_score;
int32_t set_intaxa;
int32_t set_wi_cnt;
}pairset;
typedef struct{
ppair_t* sortedpairs;
int32_t sorted_count;
pecodnadb_t seqdb;
poptions_t options;
}SetParams;
typedef struct{
float t_spc; //specificity contribution
float t_cov; //coverage contribution
float t_lmd; //link spread difference
float len; //length
float score; //score
}primerscore;
void add_pair_in_set (pairset *pair_set, int32_t pset_idx, int32_t prb_idx, SetParams *pparams);
void get_next_pair_options (int *pair_wi_count_sorted_ids, pairset *pair_set, SetParams *pparams);
float get_links_distribution (int prb_idx, pairset *prob_set, SetParams *pparams);
pairset build_primers_set_greedy_spc (SetParams *pparams);
void get_set_mean_cov_stats (pairset *prob_set, SetParams *pparams);
void some_other_set_possibilities (pairset *pair_set,
ppair_t * sortedpairs, int32_t sorted_count, pecodnadb_t seqdb, poptions_t options);
void sets_by_SimulatedAnealing (pairset *pair_set,
ppair_t * sortedpairs, int32_t sorted_count, pecodnadb_t seqdb, poptions_t options);
void sets_by_TabuSearch (pairset *pair_set,
ppair_t * sortedpairs, int32_t sorted_count, pecodnadb_t seqdb, poptions_t options);
pairset * sets_by_BruteForce (ppair_t * sortedpairs,
int32_t sorted_count, pecodnadb_t seqdb, poptions_t options);
pairset * extend_set_randomly (pairset *pair_set, SetParams *params, int extend_to_cnt);
void build_and_print_sets (ppair_t * sortedpairs, int32_t sorted_count, pecodnadb_t seqdb, poptions_t options);
int32_t get_next_option_increasing_cov (pairset *pair_set, SetParams *pparams);
void reset_set_props (pairset *pair_set, SetParams *pparams);
void primers_graph_graphviz (ppair_t * sortedpairs,
int32_t sorted_count, poptions_t options);
size_t primers_changeSortedArray (ppair_t ** pairs,
size_t sorted_count, poptions_t options);
size_t primers_filterWithGivenLinks (ppair_t ** pairs,
size_t sorted_count, poptions_t options);
#endif

478
src/libecoprimer/ahocorasick.c Executable file
View File

@ -0,0 +1,478 @@
/*
* ahocorasick.h
*
* Created on: 26 march 2011
* Author: tiayyba
*/
#include <inttypes.h>
#include "hashencoder.h"
#include "ahocorasick.h"
void ahoc_graphKeywordTree (aho_state *root);
aho_state *groot = NULL; //just for graph testing
#define BASEATINDEX(w, l, i) (uint8_t)((((w)&(0x3LLU<<(((l)-(i))*2)))>>(((l)-(i))*2)) & 0x3LLU)
void ahoc_addOutputElement (aho_state *node, bool_t isdirect, uint32_t idx)
{
if (!node) return;
if (node->output.count == 0)
node->output.out_set = ECOMALLOC(sizeof(aho_output),
"Cannot allocate memory for aho-corasick state output element");
else
node->output.out_set = ECOREALLOC(node->output.out_set, (node->output.count+1)*sizeof(aho_output),
"Cannot allocate memory for aho-corasick state output element");
node->output.out_set[node->output.count].wordidx = idx;
node->output.out_set[node->output.count].isdirect = isdirect;
node->output.count++;
}
//is the passed output element in the set
bool_t ahoc_isOutputIn (aho_state *node, aho_output ot)
{
uint32_t i;
for (i=0; i<node->output.count; i++)
if (node->output.out_set[i].isdirect == ot.isdirect && node->output.out_set[i].wordidx == ot.wordidx) return TRUE;
return FALSE;
}
//take union of output of the two nodes and put in node1
void ahoc_unionOutputElements (aho_state *node1, aho_state *node2)
{
uint32_t i;
for (i=0; i<node2->output.count; i++)
if (ahoc_isOutputIn (node1, node2->output.out_set[i]) == FALSE)
ahoc_addOutputElement (node1, node2->output.out_set[i].isdirect, node2->output.out_set[i].wordidx);
}
void ahoc_addKeyword (aho_state *root, word_t w, bool_t isdirect, uint32_t idx, poptions_t options)
{
uint32_t i;
aho_state *nextnode = root;
uint8_t basecode;
static uint32_t state_id = 0;
//fprintf (stderr, "%s\n", ecoUnhashWord(w, options->primer_length));
for (i=1; i<=options->primer_length; i++)
{
basecode = BASEATINDEX (w, options->primer_length, i);
//fprintf (stderr, "%d", basecode);
if (nextnode->next[basecode] == NULL)
{
//add new state
nextnode->next[basecode] = ECOMALLOC(sizeof(aho_state),
"Cannot allocate memory for aho-corasick state");
nextnode = nextnode->next[basecode];
//initialize state
nextnode->id = ++state_id;
nextnode->next[0]=nextnode->next[1]=nextnode->next[2]=nextnode->next[3]=NULL;
nextnode->fail = NULL;
nextnode->output.count = 0;
}
else
nextnode = nextnode->next[basecode];
}
//fprintf (stderr, "\n", basecode);
//new pattern addess so add node ouptup element
ahoc_addOutputElement (nextnode, isdirect, idx);
}
void ahoc_buildKeywordTree (aho_state *root, pwordcount_t words, poptions_t options)
{
uint32_t i;
if (!root) return;
//init root
root->id = 0;
root->next[0]=root->next[1]=root->next[2]=root->next[3]=NULL;
root->fail = NULL;
root->output.count = 0;
//now add each word as a pattern in the keyword tree
for (i=0; i<words->size; i++)
{
//add direct word
word_t w=WORD(words->words[i]);
ahoc_addKeyword (root, w, TRUE, i, options);
//add reverse word
w=ecoComplementWord(w,options->primer_length);
ahoc_addKeyword (root, w, FALSE, i, options);
}
//loop on root if some base has no out going edge from roots
for (i=0; i<4; i++)
if (root->next[i] == NULL)
root->next[i] = root;
}
void ahoc_enqueue (aho_queue *ahoqueue, aho_state *node)
{
queue_node *q;
if (node == NULL) return;
q = ECOMALLOC(sizeof(queue_node),
"Cannot allocate memory for aho-corasick queue node");
q->state_node = node;
q->next = NULL;
if (ahoqueue->first == NULL)
{
ahoqueue->first = q;
ahoqueue->last = q;
}
else
{
ahoqueue->last->next = q;
ahoqueue->last = q;
}
}
aho_state *ahoc_dequeue (aho_queue *ahoqueue)
{
aho_state *node = NULL;
queue_node *q;
if (ahoqueue->first == NULL) return node;
q = ahoqueue->first;
ahoqueue->first = q->next;
node = q->state_node;
ECOFREE (q, "Cannot free memory for aho-corasick queue node");
return node;
}
//set fail links and output sets for the keyword tree
void ahoc_updateForFailAndOutput (aho_state *root)
{
int32_t i;
aho_queue Q;
aho_state *node_r;
aho_state *node_u;
aho_state *node_v;
//empty queue
Q.first = NULL;
Q.last = NULL;
//for us alphabet has 4 elements, A=0, C=1, G=2 and T=3
for (i=0; i<4; i++)
{
if (root->next[i] != root && root->next[i] != NULL)
{
root->next[i]->fail = root;
ahoc_enqueue (&Q, root->next[i]);
}
}
//while queue not empty
while (Q.first != NULL)
{
node_r = ahoc_dequeue (&Q);
for (i=0; i<4; i++)
{
if (node_r->next[i] != NULL)
{
node_u = node_r->next[i];
ahoc_enqueue (&Q, node_u);
node_v = node_r->fail;
while (node_v->next[i] == NULL)
node_v = node_v->fail;
node_u->fail = node_v->next[i];
ahoc_unionOutputElements (node_u, node_u->fail);
}
}
}
}
void ahoc_freeKeywordTree (aho_state *node)
{
int i;
for (i=0; i<4; i++)
if (node->next[i])
ahoc_freeKeywordTree (node->next[i]);
if (node->output.count > 0)
ECOFREE (node->output.out_set, "Free failed for node output");
ECOFREE (node, "Free failed for node");
}
pprimercount_t ahoc_lookforStrictPrimers (pecodnadb_t database, uint32_t seqdbsize,uint32_t exampleCount,
pwordcount_t words,poptions_t options)
{
aho_state automaton_root;
aho_state *curr_state;
//uint32_t inSequenceQuorum;
uint32_t outSequenceQuorum;
pprimer_t data;
pprimercount_t primers;
uint32_t i, j, k;
int32_t pos;
uint32_t lmax;
char *base;
int8_t code;
uint32_t goodPrimers=0;
//inSequenceQuorum = (uint32_t)floor((float)exampleCount * options->sensitivity_quorum);
outSequenceQuorum = (uint32_t)floor((float)(seqdbsize-exampleCount) * options->false_positive_quorum);
//fprintf(stderr," Primers should be at least present in %d/%d example sequences\n",inSequenceQuorum,exampleCount);
fprintf(stderr," Primers should not be present in more than %d/%d counterexample sequences\n",outSequenceQuorum,(seqdbsize-exampleCount));
data = ECOMALLOC(words->size * sizeof(primer_t),
"Cannot allocate memory for fuzzy matching results");
for (i=0; i < words->size; i++)
{
data[i].word=WORD(words->words[i]);
data[i].inexample = 0;
data[i].outexample= 0;
data[i].directCount=ECOMALLOC(seqdbsize * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[i].directPos = ECOMALLOC(seqdbsize * sizeof(poslist_t),
"Cannot allocate memory for primer position");
data[i].reverseCount=ECOMALLOC(seqdbsize * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[i].reversePos = ECOMALLOC(seqdbsize * sizeof(poslist_t),
"Cannot allocate memory for primer position");
}
//build keywords automaton
ahoc_buildKeywordTree (&automaton_root, words, options);
//set fail links and output sets
ahoc_updateForFailAndOutput (&automaton_root);
//debug; print keywordtree in a gv file
//ahoc_graphKeywordTree (&automaton_root);
//loop on each sequence for its each base and find words
for (i=0; i < seqdbsize; i++)
{
if(database[i]->SQ_length <= options->primer_length) continue;
lmax = database[i]->SQ_length;
if (!options->circular)
lmax += options->primer_length-1;
curr_state = &automaton_root;
for (j=0,base=database[i]->SQ; j<lmax; j++,base++)
{
if (i==(uint32_t)database[i]->SQ_length) base=database[i]->SQ;
//code = encoder[(*base) - 'A'];
code = *base;
//if (iii++ < 30)
// fprintf (stderr, "%d:%d,", *base, code);
if (code < 0 || code > 3)
{
//if error char, start from root for next character
//+forget any incomplete words
curr_state = &automaton_root;
continue;
}
while (curr_state->next[code] == NULL) curr_state = curr_state->fail;
curr_state = curr_state->next[code];
//start position of primer is options->primer_length-1 chars back
pos = j-options->primer_length+1;
if (pos < 0) pos = database[i]->SQ_length+pos;
//set output, if there is some output on this state then
//+all words in the output set complete here, so increment their
//+found properties for current sequence
for (k=0; k<curr_state->output.count; k++)
{
if (curr_state->output.out_set[k].isdirect)
data[curr_state->output.out_set[k].wordidx].directCount[i]++;
else
data[curr_state->output.out_set[k].wordidx].reverseCount[i]++;
if (options->no_multi_match)
{
if ((data[curr_state->output.out_set[k].wordidx].directCount[i] +
data[curr_state->output.out_set[k].wordidx].reverseCount[i]) > 1)
//since multimach not allowd, set an indication on 1st seq position that
//+ a multimatch was found, so that this word will be filtered out
//+ and because of first postion we wont have to search the whole array
//+ to find if it voilated nomultimatch constraint for some seq
data[curr_state->output.out_set[k].wordidx].directCount[0] = 2;
else
{
if (curr_state->output.out_set[k].isdirect)
//direct word found on jth position of ith sequence
data[curr_state->output.out_set[k].wordidx].directPos[i].value = (uint32_t)pos;
else
//reverse word found on jth position of ith sequence
data[curr_state->output.out_set[k].wordidx].reversePos[i].value = (uint32_t)pos;
}
}
else
{
//okay multi match allowed
if (curr_state->output.out_set[k].isdirect)
{
if (data[curr_state->output.out_set[k].wordidx].directCount[i] == 1)
data[curr_state->output.out_set[k].wordidx].directPos[i].value = (uint32_t)pos;
else
{
//need to create or extend the positions list
if (data[curr_state->output.out_set[k].wordidx].directCount[i] == 2)
{
//for second element, first was put in .value, so dont forget to copy that in the array too
data[curr_state->output.out_set[k].wordidx].directPos[i].pointer = ECOMALLOC(2 * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[curr_state->output.out_set[k].wordidx].directPos[i].pointer[0] = data[curr_state->output.out_set[k].wordidx].directPos[i].value;
data[curr_state->output.out_set[k].wordidx].directPos[i].pointer[1] = (uint32_t)pos;
}
else
{
//for third or greater element
data[curr_state->output.out_set[k].wordidx].directPos[i].pointer = ECOREALLOC(data[curr_state->output.out_set[k].wordidx].directPos[i].pointer,
data[curr_state->output.out_set[k].wordidx].directCount[i] * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[curr_state->output.out_set[k].wordidx].directPos[i].pointer[data[curr_state->output.out_set[k].wordidx].directCount[i]-1] = (uint32_t)pos;
}
}
}
else
{
if (data[curr_state->output.out_set[k].wordidx].reverseCount[i] == 1)
data[curr_state->output.out_set[k].wordidx].reversePos[i].value = (uint32_t)pos;
else
{
//need to create or extend the positions list
if (data[curr_state->output.out_set[k].wordidx].reverseCount[i] == 2)
{
//for second element, first was put in .value, so dont forget to copy that in the array too
data[curr_state->output.out_set[k].wordidx].reversePos[i].pointer = ECOMALLOC(2 * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[curr_state->output.out_set[k].wordidx].reversePos[i].pointer[0] = data[curr_state->output.out_set[k].wordidx].reversePos[i].value;
data[curr_state->output.out_set[k].wordidx].reversePos[i].pointer[1] = (uint32_t)pos;
}
else
{
//for third or greater element
data[curr_state->output.out_set[k].wordidx].reversePos[i].pointer = ECOREALLOC(data[curr_state->output.out_set[k].wordidx].reversePos[i].pointer,
data[curr_state->output.out_set[k].wordidx].reverseCount[i] * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[curr_state->output.out_set[k].wordidx].reversePos[i].pointer[data[curr_state->output.out_set[k].wordidx].reverseCount[i]-1] = (uint32_t)pos;
}
}
}
}
//dont forget to increment inexample or outexample count, but only once for a sequence
if ((data[curr_state->output.out_set[k].wordidx].directCount[i] +
data[curr_state->output.out_set[k].wordidx].reverseCount[i]) == 1)
{
if (database[i]->isexample)
data[curr_state->output.out_set[k].wordidx].inexample++;
else
data[curr_state->output.out_set[k].wordidx].outexample++;
}
}
}
}
//Only thing that remains is to remove the failed words
for (i=0,j=0; i<words->size; i++)
{
fprintf(stderr,"Primers %5d/%lld analyzed => sequence : %s in %d example and %d counterexample sequences \r",
i+1,words->size,ecoUnhashWord(data[i].word,options->primer_length),
data[i].inexample,data[i].outexample);
//if (data[i].inexample < inSequenceQuorum || (data[i].directCount[0] == 2 && options->no_multi_match))
if (data[i].directCount[0] == 2 && options->no_multi_match)
{
//bad word, delete from the array
for (k=0; k<seqdbsize; k++)
{
if (data[i].directCount[k] > 1)
ECOFREE (data[i].directPos[k].pointer, "Cannot free position pointer.");
if (data[i].reverseCount[k] > 1)
ECOFREE (data[i].reversePos[k].pointer, "Cannot free position pointer.");
}
ECOFREE (data[i].directCount, "Cannot free position pointer.");
ECOFREE (data[i].directPos, "Cannot free position pointer.");
ECOFREE (data[i].reverseCount, "Cannot free position pointer.");
ECOFREE (data[i].reversePos, "Cannot free position pointer.");
}
else
{
//data[i].good = data[i].inexample >= inSequenceQuorum && data[i].outexample <= outSequenceQuorum;
data[i].good = data[i].outexample <= outSequenceQuorum;
goodPrimers+=data[i].good? 1:0;
if (j < i)
data[j] = data[i];
j++;
}
}
fprintf(stderr,"\n\nOn %lld analyzed primers %d respect quorum conditions\n",words->size,goodPrimers);
fprintf(stderr,"Conserved primers for further analysis : %d/%lld\n",j,words->size);
primers = ECOMALLOC(sizeof(primercount_t),"Cannot allocate memory for primer table");
primers->primers=ECOREALLOC(data,
j * sizeof(primer_t),
"Cannot reallocate memory for fuzzy matching results");
primers->size=j;
//free memory of keyword table
for (i=0; i<4; i++)
if (automaton_root.next[i] != &automaton_root)
ahoc_freeKeywordTree (automaton_root.next[i]);
return primers;
}
void ahoc_graphPrintNodesInfo (aho_state *node, FILE* gfile)
{
uint32_t i;
fprintf (gfile, "\"%d\"[\n", node->id);
fprintf (gfile, "label=\"%d\\n", node->id);
for (i=0; i<node->output.count; i++)
fprintf (gfile, "%d%c,", node->output.out_set[i].wordidx, node->output.out_set[i].isdirect?'d':'r');
fprintf (gfile, "\"\n];\n");
for (i=0; i<4; i++)
if (node->next[i] != NULL && node->next[i] != node)
ahoc_graphPrintNodesInfo (node->next[i], gfile);
}
void ahoc_graphPrintNodesLinks (aho_state *node, FILE* gfile)
{
uint32_t i;
static int j=0;
for (i=0; i<4; i++)
if (node->next[i] != NULL && node->next[i] != node)
{
fprintf (gfile, "\"%d\" -> \"%d\" [\n", node->id, node->next[i]->id);
fprintf (gfile, "label=\"%c\"\n];\n", "ACGT"[i]);
}
if (j++ < 40)
if (node->fail != NULL && node->fail != groot)
{
fprintf (gfile, "\"%d\" -> \"%d\" [\n", node->id, node->fail->id);
fprintf (gfile, "color= \"red\"\n];\n");
}
for (i=0; i<4; i++)
if (node->next[i] != NULL && node->next[i] != node)
ahoc_graphPrintNodesLinks (node->next[i], gfile);
}
void ahoc_graphKeywordTree (aho_state *root)
{
FILE *gfile;
groot=root;
gfile = fopen ("keywordtree.gv", "w");
fprintf (gfile, "digraph keywordtree {\n");
ahoc_graphPrintNodesInfo (root, gfile);
ahoc_graphPrintNodesLinks (root, gfile);
fprintf (gfile, "}\n");
fclose(gfile);
}

43
src/libecoprimer/ahocorasick.h Executable file
View File

@ -0,0 +1,43 @@
/*
* ahocorasick.h
*
* Created on: 26 march 2011
* Author: tiayyba
*/
#ifndef H_ahocorasick
#define H_ahocorasick
#include "ecoprimer.h"
typedef struct aho_output_t{
uint32_t wordidx; //index of strict word (dont save the word of 64B)
bool_t isdirect; //we need to find both direct and reverse words so we must know which one is it
}aho_output;
typedef struct aho_output_count_t{
uint32_t count;
aho_output *out_set;
}aho_output_count;
typedef struct aho_state_t{
int32_t id;
struct aho_state_t *next[4]; //for labels A=0,C=1,G=2 and T=3
struct aho_state_t *fail;
aho_output_count output;
}aho_state;
typedef struct queue_node_t {
aho_state *state_node;
struct queue_node_t *next;
}queue_node;
typedef struct{
queue_node *first;
queue_node *last;
}aho_queue;
pprimercount_t ahoc_lookforStrictPrimers (pecodnadb_t database, uint32_t seqdbsize,uint32_t exampleCount,
pwordcount_t words,poptions_t options);
#endif /* H_ahocorasick */

View File

@ -0,0 +1,131 @@
/*
* amplifiatree.c
*
* Created on: 7 mars 2009
* Author: coissac
*/
#include "ecoprimer.h"
#include <search.h>
static void cleanamplifia(pamplifia_t amplifia);
static void deleteamplifialist(pamplifialist_t list);
static int cmpamplifia(const void* p1,const void*p2);
static void cleanamplifiatlist(pamplifiacount_t list)
{
if (list->amplifias)
ECOFREE(list->amplifias,
"Free amplifia list");
}
static void cleanamplifia(pamplifia_t amplifia)
{
cleanamplifiatlist(&(amplifia->pcr));
}
static pamplifialist_t newamplifialist(pamplifialist_t parent, size_t size)
{
pamplifialist_t tmp;
tmp=ECOMALLOC(sizeof(amplifialist_t)+sizeof(amplifia_t)*(size-1),
"Cannot allocate new amplifia list");
tmp->amplifiaslots=size;
tmp->amplifiacount=0;
tmp->next=NULL;
if (parent)
parent->next=(void*)tmp;
return tmp;
}
static void deleteamplifialist(pamplifialist_t list)
{
size_t i;
if (list)
{
if (list->next)
{
deleteamplifialist(list->next);
list->next=NULL;
}
for (i=0; i < list->amplifiacount; i++)
cleanamplifia((list->amplifias)+i);
ECOFREE(list,"Delete amplifia list");
}
}
static int cmpamplifia(const void* p1,const void*p2)
{
pamplifia_t pr1,pr2;
pr1=(pamplifia_t)p1;
pr2=(pamplifia_t)p2;
if (pr1->p1 < pr2->p1) return -1;
if (pr1->p1 > pr2->p1) return 1;
if (pr1->asdirect1 < pr2->asdirect1) return -1;
if (pr1->asdirect1 > pr2->asdirect1) return 1;
if (pr1->p2 < pr2->p2) return -1;
if (pr1->p2 > pr2->p2) return 1;
if (pr1->asdirect2 < pr2->asdirect2) return -1;
if (pr1->asdirect2 > pr2->asdirect2) return 1;
return 0;
}
pamplifia_t amplifiaintree (amplifia_t key,
pamplifiatree_t amplifialist)
{
if (!amplifialist->tree)
return NULL;
return *((pamplifia_t*)tsearch((const void *)(&key),
&(amplifialist->tree),
cmpamplifia
));
}
pamplifia_t insertamplifia(amplifia_t key,
pamplifiatree_t list)
{
pamplifia_t current;
pamplifia_t found;
if (list->last->amplifiacount==list->last->amplifiaslots)
{
list->last->next=newamplifialist(list,100);
list->last=list->last->next;
}
current = list->last->amplifias + list->last->amplifiacount;
*current=key;
found = *((pamplifia_t*)tsearch((const void *)current,
&(list->tree),
cmpamplifia));
if (found==current)
list->last->amplifiacount++;
return found;
}
pamplifiatree_t initamplifiatree(pamplifiatree_t tree)
{
if (!tree)
tree = ECOMALLOC(sizeof(amplifiatree_t),"Cannot allocate amplifia tree");
tree->first=newamplifialist(NULL,500);
tree->last=tree->first;
tree->tree=NULL;
}

120
src/libecoprimer/apat.h Normal file
View File

@ -0,0 +1,120 @@
/* ==================================================== */
/* Copyright (c) Atelier de BioInformatique */
/* Dec. 94 */
/* File: apat.h */
/* Purpose: pattern scan */
/* History: */
/* 28/12/94 : <Gloup> ascan first version */
/* 14/05/99 : <Gloup> last revision */
/* ==================================================== */
#ifndef H_apat
#define H_apat
#include "libstki.h"
#include "inttypes.h"
#include "../libecoPCR/ecoPCR.h"
/* ----------------------------------------------- */
/* constantes */
/* ----------------------------------------------- */
#ifndef BUFSIZ
#define BUFSIZ 1024 /* io buffer size */
#endif
#define MAX_NAME_LEN BUFSIZ /* max length of sequence name */
#define ALPHA_LEN 4 /* alphabet length */
/* *DO NOT* modify */
#define MAX_PATTERN 4 /* max # of patterns */
/* *DO NOT* modify */
#define MAX_PAT_LEN 32 /* max pattern length */
/* *DO NOT* modify */
#define MAX_PAT_ERR 32 /* max # of errors */
/* *DO NOT* modify */
#define PATMASK 0x3ffffff /* mask for 26 symbols */
/* *DO NOT* modify */
#define OBLIBIT 0x4000000 /* bit 27 to 1 -> oblig. pos */
/* *DO NOT* modify */
/* mask for position */
#define ONEMASK 0x80000000 /* mask for highest position */
/* masks for Levenhstein edit */
#define OPER_IDT 0x00000000 /* identity */
#define OPER_INS 0x40000000 /* insertion */
#define OPER_DEL 0x80000000 /* deletion */
#define OPER_SUB 0xc0000000 /* substitution */
#define OPER_SHFT 30 /* <unused> shift */
/* Levenhstein Opcodes */
#define SOPER_IDT 0x0 /* identity */
#define SOPER_INS 0x1 /* insertion */
#define SOPER_DEL 0x2 /* deletion */
#define SOPER_SUB 0x3 /* substitution */
/* Levenhstein Opcodes masks */
#define OPERMASK 0xc0000000 /* mask for Opcodes */
#define NOPERMASK 0x3fffffff /* negate of previous */
/* ----------------------------------------------- */
/* data structures */
/* ----------------------------------------------- */
typedef uint32_t pattern_t[ALPHA_LEN], *ppattern_t;
/* -------------------- */
typedef struct { /* pattern */
/* -------------------- */
int patlen; /* pattern length */
int maxerr; /* max # of errors */
uint32_t omask; /* oblig. bits mask */
bool_t circular; /* is circular sequence */
} patternParam_t, *ppatternParam_t;
/* ----------------------------------------------- */
/* macros */
/* ----------------------------------------------- */
#ifndef NEW
#define NEW(typ) (typ*)malloc(sizeof(typ))
#define NEWN(typ, dim) (typ*)malloc((unsigned long)(dim) * sizeof(typ))
#define REALLOC(typ, ptr, dim) (typ*)realloc((void *) (ptr), (unsigned long)(dim) * sizeof(typ))
#define FREE(ptr) free((void *) ptr)
#endif
/* ----------------------------------------------- */
/* prototypes */
/* ----------------------------------------------- */
/* apat_search.c */
int32_t ManberNoErr(pecoseq_t pseq,ppattern_t pat,
ppatternParam_t param,
StackiPtr stkpos);
int32_t ManberSub(pecoseq_t pseq,ppattern_t pat,
ppatternParam_t param,
StackiPtr stkpos);
int32_t ManberAll(pecoseq_t pseq,ppattern_t pat,
ppatternParam_t param,
StackiPtr stkpos);
#endif /* H_apat */

View File

@ -0,0 +1,65 @@
/* ==================================================== */
/* Copyright (c) Atelier de BioInformatique */
/* Mar. 92 */
/* File: apat_parse.c */
/* Purpose: Codage du pattern */
/* History: */
/* 00/07/94 : <Gloup> first version (stanford) */
/* 00/11/94 : <Gloup> revised for DNA/PROTEIN */
/* 30/12/94 : <Gloup> modified EncodePattern */
/* for manber search */
/* 14/05/99 : <Gloup> indels added */
/* ==================================================== */
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "apat.h"
#include "ecoprimer.h"
/* IUPAC Dna */
static int32_t sDnaCode[] = {
/* IUPAC */
0x00000001 /* A */, 0x0000000E /* B */, 0x00000002 /* C */,
0x0000000D /* D */, 0x00000000 /* E */, 0x00000000 /* F */,
0x00000004 /* G */, 0x0000000B /* H */, 0x00000000 /* I */,
0x00000000 /* J */, 0x0000000C /* K */, 0x00000000 /* L */,
0x00000003 /* M */, 0x0000000F /* N */, 0x00000000 /* O */,
0x00000000 /* P */, 0x00000000 /* Q */, 0x00000005 /* R */,
0x00000006 /* S */, 0x00000008 /* T */, 0x00000008 /* U */,
0x00000007 /* V */, 0x00000009 /* W */, 0x00000000 /* X */,
0x0000000A /* Y */, 0x00000000 /* Z */
};
/* -------------------------------------------- */
/* internal replacement of gets */
/* -------------------------------------------- */
static char *sGets(char *buffer, int size) {
char *ebuf;
if (! fgets(buffer, size-1, stdin))
return NULL;
/* remove trailing line feed */
ebuf = buffer + strlen(buffer);
while (--ebuf >= buffer) {
if ((*ebuf == '\n') || (*ebuf == '\r'))
*ebuf = '\000';
else
break;
}
return buffer;
}
/* -------------------------------------------- */
/* Interface */
/* -------------------------------------------- */

View File

@ -0,0 +1,155 @@
/* ==================================================== */
/* Copyright (c) Atelier de BioInformatique */
/* Dec. 94 */
/* File: apat_search.c */
/* Purpose: recherche du pattern */
/* algorithme de Baeza-Yates/Gonnet */
/* Manber (agrep) */
/* History: */
/* 07/12/94 : <MFS> first version */
/* 28/12/94 : <Gloup> revised version */
/* 14/05/99 : <Gloup> last revision */
/* ==================================================== */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libstki.h"
#include "apat.h"
#define POP PopiOut
#define PUSH(s,v) PushiIn(&(s),(v))
#define TOPCURS CursiToTop
#define DOWNREAD ReadiDown
#define KRONECK(x, msk) ((~x & msk) ? 0 : 1)
#define MIN(x, y) ((x) < (y) ? (x) : (y))
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* NoError */
/* -------------------------------------------- */
int32_t ManberNoErr(pecoseq_t pseq,ppattern_t pat,
ppatternParam_t param,
StackiPtr stkpos)
{
uint32_t pos;
uint32_t smask, r;
uint8_t *data;
uint32_t end;
end = (size_t)(pseq->SQ_length);
if (param->circular)
end+=param->patlen - 1;
/* create local masks */
smask = r = 0x1L << param->patlen;
/* init. scan */
data = (uint8_t*)(pseq->SQ);
/* loop on text data */
for (pos = 0 ; pos < end ; pos++,data++) {
if (pos==pseq->SQ_length)
data=(uint8_t*)(pseq->SQ);
if (*data < 4)
r = (r >> 1) & pat[*data];
else
r=0;
if (r & 0x1L) {
PUSH(stkpos, pos - param->patlen + 1);
}
r |= smask;
}
return stkpos->top; /* aka # of hits */
}
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* Substitution only */
/* */
/* Note : r array is stored as : */
/* 0 0 r(0,j) r(0,j+1) r(1,j) r(1,j+1) ... */
/* */
/* -------------------------------------------- */
int32_t ManberSub(pecoseq_t pseq,ppattern_t pat,
ppatternParam_t param,
StackiPtr stkpos)
{
int e, found;
uint32_t pos;
uint32_t smask, cmask, sindx;
uint32_t *pr, r[2 * MAX_PAT_ERR + 2];
uint8_t *data;
uint32_t end;
end = (size_t)(pseq->SQ_length);
if (param->circular)
end+=param->patlen - 1;
/* create local masks */
r[0] = r[1] = 0x0;
cmask = smask = 0x1L << param->patlen;
for (e = 0, pr = r + 3 ; e <= param->maxerr ; e++, pr += 2)
*pr = cmask;
cmask = ~ param->omask;
/* init. scan */
data = (uint8_t*)(pseq->SQ);
/* loop on text data */
for (pos = 0 ; pos < end ; pos++,data++) {
if (pos==pseq->SQ_length)
data=(uint8_t*)(pseq->SQ);
sindx = (*data==4) ? 0:pat[*data];
for (e = found = 0, pr = r ; e <= param->maxerr ; e++, pr += 2) {
pr[2] = pr[3] | smask;
pr[3] = ((pr[0] >> 1) & cmask) /* sub */
| ((pr[2] >> 1) & sindx); /* ident */
if (pr[3] & 0x1L) { /* found */
if (! found) {
PUSH(stkpos, pos - param->patlen + 1);
}
found++;
}
}
}
return stkpos->top; /* aka # of hits */
}
/* -------------------------------------------- */
/* Baeza-Yates/Manber algorithm */
/* API call to previous functions */
/* -------------------------------------------- */
int32_t ManberAll(pecoseq_t pseq,ppattern_t pat,
ppatternParam_t param,
StackiPtr stkpos)
{
if (param->maxerr == 0)
return ManberNoErr(pseq,
pat, param,
stkpos);
else
return ManberSub(pseq,
pat, param,
stkpos);
}

View File

@ -0,0 +1,237 @@
/*
* aproxpattern.c
*
* Created on: 20 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
#include "apat.h"
#include <math.h>
static uint8_t encoder[] = {0, // A
4, // b
1, // C
4,4,4, // d, e, f
2, // G
4,4,4,4,4,4,4,4,4,4,4,4, // h,i,j,k,l,m,n,o,p,q,r,s
3,3, // T,U
4,4,4,4,4}; // v,w,x,y,z
ppattern_t buildPatternFromWord(word_t word, uint32_t patlen)
{
static pattern_t pattern;
uint32_t i;
for (i = 0 ; i < ALPHA_LEN ; i++)
pattern[i] = 0x0;
for (i=0;i < patlen; i++)
{
pattern[word & 3LLU] |= 1 << i;
word>>=2;
}
return pattern;
}
#ifdef IS_UPPER
#undef IS_UPPER
#endif
/* -------------------------------------------- */
/* encode sequence */
/* IS_UPPER is slightly faster than isupper */
/* -------------------------------------------- */
#define IS_UPPER(c) (((c) >= 'A') && ((c) <= 'Z'))
void encodeSequence(ecoseq_t *seq)
{
int i;
uint8_t *data;
char *cseq;
data = (uint8_t*)(seq->SQ);
cseq = seq->SQ;
for (i=0;i<(int)(seq->SQ_length);i++,data++,cseq++)
{
*data = encoder[(IS_UPPER(*cseq) ? *cseq : 'Z') - 'A'];
}
}
pprimercount_t lookforAproxPrimer(pecodnadb_t database, uint32_t seqdbsize,uint32_t exampleCount,
pwordcount_t words,poptions_t options)
{
pprimer_t data;
pprimercount_t primers;
ppattern_t pattern;
patternParam_t params;
uint32_t i;
uint32_t w;
uint32_t j;
Stacki positions;
uint32_t count=1;
uint32_t goodPrimers=0;
uint32_t inSequenceQuorum;
uint32_t outSequenceQuorum;
bool_t conserved = TRUE;
//poslist_t ttt;
inSequenceQuorum = (uint32_t)floor((float)exampleCount * options->sensitivity_quorum);
outSequenceQuorum = (uint32_t)floor((float)(seqdbsize-exampleCount) * options->false_positive_quorum);
fprintf(stderr," Primers should be at least present in %d/%d example sequences\n",inSequenceQuorum,exampleCount);
fprintf(stderr," Primers should not be present in more than %d/%d counterexample sequences\n",outSequenceQuorum,(seqdbsize-exampleCount));
data = ECOMALLOC(words->size * sizeof(primer_t),
"Cannot allocate memory for fuzzy matching results");
params.circular = options->circular;
params.maxerr = options->error_max;
// params.omask = (1 << options->strict_three_prime) -1;
params.omask = 0;
params.patlen = options->primer_length;
positions.val=NULL;
for (i=0,w=0; i < words->size; i++)
{
data[w].word=WORD(words->words[i]);
data[w].inexample = 0;
data[w].outexample= 0;
count = 1;
if (conserved)
{
data[w].directCount=ECOMALLOC(seqdbsize * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[w].directPos = ECOMALLOC(seqdbsize * sizeof(poslist_t),
"Cannot allocate memory for primer position");
data[w].reverseCount=ECOMALLOC(seqdbsize * sizeof(uint32_t),
"Cannot allocate memory for primer position");
data[w].reversePos = ECOMALLOC(seqdbsize * sizeof(poslist_t),
"Cannot allocate memory for primer position");
}
pattern = buildPatternFromWord(data[w].word,options->primer_length);
positions.val=NULL;
for (j=0; j < seqdbsize && (count < 2 || !options->no_multi_match); j++)
{
positions.cursor=0;
positions.top =0;
if (!positions.val)
{
positions.size=1;
positions.val = ECOMALLOC(sizeof(uint32_t),
"Cannot allocate memory for primer position");
}
count = ManberAll(database[j],pattern,&params,&positions);
data[w].directCount[j]=count;
if (count>1)
{
data[w].directPos[j].pointer = (uint32_t*)positions.val;
positions.val=NULL;
}
else
{
data[w].directPos[j].pointer=NULL;
if (count==1)
data[w].directPos[j].value = (uint32_t)*(positions.val);
}
}
pattern = buildPatternFromWord(ecoComplementWord(data[w].word,options->primer_length),
options->primer_length);
for (j=0; j < seqdbsize && (count < 2 || !options->no_multi_match); j++)
{
positions.cursor=0;
positions.top =0;
if (!positions.val)
{
positions.size=1;
positions.val = ECOMALLOC(sizeof(uint32_t),
"Cannot allocate memory for primer position");
}
count = ManberAll(database[j],pattern,&params,&positions);
data[w].reverseCount[j]=count;
if (count>1)
{
data[w].reversePos[j].pointer = (uint32_t*)positions.val;
positions.val=NULL;
}
else
{
data[w].reversePos[j].pointer=NULL;
if (count==1)
data[w].reversePos[j].value = (uint32_t)*(positions.val);
}
if (database[j]->isexample)
{
data[w].inexample+=(data[w].directCount[j] || data[w].reverseCount[j])? 1:0;
}
else
{
data[w].outexample+=(data[w].directCount[j] || data[w].reverseCount[j])? 1:0;
}
count+=data[w].directCount[j];
}
data[w].good = data[w].inexample >= inSequenceQuorum && data[w].outexample <= outSequenceQuorum;
goodPrimers+=data[w].good? 1:0;
fprintf(stderr,"Primers %5d/%lld analyzed => sequence : %s in %d example and %d counterexample sequences \r",
i+1,words->size,ecoUnhashWord(data[w].word,options->primer_length),
data[w].inexample,data[w].outexample);
conserved=data[w].inexample >= inSequenceQuorum;
conserved=conserved && (count < 2 || !options->no_multi_match);
if (conserved)
w++;
}
if (positions.val)
ECOFREE(positions.val,"Free stack position pointer");
if (!conserved)
{
ECOFREE(data[w].directCount,"Free direct count table");
ECOFREE(data[w].directPos,"Free direct count table");
ECOFREE(data[w].reverseCount,"Free direct count table");
ECOFREE(data[w].reversePos,"Free direct count table");
}
fprintf(stderr,"\n\nOn %lld analyzed primers %d respect quorum conditions\n",words->size,goodPrimers);
fprintf(stderr,"Conserved primers for further analysis : %d/%lld\n",w,words->size);
primers = ECOMALLOC(sizeof(primercount_t),"Cannot allocate memory for primer table");
primers->primers=ECOREALLOC(data,
w * sizeof(primer_t),
"Cannot reallocate memory for fuzzy matching results");
primers->size=w;
return primers;
}

29
src/libecoprimer/debug.h Normal file
View File

@ -0,0 +1,29 @@
/*
* debug.h
*
* Created on: 12 nov. 2008
* Author: coissac
*/
#ifndef DEBUG_H_
#define DEBUG_H_
#include <stdio.h>
#ifdef DEBUG
#define DEBUG_LOG(message,...) { \
char *text; \
(void)asprintf(&text,(message),##__VA_ARGS__); \
fprintf(stderr,"DEBUG %s (line %d) : %s\n",__FILE__,__LINE__,(text)); \
free(text); \
}
#else
#define DEBUG_LOG(message, ...)
#endif
#endif /* DEBUG_H_ */

View File

@ -0,0 +1,366 @@
/*
* epsort.h
*
* Created on: 6 nov. 2008
* Author: coissac
*/
#ifndef EPSORT_H_
#define EPSORT_H_
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include "ecotype.h"
#include "../libecoPCR/ecoPCR.h"
#include "../libthermo/nnparams.h"
#include "apat.h"
#define DEBUG
#include "debug.h"
/****
* Word format used :
*
* bit 63 : bad word -> this word should not be used
* bit 62 : multi word -> this word is not uniq in at least one seq
* bits 0-61 : hashed dna word of max size 31 pb
* code used for a : 00
* code used for c : 01
* code used for g : 10
* code used for t : 11
*/
typedef uint64_t word_t, *pword_t;
#define WORD(x) ((x) & 0x3FFFFFFFFFFFFFFFLLU)
#define WORD(x) ((x) & 0x3FFFFFFFFFFFFFFFLLU)
#define ISBADWORD(x) (((x) & 0x8000000000000000LLU) >> 63)
#define SETBADWORD(x) ((x) | 0x8000000000000000LLU)
#define RESETBADWORD(x) ((x) & 0x7FFFFFFFFFFFFFFFLLU)
#define ISMULTIWORD(x) (((x) & 0x4000000000000000LLU) >> 62)
#define SETMULTIWORD(x) ((x) | 0x4000000000000000LLU)
#define RESETMULTIWORD(x) ((x) & 0xBFFFFFFFFFFFFFFFLLU)
#define WORDMASK(s) ((1LLU << ((s) * 2)) -1)
#define LSHIFTWORD(x,s) (((x) << 2) & WORDMASK(s))
#define RSHIFTWORD(x,s) (((x) & WORDMASK(s))>> 2)
#define ERRORMASK(s) ((int32_t)((1LLU << (s)) -1))
#define RAPPENDBASE(x,s,c) (LSHIFTWORD((x),(s)) | (word_t)(c))
#define LAPPENDBASE(x,s,c) (RSHIFTWORD((x),(s)) | ((word_t)((~(c)) & 3) << (((s)-1) *2)))
#define ECO_ASSERT(x,message) if (!(x)) \
{ \
fprintf(stderr,"Assertion Error in %s (line %d): %s\n", \
__FILE__,\
__LINE__,\
message\
); \
exit(ECO_ASSERT_ERROR); \
}
#define MINI(x,y) (((x) < (y)) ? (x):(y))
#define MAXI(x,y) (((x) < (y)) ? (y):(x))
#define FWORDSIZE (13)
#define FWORDMASK WORDMASK(FWORDSIZE)
#define FILTERWORD(x) ((uint32_t)((x) & FWORDMASK))
#define CFILTERWORD(x,s) ((uint32_t)(((x) >> (((s)-FWORDSIZE)*2)) & FWORDMASK))
typedef struct {
pword_t words;
uint32_t *strictcount;
uint32_t inseqcount;
uint32_t outseqcount;
uint64_t size;
} wordcount_t, *pwordcount_t;
typedef union {
uint32_t *pointer;
uint32_t value;
} poslist_t, *pposlist_t;
/**
* primer_t structure store fuzzy match positions for a primer
* on all sequences
*/
typedef struct {
word_t word; //< code for the primer
uint32_t *directCount; //< Occurrence count on direct strand
pposlist_t directPos; //< list of position list on direct strand
uint32_t *reverseCount; //< Occurrence count on reverse strand
pposlist_t reversePos; //< list of position list on reverse strand
bool_t good; //< primer match more than quorum example and no
// more counterexample quorum.
uint32_t inexample; //< count of example sequences matching primer
uint32_t outexample; //< count of counterexample sequences matching primer
} primer_t, *pprimer_t;
/**
* primercount_t structure store fuzzy match positions for all primers
* on all sequences as a list of primer_t
*/
typedef struct {
pprimer_t primers;
uint32_t size;
} primercount_t, *pprimercount_t;
typedef struct {
pprimer_t primer;
uint32_t position;
bool_t strand;
} primermatch_t, *pprimermatch_t;
/*TR: Added*/
typedef struct {
pprimermatch_t matches;
uint32_t matchcount;
} primermatchcount_t, *pprimermatchcount_t;
typedef struct {
pecoseq_t sequence;
bool_t strand;
const char *amplifia;
int32_t length;
uint32_t begin;
uint32_t end;
} amplifia_t, *pamplifia_t;
typedef struct {
pamplifia_t amplifias;
uint32_t ampcount;
uint32_t ampslot;
} amplifiacount_t, *pamplifiacount_t;
typedef struct {
char *amplifia;
int32_t *taxonids;
uint32_t seqidcount;
uint32_t seqidindex;
} ampseqset_t, *pampseqset_t;
typedef struct {
int32_t taxonid;
char **amplifia;
uint32_t amplifiacount;
uint32_t amplifiaindex;
} taxampset_t, *ptaxampset_t;
typedef struct {
pprimer_t p1;
bool_t asdirect1;
pprimer_t p2;
bool_t asdirect2;
amplifiacount_t pcr;
uint32_t inexample; //< example sequence count
uint32_t outexample; //< counterexample sequence count
uint32_t intaxa; //< example taxa count
uint32_t outtaxa; //< counterexample taxa count
uint32_t notwellidentifiedtaxa;
int *wellIdentifiedSeqs; //< an array having elements equla to total seqs
// values are either 0 or 1, if seq is well identified
// its 1 else 0
int *coveredSeqs; //< an array having elements equal to total seqs, 1 if seq is covered else 0
// these statistics are relative to inexample sequences
uint32_t mind; //< minimum distance between primers
uint32_t maxd; //< maximum distance between primers
uint32_t sumd; //< distance sum
uint32_t amplifiacount;
float yule;
float quorumin;
float quorumout;
float bs;
float bc;
int32_t refsequence;
//
// uint32_t taxsetcount;
// uint32_t taxsetindex;
// ptaxampset_t taxset;
//
// uint32_t oktaxoncount;
uint32_t curseqid;
float p1temp; //strict primer1 melting temperature
float p1mintemp; //approx primer1 minimum melting temperature
float p2temp; //strict primer2 melting temperature
float p2mintemp; //approx primer2 minimum melting temperature
} pair_t, *ppair_t;
/*TR: Added*/
typedef struct {
size_t paircount;
size_t pairslots;
void* next;
pair_t pairs[1];
} pairlist_t, *ppairlist_t;
typedef struct {
ppairlist_t first;
ppairlist_t last;
void *tree;
int32_t count;
} pairtree_t, *ppairtree_t;
typedef struct {
pword_t words;
uint32_t *count;
uint32_t push;
uint32_t pop;
uint32_t size;
bool_t empty;
bool_t full;
} queue_t, *pqueue_t;
typedef struct {
pword_t words;
uint32_t *count;
uint32_t write;
uint32_t read1;
uint32_t read2;
uint32_t size;
} merge_t, *pmerge_t;
typedef struct {
const char *amplifia;
bool_t strand;
int32_t length;
int32_t taxoncount;
void *taxontree;
}amptotaxon_t, *pamptotaxon_t;
typedef struct {
int32_t taxid;
void *amptree;
}taxontoamp_t, *ptaxontoamp_t;
typedef struct {
bool_t printAC;
bool_t statistics;
bool_t filtering;
uint32_t lmin; //**< Amplifia minimal length
uint32_t lmax; //**< Amplifia maximal length
uint32_t error_max; //**< maximum error count in fuzzy search
uint32_t primer_length; //**< minimal length of the primers
int32_t *restricted_taxid; //**< limit amplification below these taxid
int32_t *ignored_taxid; //**< no amplification below these taxid
int32_t *exception_taxid;
char *prefix;
char *reference;
pecoseq_t refseq;
uint32_t refseqid;
uint32_t circular;
uint32_t doublestrand;
float strict_quorum;
float strict_exclude_quorum;
float sensitivity_quorum;
float false_positive_quorum;
uint32_t strict_three_prime;
int32_t r; //**< count of restrited taxa (restricted_taxid array size)
int32_t g; //**< count of ignored taxa (ignored_taxid array size)
int32_t e; //**< count of ignored taxa (ignored_taxid array size)
bool_t no_multi_match;
char taxonrank[20]; //TR to count ranks against a pair
int32_t taxonrankidx; //TR to count ranks against a pair
// Some statistics useful for options filters
int32_t dbsize;
int32_t insamples;
int32_t outsamples;
int32_t intaxa;
int32_t outtaxa;
int saltmethod;
float salt;
PNNParams pnparm;
bool_t print_sets_of_primers;
float specificity_threshold;
int links_cnt;
float max_links_percent;
bool_t filter_on_links;
} options_t, *poptions_t;
typedef ecoseq_t **pecodnadb_t;
void sortword(pword_t table,uint32_t N);
pecodnadb_t readdnadb(const char *name, ecotaxonomy_t *taxonomy, uint32_t *size,poptions_t options);
int isGoodTaxon(ecotaxonomy_t *taxonomy,int32_t taxon,poptions_t options);
int isExampleTaxon(ecotaxonomy_t *taxonomy,int32_t taxon,poptions_t options);
int isCounterExampleTaxon(ecotaxonomy_t *taxonomy,int32_t taxon,poptions_t options);
uint32_t ecoWordCount(uint32_t wordsize, uint32_t circular, ecoseq_t *seq);
pword_t ecoHashSequence(pword_t dest, uint32_t wordsize, uint32_t circular, uint32_t doublestrand, ecoseq_t *seq,uint32_t *size,int32_t *neededWords,uint32_t neededWordCount,
int32_t quorum);
uint32_t ecoCompactHashSequence(pword_t dest,uint32_t size);
const char* ecoUnhashWord(word_t word,uint32_t size);
word_t ecoComplementWord(word_t word,uint32_t size);
uint32_t ecoFindWord(pwordcount_t table,word_t word);
void ecomerge(pwordcount_t data,uint32_t s1,uint32_t s2,uint32_t remainingSeq,uint32_t seqQuorum);
pwordcount_t initCountTable(pwordcount_t table, uint32_t wordsize, uint32_t circular, uint32_t doublestrand,uint32_t seqQuorum,ecoseq_t *seq,int32_t *neededWords,uint32_t neededWordCount);
void addSeqToWordCountTable(pwordcount_t table, uint32_t wordsize, uint32_t circular, uint32_t doublestrand,uint32_t exampleCount,uint32_t seqQuorum,ecoseq_t *seq,int32_t *neededWords,uint32_t neededWordCount);
pqueue_t newQueue(pqueue_t queue, uint32_t size);
pqueue_t resizeQueue(pqueue_t queue, uint32_t size);
void pop(pqueue_t queue);
void push(pqueue_t queue, word_t word, uint32_t count);
pqueue_t cleanQueue(pqueue_t queue);
pwordcount_t lookforStrictPrimer(pecodnadb_t database, uint32_t seqdbsize,
uint32_t exampleCount, poptions_t options);
uint32_t filterMultiStrictPrimer(pwordcount_t strictprimers);
void encodeSequence(ecoseq_t *seq);
ppattern_t buildPatternFromWord(word_t word, uint32_t patlen);
pprimercount_t lookforAproxPrimer(pecodnadb_t database, uint32_t seqdbsize,uint32_t exampleCount,
pwordcount_t words,poptions_t options);
void sortmatch(pprimermatch_t table,uint32_t N);
ppairtree_t initpairtree(ppairtree_t tree);
ppair_t pairintree (pair_t key,ppairtree_t pairlist);
ppair_t insertpair(pair_t key,ppairtree_t list);
/*TR: Added*/
ppairtree_t buildPrimerPairs(pecodnadb_t seqdb,uint32_t seqdbsize,pprimercount_t primers,poptions_t options);
int32_t counttaxon(int32_t taxid);
int32_t getrankdbstats(pecodnadb_t seqdb,
uint32_t seqdbsize,
ecotaxonomy_t *taxonomy,
poptions_t options);
float taxonomycoverage(ppair_t pair, poptions_t options, pecodnadb_t seqdb,uint32_t seqdbsize);
char ecoComplementChar(char base);
void taxonomyspecificity (ppair_t pair, pecodnadb_t seqdb,uint32_t seqdbsize);
int32_t *filteringSeq(pecodnadb_t database, uint32_t seqdbsize,
uint32_t exampleCount,poptions_t options,uint32_t *size,int32_t sequenceQuorum);
void printSeqTest(pecodnadb_t seqdb,uint32_t seqdbsize);
#endif /* EPSORT_H_ */

View File

@ -0,0 +1,14 @@
/*
* ecotype.h
*
* Created on: 24 nov. 2008
* Author: coissac
*/
#ifndef ECOTYPE_H_
#define ECOTYPE_H_
typedef enum { FALSE=0,TRUE=1} bool_t, *pbool_t;
#endif /* ECOTYPE_H_ */

View File

@ -0,0 +1,222 @@
/*
* filtering.c
*
* Created on: 12 mai 2009
* Author: coissac
*/
#include "ecoprimer.h"
#include <string.h>
#include <math.h>
#include "hashencoder.h"
static int32_t *ecoFilteringHashSequence(int32_t *dest,
uint32_t circular,
uint32_t doublestrand,
ecoseq_t *seq,
uint32_t *size);
static int32_t *ecoFilteringHashSequence(int32_t *dest,
uint32_t circular,
uint32_t doublestrand,
ecoseq_t *seq,
uint32_t *size)
{
/*
* This function aims at building a vector of count for every possible hash codes
*
* The function must be applied once on each sequence
*
* The function allocates memory on the first call for the dest table
* The function also allocates memory for the static temporary table in_last_seq and
* the function must be called with *dest == -1 in order to free this temporary table
*
*/
static char *in_last_seq=NULL;
uint32_t i=0;
uint32_t j;
char *base;
int8_t code;
int32_t error=0;
word_t word=0;
word_t antiword=0;
uint32_t goodword;
uint32_t lmax=0;
// run on the first call;
if (dest==(void*)-1)
{
if (in_last_seq) ECOFREE(in_last_seq,"Free in last seq table");
return NULL;
}
/* FWORDSIZE = 13 => *size = 67 108 864
* FWORDSIZE = 14 => *size = 268 435 456
* FWORDSIZE = 15 => *size = 1 073 741 824
*/
*size = pow(4,FWORDSIZE);
/*
* in_last_seq is a vector of char as it is just to avoid counting twice (or more) a hash code (a DNA word)
* it is set to zero (with memset) and then filled with ones for each word belonging to the sequence
*/
if (!in_last_seq)
in_last_seq = ECOMALLOC(*size*sizeof(char),
"Cannot allocate filtering hash table");
memset(in_last_seq,0,*size*sizeof(char));
/*
* Allocate (on first call) the memory for the table of counts
*/
if (!dest)
{
dest = ECOMALLOC(*size*sizeof(int32_t),
"Cannot allocate filtering hash table");
memset(dest,0,*size*sizeof(int32_t));
}
lmax = seq->SQ_length;
if (!circular)
lmax-= FWORDSIZE-1;
// DEBUG_LOG("Sequence %s @ %d : %18.18s",seq->AC,i,(seq->SQ+i));
/*
* Compute first word of seq
*/
for (i=0, base = seq->SQ; i < FWORDSIZE && i < lmax; i++,base++)
{
error<<= 1;
error&=ERRORMASK(FWORDSIZE);
code = encoder[(*base) - 'A'];
if (code <0)
{
code = 0;
error|= 1;
}
word=RAPPENDBASE(word,FWORDSIZE,code);
if (doublestrand)
antiword=LAPPENDBASE(antiword,FWORDSIZE,code);
}
if (!error && i==FWORDSIZE)
{
goodword=(uint32_t)((doublestrand) ? MINI(word,antiword):word);
/*
* FB: I don't think the test is necessary as the table has just been initialized
*/
if (!in_last_seq[goodword])
{
in_last_seq[goodword]=1;
dest[goodword]++;
}
}
/*
* compute and store counts (avoid counting twice a word) for the other words of the seq
*/
for (j=1; j < lmax; j++,i++,base++)
{
// DEBUG_LOG("Sequence %s @ %d : %18.18s",seq->AC,j,(seq->SQ+j));
/* roll over the sequence for circular ones */
if (i==(uint32_t)seq->SQ_length) base=seq->SQ;
error<<= 1;
error&=ERRORMASK(FWORDSIZE);
//code = -1;
//if((*base) >= 'A' && (*base) <= 'Z')
code = encoder[(*base) - 'A'];
if (code <0)
{
code = 0;
error|= 1;
}
word=RAPPENDBASE(word,FWORDSIZE,code);
if (doublestrand)
antiword=LAPPENDBASE(antiword,FWORDSIZE,code);
if (!error)
{
if (doublestrand)
goodword=(uint32_t)MINI(word,antiword);
else
goodword=word;
if (!in_last_seq[goodword])
{
in_last_seq[goodword]=1;
dest[goodword]++;
}
}
}
return dest;
}
int32_t *filteringSeq(pecodnadb_t database, uint32_t seqdbsize,
uint32_t exampleCount,poptions_t options,uint32_t *size,int32_t sequenceQuorum)
{
int32_t *wordscount=NULL;
int32_t keep=0;
uint32_t i,j=0;
for (i=0;i<seqdbsize;i++)
{
if (database[i]->isexample && database[i]->SQ_length > options->primer_length)
{
j++;
wordscount=ecoFilteringHashSequence(wordscount,
options->circular,
options->doublestrand,
database[i],
size);
}
fprintf(stderr," Filtered sequences %5u/%5u \r",j,exampleCount);
}
fprintf(stderr,"\n");
for (i=0;i<*size;i++)
if (wordscount[i] >= sequenceQuorum)
keep++;
(void)ecoFilteringHashSequence((int32_t*)-1,
options->circular,
options->doublestrand,
NULL,
NULL);
fprintf(stderr,"ok\n Considered word of size %d for filtering : %d\n",FWORDSIZE,keep);
return wordscount;
}

View File

@ -0,0 +1,64 @@
/*
* goodtaxon.c
*
* Created on: 7 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
int isGoodTaxon(ecotaxonomy_t *taxonomy,int32_t taxon,poptions_t options)
{
int result;
result=((options->r == 0) || (eco_is_taxid_included(taxonomy,
options->restricted_taxid,
options->r,
taxonomy->taxons->taxon[taxon].taxid)
)) &&
((options->e == 0) || !(eco_is_taxid_included(taxonomy,
options->exception_taxid,
options->e,
taxonomy->taxons->taxon[taxon].taxid)
));
return result;
}
int isExampleTaxon(ecotaxonomy_t *taxonomy,int32_t taxon,poptions_t options)
{
int result;
result=( (options->r == 0) || (eco_is_taxid_included(taxonomy,
options->restricted_taxid,
options->r,
taxonomy->taxons->taxon[taxon].taxid)
)) &&
((options->e == 0) || !(eco_is_taxid_included(taxonomy,
options->exception_taxid,
options->e,
taxonomy->taxons->taxon[taxon].taxid)
));
return result;
}
int isCounterExampleTaxon(ecotaxonomy_t *taxonomy,int32_t taxon,poptions_t options)
{
int result;
result=((options->g != 0) && (eco_is_taxid_included(taxonomy,
options->ignored_taxid,
options->g,
taxonomy->taxons->taxon[taxon].taxid))
) || ((options->e != 0) && (eco_is_taxid_included(taxonomy,
options->exception_taxid,
options->e,
taxonomy->taxons->taxon[taxon].taxid))
);
return result;
}

View File

@ -0,0 +1,13 @@
/*
* hashencoder.h
*
* Created on: 12 mai 2009
* Author: coissac
*/
#ifndef HASHENCODER_H_
#define HASHENCODER_H_
extern int8_t encoder[];
#endif /* HASHENCODER_H_ */

View File

@ -0,0 +1,272 @@
/*
* hashsequence.c
*
* Created on: 7 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
static int cmpword(const void *x,const void *y);
#include "hashencoder.h"
int8_t encoder[] = {0, // A
-1, // b
1, // C
-1,-1,-1, // d, e, f
2, // G
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // h,i,j,k,l,m,n,o,p,q,r,s
3,3, // T,U
-1,-1,-1,-1,-1}; // v,w,x,y,z
uint32_t ecoWordCount(uint32_t wordsize, uint32_t circular, ecoseq_t *seq)
{
uint32_t wordcount;
wordcount = seq->SQ_length;
if (!circular) wordcount-=wordsize-1;
return wordcount;
}
pword_t ecoHashSequence(pword_t dest,
uint32_t wordsize,
uint32_t circular,
uint32_t doublestrand,
ecoseq_t *seq,
uint32_t *size,
int32_t *neededWords,
uint32_t neededWordCount,
int32_t quorum)
{
/*
* dest / out : words of the hashed sequence position per position
* wordsize / in : size of the word to be hashed (record error for that size) BUT not equal to FWORDSIZE ...
* ... the size of the word REALLY returned as a result
* circular / in : is the sequence circular
* doublestrand / in : if we have to hash on both strands of the sequence
* seq / in : the sequence in ecoseq format
* size / out : number of hashed words (size of the dest vector)
* neededWordCount / in : table hash codes of word counts in the full DB (used to filter words)
* quorum / in : minimum quorum used to filter words based on the neededWordCount table
*/
uint32_t i=0;
uint32_t j;
char *base;
int8_t code;
int32_t error=0;
word_t word=0;
word_t antiword=0;
word_t goodword;
uint32_t lmax=0;
(*size)=0;
lmax = seq->SQ_length;
if (!circular)
lmax-= wordsize-1;
if (!dest)
dest = ECOMALLOC(lmax*sizeof(word_t),
"I cannot allocate memory for sequence hashing"
);
//DEBUG_LOG("Sequence %s @ %d : %18.18s",seq->AC,i,(seq->SQ+i));
for (i=0, base = seq->SQ; i < wordsize && i < lmax; i++,base++)
{
error<<= 1;
error&=ERRORMASK(wordsize);
code = encoder[(*base) - 'A'];
if (code <0)
{
code = 0;
error|= 1;
}
word=RAPPENDBASE(word,wordsize,code);
if (doublestrand)
antiword=LAPPENDBASE(antiword,wordsize,code);
if (neededWordCount && i>=(FWORDSIZE-1))
{
goodword = (doublestrand) ? MINI(FILTERWORD(word),CFILTERWORD(antiword,wordsize)):FILTERWORD(word);
if (neededWords[(uint32_t)goodword]<quorum)
error|= (1 << (FWORDSIZE-1));
}
}
if (!error && i==wordsize)
{
dest[*size]=(doublestrand) ? MINI(word,antiword):word;
(*size)++;
}
for (j=1; j < lmax; j++,i++,base++)
{
//DEBUG_LOG("Sequence %s @ %d : %18.18s",seq->AC,j,(seq->SQ+j));
/* roll over the sequence for circular ones */
if (i==(uint32_t)seq->SQ_length) base=seq->SQ;
error<<= 1;
error&=ERRORMASK(wordsize);
code = encoder[(*base) - 'A'];
if (code <0)
{
code = 0;
error|= 1;
}
word=RAPPENDBASE(word,wordsize,code);
if (doublestrand)
antiword=LAPPENDBASE(antiword,wordsize,code);
if (neededWordCount)
{
goodword = (doublestrand) ? MINI(FILTERWORD(word),CFILTERWORD(antiword,wordsize)):FILTERWORD(word);
if (neededWords[(uint32_t)goodword]<quorum)
error|= (1 << (FWORDSIZE-1));
// else
// DEBUG_LOG("%s goodword = %p %d/%d (pos:%d error:%d)",seq->AC,goodword,neededWords[(uint32_t)goodword],quorum,i,error);
}
if (!error)
{
dest[*size]=(doublestrand) ? MINI(word,antiword):word;
(*size)++;
}
}
//DEBUG_LOG("%s goodword = %d",seq->AC,*size);
return dest;
}
uint32_t ecoCompactHashSequence(pword_t table,uint32_t size)
{
/*
*
* MULTIWORD is a word occurring more than once in a sequence
*
*/
uint32_t i,j;
word_t current;
// bool_t here=FALSE;
sortword(table,size);
current = 0;
current=SETMULTIWORD(current); /* build impossible word for the first loop cycle */
// if (strcmp(ecoUnhashWord(table[size-1],18),"GTTTGTTCAACGATTAAA")==0)
// here=TRUE;
for (i=0,j=0; j < size;j++)
{
if (WORD(table[j])!=current)
{
current =table[j];
table[i]=current;
i++;
}
else
table[i]=SETMULTIWORD(table[i]);
}
// if (strcmp(ecoUnhashWord(WORD(table[i-1]),18),"TACGACCTCGATGTTGGA")==0)
// DEBUG_LOG("winner %d",i)
return i;
}
const char* ecoUnhashWord(word_t word,uint32_t size)
{
static char buffer[32];
static char decode[]="ACGT";
uint32_t i;
for (i=0; i < size; i++)
{
buffer[i]=decode[(word >> (2 * (size - 1 -i))) & 3];
}
buffer[size]=0;
return buffer;
}
word_t ecoComplementWord(word_t word,uint32_t size)
{
word_t rep=0;
uint32_t i;
// DEBUG_LOG("%llx %llx",word,~word);
word=(~word) & WORDMASK(size);
for (i=0;i < size; i++)
{
rep = RAPPENDBASE(rep,size,word & 3LLU);
// DEBUG_LOG("%016llx %016llx %016llx",word,word & 3LLU,rep);
word>>=2;
}
// DEBUG_LOG("Complemented = %s",ecoUnhashWord(rep,18));
return rep;
}
static int cmpword(const void *x,const void *y)
{
word_t w1 = *(pword_t)x;
word_t w2 = *(pword_t)y;
w1 = WORD(w1);
w2 = WORD(w2);
if (w1 < w2)
return -1;
if (w1 > w2)
return +1;
return 0;
}
uint32_t ecoFindWord(pwordcount_t table,word_t word)
{
pword_t dest;
dest = (pword_t)bsearch((const void*)&word,(const void*)table->words,table->size,sizeof(word_t),cmpword);
if (dest)
return dest - table->words;
else
return ~0;
}
char ecoComplementChar(char base)
{
return (base < 4)? ~base & 3: 4;
}

View File

@ -16,8 +16,8 @@
#include <stdlib.h>
#include <string.h>
#include "Gtypes.h"
#include "libstki.h"
#include "ecoprimer.h"
/* ============================ */
@ -29,7 +29,7 @@
#define ShrinkStack(stkh) ResizeStacki((stkh), (*stkh)->size >> 1)
static Int16 sStkiLastError = kStkiNoErr;
static int16_t sStkiLastError = kStkiNoErr;
/* -------------------------------------------- */
/* gestion des erreurs */
@ -38,9 +38,9 @@ static Int16 sStkiLastError = kStkiNoErr;
/* @function: StkiError */
/* -------------------------------------------- */
Int16 StkiError(Bool reset)
int16_t StkiError(bool_t reset)
{
Int16 err;
int16_t err;
err = sStkiLastError;
@ -57,7 +57,7 @@ Int16 StkiError(Bool reset)
/* @function: NewStacki */
/* -------------------------------------------- */
StackiPtr NewStacki(Int32 size)
StackiPtr NewStacki(int32_t size)
{
StackiPtr stki;
@ -68,7 +68,7 @@ StackiPtr NewStacki(Int32 size)
stki->top = 0;
stki->cursor = 0;
if ( ! (stki->val = NEWN(Int32, size))) {
if ( ! (stki->val = NEWN(int32_t, size))) {
sStkiLastError = kStkiMemErr;
return FreeStacki(stki);
}
@ -88,8 +88,8 @@ StackiPtr FreeStacki(StackiPtr stki)
{
if (stki) {
if (stki->val)
FREE(stki->val);
FREE(stki);
ECOFREE(stki->val,"Free stack values");
ECOFREE(stki,"Free stack");
}
return NULL;
@ -102,9 +102,9 @@ StackiPtr FreeStacki(StackiPtr stki)
/* @function: NewStackiVector */
/* -------------------------------------------- */
StackiHdle NewStackiVector(Int32 vectSize, Int32 stackSize)
StackiHdle NewStackiVector(int32_t vectSize, int32_t stackSize)
{
Int32 i;
int32_t i;
StackiHdle stkh;
if (! (stkh = NEWN(StackiPtr, vectSize))) {
@ -127,14 +127,14 @@ StackiHdle NewStackiVector(Int32 vectSize, Int32 stackSize)
/* @function: FreeStackiVector */
/* -------------------------------------------- */
StackiHdle FreeStackiVector(StackiHdle stkh, Int32 vectSize)
StackiHdle FreeStackiVector(StackiHdle stkh, int32_t vectSize)
{
Int32 i;
int32_t i;
if (stkh) {
for (i = 0 ; i < vectSize ; i++)
(void) FreeStacki(stkh[i]);
FREE(stkh);
ECOFREE(stkh,"Free stack vector");
}
return NULL;
@ -147,12 +147,12 @@ StackiHdle FreeStackiVector(StackiHdle stkh, Int32 vectSize)
/* @function: ResizeStacki */
/* -------------------------------------------- */
Int32 ResizeStacki(StackiHdle stkh, Int32 size)
int32_t ResizeStacki(StackiHdle stkh, int32_t size)
{
Int32 resize = 0; /* assume error */
Int32 *val;
int32_t resize = 0; /* assume error */
int32_t *val;
if ((val = REALLOC(Int32, (*stkh)->val, size))) {
if ((val = ECOREALLOC((*stkh)->val, size * sizeof(int32_t),"Cannot reallocate stack values"))) {
(*stkh)->size = resize = size;
(*stkh)->val = val;
}
@ -170,14 +170,14 @@ Int32 ResizeStacki(StackiHdle stkh, Int32 size)
/* @function: PushiIn */
/* -------------------------------------------- */
Bool PushiIn(StackiHdle stkh, Int32 val)
bool_t PushiIn(StackiHdle stkh, int32_t val)
{
if (((*stkh)->top >= (*stkh)->size) && (! ExpandStack(stkh)))
return Faux;
return FALSE;
(*stkh)->val[((*stkh)->top)++] = val;
return Vrai;
return TRUE;
} /* end of PushiIn */
@ -187,10 +187,10 @@ Bool PushiIn(StackiHdle stkh, Int32 val)
/* @function: PopiOut */
/* -------------------------------------------- */
Bool PopiOut(StackiHdle stkh, Int32 *val)
bool_t PopiOut(StackiHdle stkh, int32_t *val)
{
if ((*stkh)->top <= 0)
return Faux;
return FALSE;
*val = (*stkh)->val[--((*stkh)->top)];
@ -199,7 +199,7 @@ Bool PopiOut(StackiHdle stkh, Int32 *val)
(void) ShrinkStack(stkh);
return Vrai;
return TRUE;
} /* end of PopiOut */
@ -209,14 +209,14 @@ Bool PopiOut(StackiHdle stkh, Int32 *val)
/* @function: ReadiDown */
/* -------------------------------------------- */
Bool ReadiDown(StackiPtr stki, Int32 *val)
bool_t ReadiDown(StackiPtr stki, int32_t *val)
{
if (stki->cursor <= 0)
return Faux;
return FALSE;
*val = stki->val[--(stki->cursor)];
return Vrai;
return TRUE;
} /* end of ReadiDown */
@ -226,14 +226,14 @@ Bool ReadiDown(StackiPtr stki, Int32 *val)
/* @function: ReadiUp */
/* -------------------------------------------- */
Bool ReadiUp(StackiPtr stki, Int32 *val)
bool_t ReadiUp(StackiPtr stki, int32_t *val)
{
if (stki->cursor >= stki->top)
return Faux;
return FALSE;
*val = stki->val[(stki->cursor)++];
return Vrai;
return TRUE;
} /* end of ReadiUp */
@ -250,8 +250,7 @@ void CursiToTop(StackiPtr stki)
} /* end of CursiToTop */
void CursiToBottom(stki)
StackiPtr stki;
void CursiToBottom(StackiPtr stki)
{
stki->cursor = 0;
@ -265,7 +264,7 @@ void CursiToBottom(stki)
void CursiSwap(StackiPtr stki)
{
Int32 tmp;
int32_t tmp;
if ((stki->top <= 0) || (stki->cursor < 0))
return;
@ -284,10 +283,10 @@ void CursiSwap(StackiPtr stki)
/* @function: SearchDownStacki */
/* -------------------------------------------- */
Bool SearchDownStacki(StackiPtr stki, Int32 sval)
bool_t SearchDownStacki(StackiPtr stki, int32_t sval)
{
Int32 val;
Bool more;
int32_t val;
bool_t more;
while ((more = ReadiDown(stki, &val)))
if (val == sval)
@ -306,9 +305,9 @@ Bool SearchDownStacki(StackiPtr stki, Int32 sval)
/* @function: BinSearchStacki */
/* -------------------------------------------- */
Bool BinSearchStacki(StackiPtr stki, Int32 sval)
bool_t BinSearchStacki(StackiPtr stki, int32_t sval)
{
Int32 midd, low, high, span;
int32_t midd, low, high, span;
low = 0;
high = stki->top - 1;
@ -321,7 +320,7 @@ Bool BinSearchStacki(StackiPtr stki, Int32 sval)
if (span == 0) {
stki->cursor = midd;
return Vrai;
return TRUE;
}
if (span > 0)
@ -330,7 +329,7 @@ Bool BinSearchStacki(StackiPtr stki, Int32 sval)
low = midd + 1;
}
return Faux;
return FALSE;
} /* end of BinSearchStacki */
@ -340,13 +339,13 @@ Bool BinSearchStacki(StackiPtr stki, Int32 sval)
/* @function: SameStacki */
/* -------------------------------------------- */
Bool SameStacki(StackiPtr stki1, StackiPtr stki2)
bool_t SameStacki(StackiPtr stki1, StackiPtr stki2)
{
if (stki1->top != stki2->top)
return Faux;
return FALSE;
return ((memcmp(stki1->val, stki2->val,
stki1->top * sizeof(Int32)) == 0) ? Vrai : Faux);
stki1->top * sizeof(int32_t)) == 0) ? TRUE : FALSE);
} /* end of SameStacki */
@ -357,12 +356,12 @@ Bool SameStacki(StackiPtr stki1, StackiPtr stki2)
/* @function: ReverseStacki */
/* -------------------------------------------- */
Bool ReverseStacki(StackiPtr stki)
bool_t ReverseStacki(StackiPtr stki)
{
Int32 *t, *b, swp;
int32_t *t, *b, swp;
if (stki->top <= 0)
return Faux;
return FALSE;
b = stki->val;
t = b + stki->top - 1;
@ -373,7 +372,7 @@ Bool ReverseStacki(StackiPtr stki)
*b++ = swp;
}
return Vrai;
return TRUE;
} /* end of ReverseStacki */

View File

@ -11,12 +11,13 @@
/* 14/05/99 : <Gloup> last revision */
/* ==================================================== */
#ifndef _H_Gtypes
#include "Gtypes.h"
#endif
#ifndef _H_libstki
#define _H_libstki
#include "ecotype.h"
#include <stdint.h>
/* ==================================================== */
/* Constantes de dimensionnement */
/* ==================================================== */
@ -29,8 +30,8 @@
#define kStkiNoErr 0 /* ok */
#define kStkiMemErr 1 /* not enough memory */
#define kStkiReset Vrai
#define kStkiGet Faux
#define kStkiReset TRUE
#define kStkiGet FALSE
/* ==================================================== */
/* Macros standards */
@ -38,8 +39,8 @@
#ifndef NEW
#define NEW(typ) (typ*)malloc(sizeof(typ))
#define NEWN(typ, dim) (typ*)malloc((unsigned long)(dim) * sizeof(typ))
#define REALLOC(typ, ptr, dim) (typ*)realloc((void *) (ptr), (unsigned long)(dim) * sizeof(typ))
#define NEWN(typ, dim) (typ*)malloc((uint32_t)(dim) * sizeof(typ))
#define REALLOC(typ, ptr, dim) (typ*)realloc((void *) (ptr), (uint32_t)(dim) * sizeof(typ))
#define FREE(ptr) free((Ptr) ptr)
#endif
@ -53,10 +54,10 @@
/* -------------------- */
typedef struct Stacki {
/* ---------------------*/
Int32 size; /* stack size */
Int32 top; /* current free pos. */
Int32 cursor; /* current cursor */
Int32 *val; /* values */
int32_t size; /* stack size */
int32_t top; /* current free pos. */
int32_t cursor; /* current cursor */
int32_t *val; /* values */
/* ---------------------*/
} Stacki, *StackiPtr, **StackiHdle;
@ -68,20 +69,23 @@ typedef struct Stacki {
/* libstki.c */
Int16 StkiError (Bool reset );
StackiPtr NewStacki (Int32 size );
int16_t StkiError (bool_t reset );
StackiPtr NewStacki (int32_t size );
StackiPtr FreeStacki (StackiPtr stki );
StackiHdle NewStackiVector (Int32 vectSize, Int32 stackSize );
StackiHdle FreeStackiVector (StackiHdle stkh, Int32 vectSize );
Int32 ResizeStacki (StackiHdle stkh , Int32 size );
Bool PushiIn (StackiHdle stkh , Int32 val );
Bool PopiOut (StackiHdle stkh , Int32 *val );
Bool ReadiDown (StackiPtr stki , Int32 *val );
Bool ReadiUp (StackiPtr stki , Int32 *val );
StackiHdle NewStackiVector (int32_t vectSize, int32_t stackSize );
StackiHdle FreeStackiVector (StackiHdle stkh, int32_t vectSize );
int32_t ResizeStacki (StackiHdle stkh , int32_t size );
bool_t PushiIn (StackiHdle stkh , int32_t val );
bool_t PopiOut (StackiHdle stkh , int32_t *val );
bool_t ReadiDown (StackiPtr stki , int32_t *val );
bool_t ReadiUp (StackiPtr stki , int32_t *val );
void CursiToTop (StackiPtr stki );
void CursiToBottom (StackiPtr stki );
void CursiSwap (StackiPtr stki );
Bool SearchDownStacki (StackiPtr stki , Int32 sval );
Bool BinSearchStacki (StackiPtr stki , Int32 sval );
Bool SameStacki (StackiPtr stki1 , StackiPtr stki2 );
Bool ReverseStacki (StackiPtr stki );
bool_t SearchDownStacki (StackiPtr stki , int32_t sval );
bool_t BinSearchStacki (StackiPtr stki , int32_t sval );
bool_t SameStacki (StackiPtr stki1 , StackiPtr stki2 );
bool_t ReverseStacki (StackiPtr stki );
void CursiToBottom (StackiPtr stki );
#endif /* _H_libstki */

View File

@ -0,0 +1,7 @@
/*
* mapping.c
*
* Created on: 25 nov. 2008
* Author: coissac
*/

201
src/libecoprimer/merge.c Normal file
View File

@ -0,0 +1,201 @@
/*
* merge.c
*
* Created on: 11 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
static pmerge_t mergeInit(pmerge_t merge,pwordcount_t data,uint32_t s1,uint32_t s2);
static pmerge_t mergeInit(pmerge_t merge, pwordcount_t data, uint32_t s1, uint32_t s2)
{
merge->words = data->words;
merge->count = data->strictcount;
merge->write = 0;
merge->read1 = 0;
merge->read2 = s1;
merge->size = s1+s2;
return merge;
}
typedef enum {S1=1,S2=2,STACK=3} source_t;
void ecomerge(pwordcount_t data,uint32_t s1,uint32_t s2,uint32_t remainingSeq,uint32_t seqQuorum)
{
/*
* data / in out : the table that contains the two parts to be merged
* s1 / in : end of the first part of the table
* s2 / in : end of the second part of the table
* remainingSeq / in : the number of remaining seqs to be added to the table
* seqQuorum / in : the minimum number of sequences in which a pattern must appear
*/
merge_t merged;
source_t source;
word_t currentword,tmpword;
uint32_t currentcount,tmpcount;
int same;
queue_t queue;
// int nsame=0;
uint32_t maxcount=0;
bool_t writed=TRUE;
// DEBUG_LOG("Coucou %p s1= %d s2= %d",data,s1,s2)
/*
* init the merged structure (used only for coding convenience, never returned, allocated on the C-stack)
* note that :
* merged.words : hashcodes (initialized to data->words)
* merged.count : counts of each word (initialized to data->strictcount)
* merged.read1 : index of the first word of the first subtable (initialized to 0)
* merged.read1 : index of the first word of the first subtable (initialized to 0)
* merged.read2 : index of the first word of the second subtable (initialized to s1)
* merged.size : total size of the table (initialized to s1+s2)
*
* allocate a new stack of size min(s1, s2)
*/
(void)mergeInit(&merged,data,s1,s2);
(void)newQueue(&queue,MINI(s1,s2));
/* true until
* merged.read1 == s1 AND merged.read2 == merged.size, i.e. ALL words have been processed
*/
while (merged.read1 < s1 || merged.read2 < merged.size)
{
/*
* initialize current{word,count} from either STACK (if not empty) or first table (S1)
*/
if (! queue.empty)
{
currentword = queue.words[queue.pop];
currentcount = queue.count[queue.pop];
source=STACK;
}
else
{
currentword = merged.words[merged.read1];
currentcount = merged.count[merged.read1];
source=S1;
}
/*
* IF there are some words in the second subtable remaining to be processed AND
* its first word is lower than current word
* THEN initialize current{word,count} from the second table (S2)
*
*/
if (merged.read2 < merged.size &&
WORD(currentword) > WORD(merged.words[merged.read2]))
{
currentword = merged.words[merged.read2];
currentcount = merged.count[merged.read2];
source = S2;
}
/*
* record if the two words in the both subtable are the same
*/
same = (source != S2) && (WORD(currentword) == WORD(merged.words[merged.read2]));
// nsame+=same;
// DEBUG_LOG("Merging : r1 = %d s1 = %d r2 = %d size = %d word = %s source=%u same=%u",merged.read1,s1,merged.read2-s1,merged.size,ecoUnhashWord(currentword,18),source,same)
/*
* merge step (AND apply the quorum property)
* update merged.read1 AND/OR merged.read2
* record the word and its count in the table
*/
tmpword = merged.words[merged.write];
tmpcount= merged.count[merged.write];
merged.words[merged.write] = currentword;
merged.count[merged.write] = currentcount;
if (source != S2)
{
if (same)
{
merged.count[merged.write]+=merged.count[merged.read2];
if (ISMULTIWORD(currentword) || ISMULTIWORD(merged.words[merged.read2]))
merged.words[merged.write]=SETMULTIWORD(currentword);
merged.read2++;
}
if (source==STACK)
pop(&queue);
merged.read1++;
}
else
merged.read2++;
if (writed && merged.read1 <= merged.write && merged.write < s1)
push(&queue,tmpword,tmpcount);
if (merged.count[merged.write] > maxcount)
maxcount=merged.count[merged.write];
writed = remainingSeq + merged.count[merged.write] >= seqQuorum;
if (writed)
merged.write++;
// else
// DEBUG_LOG("Remove word : %s count : %d remainingSeq : %d total : %d Quorum : %d",
// ecoUnhashWord(currentword,18),merged.count[merged.write],remainingSeq,maxcount+remainingSeq,seqQuorum);
} /* while loop */
// DEBUG_LOG("r1 : %d r2 : %d qsize : %d nsame : %d tot : %d write : %s count : %d source : %d size : %d pop : %d push : %d empty : %d",merged.read1,merged.read2-s1,qsize,nsame,qsize+nsame,ecoUnhashWord(currentword,18),currentcount,source,queue.size,queue.pop,queue.push,queue.empty)
/*
* finish the merging with words not processed (AND apply the quorum property)
* they are stored in the second subtable (IF)
* OR in the queue (ELSE)
*/
if (merged.read2 < merged.size)
{
//DEBUG_LOG("end1 %d %d/%d %d/%d",merged.write,merged.read1,s1,merged.read2,merged.size);
for (;merged.read2 < merged.size;merged.read2++)
{
merged.words[merged.write]=merged.words[merged.read2];
merged.count[merged.write]=merged.count[merged.read2];
if (remainingSeq + merged.count[merged.write] >= seqQuorum)
merged.write++;
}
}
else {
//DEBUG_LOG("end2 %d %d/%d %d/%d",merged.write,merged.read1,s1,merged.read2,merged.size);
while (! queue.empty)
{
// DEBUG_LOG("write : %s count : %d write : %d size : %d pop : %d push : %d empty : %d",ecoUnhashWord(queue.words[queue.pop],18),queue.count[queue.pop],merged.write,queue.size,queue.pop,queue.push,queue.empty)
merged.words[merged.write]=queue.words[queue.pop];
merged.count[merged.write]=queue.count[queue.pop];
pop(&queue);
if (remainingSeq + merged.count[merged.write] >= seqQuorum)
merged.write++;
}
}
data->size = merged.write;
cleanQueue(&queue);
// DEBUG_LOG("Max count : %d remainingSeq : %d total : %d Quorum : %d",maxcount,remainingSeq,maxcount+remainingSeq,seqQuorum)
// DEBUG_LOG("Second word : %s",ecoUnhashWord(data->words[1],18))
// DEBUG_LOG("Last word : %s",ecoUnhashWord(data->words[data->size-1],18))
}

460
src/libecoprimer/pairs.c Normal file
View File

@ -0,0 +1,460 @@
/*
* pairs.c
*
* Created on: 15 d<>c. 2008
* Author: coissac
*/
#include "ecoprimer.h"
#include <string.h>
#include <stdlib.h>
#include "../libthermo/thermostats.h"
static void buildPrimerPairsForOneSeq(uint32_t seqid,
pecodnadb_t seqdb,
pprimercount_t primers,
ppairtree_t pairs,
poptions_t options);
/*************************************
*
* pair collection management
*
*************************************/
#ifdef MASKEDCODE
char *addamplifiasetelem (ppair_t pair, char* amplifia, int32_t taxid)
{
uint32_t i;
uint32_t j;
char *ampused = NULL;
if(pair->ampsetcount == 0)
{
pair->ampsetcount = 500;
pair->ampsetindex = 0;
pair->ampset = ECOMALLOC(pair->ampsetcount * sizeof(ampseqset_t),"Cannot allocate amplifia set");
}
for (i = 0; i < pair->ampsetindex; i++)
{
if (strcmp (pair->ampset[i].amplifia, amplifia) == 0)
{
ampused = pair->ampset[i].amplifia;
break;
}
}
if (i == 0)
{
pair->ampset[i].seqidcount = 100;
pair->ampset[i].seqidindex = 0;
pair->ampset[i].taxonids = ECOMALLOC(pair->ampset[i].seqidcount * sizeof(uint32_t),"Cannot allocate amplifia sequence table");
}
if (pair->ampsetindex == pair->ampsetcount)
{
pair->ampsetcount += 500;
pair->ampset = ECOREALLOC(pair->ampset, pair->ampsetcount * sizeof(ampseqset_t), "Cannot allocate amplifia set");
}
if (pair->ampset[i].seqidindex == pair->ampset[i].seqidcount)
{
pair->ampset[i].seqidcount += 100;
pair->ampset[i].taxonids = ECOREALLOC(pair->ampset[i].taxonids, pair->ampset[i].seqidcount * sizeof(int32_t), "Cannot allocate amplifia sequence table");
}
if (pair->ampset[i].amplifia == NULL)
{
pair->ampset[i].amplifia = amplifia;
pair->ampsetindex++;
}
for (j = 0; j < pair->ampset[i].seqidindex; j++)
{
if (pair->ampset[i].taxonids[j] == taxid) break;
}
if (j == pair->ampset[i].seqidindex)
pair->ampset[i].taxonids[pair->ampset[i].seqidindex++] = taxid;
return ampused;
}
void addtaxampsetelem (ppair_t pair, int32_t taxid, char *amplifia)
{
uint32_t i;
uint32_t j;
if(pair->taxsetcount == 0)
{
pair->taxsetcount = 500;
pair->taxsetindex = 0;
pair->taxset = ECOMALLOC(pair->taxsetcount * sizeof(taxampset_t),"Cannot allocate taxon set");
}
for (i = 0; i < pair->taxsetindex; i++)
{
if (pair->taxset[i].taxonid == taxid) break;
}
if (i == 0)
{
pair->taxset[i].amplifiacount = 100;
pair->taxset[i].amplifiaindex = 0;
pair->taxset[i].amplifia = ECOMALLOC(pair->taxset[i].amplifiacount * sizeof(char *),"Cannot allocate amplifia table");
}
if (pair->taxsetindex == pair->taxsetcount)
{
pair->taxsetcount += 500;
pair->taxset = ECOREALLOC(pair->taxset, pair->taxsetcount * sizeof(taxampset_t), "Cannot allocate taxon set");
}
if (pair->taxset[i].amplifiaindex == pair->taxset[i].amplifiacount)
{
pair->taxset[i].amplifiacount += 100;
pair->taxset[i].amplifia = ECOREALLOC(pair->taxset[i].amplifia, pair->taxset[i].amplifiacount * sizeof(char *), "Cannot allocate amplifia table");
}
if (pair->taxset[i].taxonid == 0)
{
pair->taxset[i].taxonid = taxid;
pair->taxsetindex++;
}
for (j = 0; j < pair->taxset[i].amplifiaindex; j++)
{
if (strcmp(pair->taxset[i].amplifia[j], amplifia) == 0) break;
}
if (j == pair->taxset[i].amplifiaindex)
{
pair->taxset[i].amplifia[j] = amplifia;
pair->taxset[i].amplifiaindex++;
}
}
char *getamplifia (pecoseq_t seq, uint32_t start, uint32_t len)
{
fprintf(stderr,"start : %d length : %d\n",start,len);
char *amplifia = ECOMALLOC((len + 1) * sizeof(char),"Cannot allocate amplifia");
char *seqc = &seq->SQ[start];
strncpy(amplifia, seqc, len);
return amplifia;
}
#endif
/*TR: Added*/
ppairtree_t buildPrimerPairs(pecodnadb_t seqdb,uint32_t seqdbsize,pprimercount_t primers,poptions_t options)
{
uint32_t i;
ppairtree_t primerpairs;
primerpairs = initpairtree(NULL);
for (i=0; i < seqdbsize; i++)
{
buildPrimerPairsForOneSeq(i, seqdb, primers, primerpairs, options);
}
return primerpairs;
}
#define DMAX (2000000000)
static void buildPrimerPairsForOneSeq(uint32_t seqid,
pecodnadb_t seqdb,
pprimercount_t primers,
ppairtree_t pairs,
poptions_t options)
{
static uint32_t paircount=0;
uint32_t i,j,k;
uint32_t matchcount=0;
pprimermatch_t matches = NULL;
//primermatchcount_t seqmatchcount;
ppair_t pcurrent;
pair_t current;
pprimer_t wswp;
bool_t bswp;
size_t distance;
bool_t strand;
//char prmr[50];
//float mtemp;
word_t w1, w1a, omask = (0x1L << (options->strict_three_prime*2)) -1;
word_t w2, w2a;//, wtmp;
uint32_t bp1,bp2;
//prmr[options->primer_length] = '\0';
for (i=0;i < primers->size; i++)
{
matchcount+=primers->primers[i].directCount[seqid];
matchcount+=primers->primers[i].reverseCount[seqid];
}
if (matchcount <= 0)
return;
matches = ECOMALLOC(matchcount * sizeof(primermatch_t),"Cannot allocate primers match table");
for (i=0,j=0;i < primers->size; i++)
{
if (primers->primers[i].directCount[seqid])
{
if (primers->primers[i].directCount[seqid]==1)
{
matches[j].primer = primers->primers+i;
matches[j].strand=TRUE;
matches[j].position=primers->primers[i].directPos[seqid].value;
j++;
}
else for (k=0; k < primers->primers[i].directCount[seqid]; k++,j++)
{
matches[j].primer = primers->primers+i;
matches[j].strand=TRUE;
matches[j].position=primers->primers[i].directPos[seqid].pointer[k];
}
}
if (primers->primers[i].reverseCount[seqid])
{
if (primers->primers[i].reverseCount[seqid]==1)
{
matches[j].primer = primers->primers+i;
matches[j].strand=FALSE;
matches[j].position=primers->primers[i].reversePos[seqid].value;
j++;
}
else for (k=0; k < primers->primers[i].reverseCount[seqid]; k++,j++)
{
matches[j].primer = primers->primers+i;
matches[j].strand=FALSE;
matches[j].position=primers->primers[i].reversePos[seqid].pointer[k];
}
}
}
if (matchcount>1)
{
// fprintf(stderr,"\n====================================\n");
sortmatch(matches,matchcount); // sort in ascending order by position
for (i=0; i < matchcount;i++)
{
// For all primers matching the sequence
/*for(j=i+1;
(j<matchcount)
&& ((distance=matches[j].position - matches[i].position - options->primer_length) < options->lmax);
j++
)//*/
for (j=i+1; j<matchcount; j++)
{
if (matches[j].position - matches[i].position <= options->primer_length) continue;
distance = matches[j].position - matches[i].position - options->primer_length;
if (distance >= options->lmax) break;
// For all not too far primers
if ( (matches[i].primer->good || matches[j].primer->good)
&& (distance > options->lmin)
)
{
// If possible primer pair
current.p1 = matches[i].primer;
current.asdirect1=matches[i].strand;
current.p2 = matches[j].primer;
current.asdirect2= !matches[j].strand;
current.maxd=DMAX;
current.mind=DMAX;
current.sumd=0;
current.amplifiacount=0;
current.inexample=0;
current.outexample=0;
current.curseqid = 0;
current.refsequence=-1;
//current.p1temp = 100;
//current.p1mintemp = 100;
//current.p2temp = 100;
//current.p2mintemp = 100;
// Standardize the pair
strand = current.p2->word > current.p1->word;
if (!strand)
{
wswp = current.p1;
current.p1=current.p2;
current.p2=wswp;
bswp = current.asdirect1;
current.asdirect1=current.asdirect2;
current.asdirect2=bswp;
}
//Code to make sure that if -3 option is given then
//3' end must match upto given number of base pairs
if (options->strict_three_prime > 0)
{
w1 = current.p1->word;
w2 = current.p2->word;
if (!current.asdirect1) //make sure that word is from 5' to 3'
w1=ecoComplementWord(w1,options->primer_length);
if (!current.asdirect2) //make sure that word is from 5' to 3'
w2=ecoComplementWord(w2,options->primer_length);
//now both w1 and w2 are from 5' to 3' end
bp1 = matches[i].position;
bp2 = matches[j].position;
if (!strand)
{
bp1 = matches[j].position;
bp2 = matches[i].position;
}
//get word of first approximate repeat
w1a = extractSite(seqdb[seqid]->SQ,bp1,options->primer_length,strand);
//get word of second approximate repeat
w2a = extractSite(seqdb[seqid]->SQ,bp2,options->primer_length,!strand);
w1 = w1 & omask; //keep only strict_three_prime bases on the right (3') end
w2 = w2 & omask; //keep only strict_three_prime bases on the right (3') end
w1a = w1a & omask; //keep only strict_three_prime bases on the right (3') end
w2a = w2a & omask; //keep only strict_three_prime bases on the right (3') end
//now check that both words and primers of amplifia have same bases on 3' end
if ((w1 ^ w1a) != 0) continue;
if ((w2 ^ w2a) != 0) continue;
}
// Look for the new pair in already seen pairs
pcurrent = insertpair(current,pairs);
if (seqdb[seqid]->isexample)
{
//pcurrent->inexample++;
pcurrent->sumd+=distance;
pcurrent->amplifiacount++;
if ((pcurrent->maxd==DMAX) || (distance > pcurrent->maxd))
pcurrent->maxd = distance;
if (distance < pcurrent->mind)
pcurrent->mind = distance;
}
//else
// pcurrent->outexample++;
//for each pair we save current sequence id in the pair
//when we see this pair for the first time in currnet sequence
//because we want to increment inexample & outexample count
//only once for one sequence
if (pcurrent->curseqid != (seqid+1))
{
if (seqdb[seqid]->isexample)
pcurrent->inexample++;
else
pcurrent->outexample++;
if (pcurrent->curseqid != 0)
pcurrent->curseqid = seqid+1;
}
/*if ((pcurrent->outexample+pcurrent->inexample)==0)
{
fprintf(stderr,"pcurrent->outexample+pcurrent->inexample=0!\n");
exit(0);
}*/
if (pcurrent->curseqid == 0)//((pcurrent->outexample+pcurrent->inexample)==1)
{
pcurrent->curseqid = seqid+1;
paircount++;
pcurrent->pcr.ampslot=200;
pcurrent->pcr.ampcount=0;
pcurrent->pcr.amplifias = ECOMALLOC(sizeof(amplifia_t)*pcurrent->pcr.ampslot,
"Cannot allocate amplifia table");
}
else
{
if (pcurrent->pcr.ampslot==pcurrent->pcr.ampcount)
{
pcurrent->pcr.ampslot+=200;
pcurrent->pcr.amplifias = ECOREALLOC(pcurrent->pcr.amplifias,
sizeof(amplifia_t)*pcurrent->pcr.ampslot,
"Cannot allocate amplifia table");
}
}
if (seqid==options->refseqid)
pcurrent->refsequence=seqid;
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].length=distance;
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].sequence=seqdb[seqid];
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].strand=strand;
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].begin=matches[i].position + options->primer_length;
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].end= matches[j].position - 1;
if (strand)
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].amplifia= seqdb[seqid]->SQ + matches[i].position + options->primer_length;
else
pcurrent->pcr.amplifias[pcurrent->pcr.ampcount].amplifia= seqdb[seqid]->SQ + matches[j].position - 1 ;
/*strncpy (prmr, seqdb[seqid]->SQ + matches[i].position, options->primer_length);
mtemp = nparam_CalcSelfTM (options->pnparm, prmr, options->primer_length) - 273.0;
if (mtemp < pcurrent->p1mintemp)
pcurrent->p1mintemp = mtemp;
//fprintf (stderr, "prmr1: %s\n", seqdb[seqid]->SQ);
strncpy (prmr, seqdb[seqid]->SQ + matches[j].position, options->primer_length);
mtemp = nparam_CalcSelfTM (options->pnparm, prmr, options->primer_length) - 273.0;
if (mtemp < pcurrent->p2mintemp)
pcurrent->p2mintemp = mtemp;
//fprintf (stderr, "prmr2: %s\n", prmr);
if (pcurrent->p1temp == 100)
pcurrent->p1temp = nparam_CalcSelfTM (options->pnparm, ecoUnhashWord(pcurrent->p1->word, options->primer_length), 0) - 273.0;
if (pcurrent->p2temp == 100)
pcurrent->p2temp = nparam_CalcSelfTM (options->pnparm, ecoUnhashWord(pcurrent->p2->word, options->primer_length), 0) - 273.0;
*/
pcurrent->pcr.ampcount++;
// fprintf(stderr,"%c%c W1 : %s direct : %c",
// "bG"[(int)pcurrent->p1->good],
// "bG"[(int)pcurrent->p2->good],
// ecoUnhashWord(pcurrent->p1->word, options->primer_length),
// "><"[(int)pcurrent->asdirect1]
// );
//
// fprintf(stderr," W2 : %s direct : %c distance : %d (min/max/avg : %d/%d/%f) in/out: %d/%d %c (%d pairs)\n",
// ecoUnhashWord(pcurrent->p2->word, options->primer_length),
// "><"[(int)pcurrent->asdirect2],
// distance,
// pcurrent->mind,pcurrent->maxd,
// (pcurrent->inexample) ? (float)pcurrent->sumd/pcurrent->inexample:0.0,
// pcurrent->inexample,pcurrent->outexample,
// " N"[(pcurrent->outexample+pcurrent->inexample)==1],
// paircount
//
// );
//
}
}
}
}
pairs->count=paircount;
}

136
src/libecoprimer/pairtree.c Normal file
View File

@ -0,0 +1,136 @@
/*
* pairtree.c
*
* Created on: 7 mars 2009
* Author: coissac
*/
#include "ecoprimer.h"
#include <search.h>
static void cleanpair(ppair_t pair);
static void deletepairlist(ppairlist_t list);
static int cmppair(const void* p1,const void*p2);
static void cleanamplifiatlist(pamplifiacount_t list)
{
if (list->amplifias)
ECOFREE(list->amplifias,
"Free amplifia list");
}
static void cleanpair(ppair_t pair)
{
cleanamplifiatlist(&(pair->pcr));
}
static ppairlist_t newpairlist(ppairlist_t parent, size_t size)
{
ppairlist_t tmp;
tmp=ECOMALLOC(sizeof(pairlist_t)+sizeof(pair_t)*(size-1),
"Cannot allocate new pair list");
tmp->pairslots=size;
tmp->paircount=0;
tmp->next=NULL;
if (parent)
parent->next=(void*)tmp;
return tmp;
}
static void deletepairlist(ppairlist_t list)
{
size_t i;
if (list)
{
if (list->next)
{
deletepairlist(list->next);
list->next=NULL;
}
for (i=0; i < list->paircount; i++)
cleanpair((list->pairs)+i);
ECOFREE(list,"Delete pair list");
}
}
static int cmppair(const void* p1,const void*p2)
{
ppair_t pr1,pr2;
pr1=(ppair_t)p1;
pr2=(ppair_t)p2;
if (pr1->p1 < pr2->p1) return -1;
if (pr1->p1 > pr2->p1) return 1;
if (pr1->asdirect1 < pr2->asdirect1) return -1;
if (pr1->asdirect1 > pr2->asdirect1) return 1;
if (pr1->p2 < pr2->p2) return -1;
if (pr1->p2 > pr2->p2) return 1;
if (pr1->asdirect2 < pr2->asdirect2) return -1;
if (pr1->asdirect2 > pr2->asdirect2) return 1;
return 0;
}
ppair_t pairintree (pair_t key,
ppairtree_t pairlist)
{
if (!pairlist->tree)
return NULL;
return *((ppair_t*)tsearch((const void *)(&key),
&(pairlist->tree),
cmppair
));
}
ppair_t insertpair(pair_t key,
ppairtree_t list)
{
ppair_t current;
ppair_t found;
if (list->last->paircount==list->last->pairslots)
{
list->last->next=newpairlist(list->last,100);
list->last=list->last->next;
}
current = list->last->pairs + list->last->paircount;
*current=key;
found = *((ppair_t*)tsearch((const void *)current,
&(list->tree),
cmppair));
if (found==current)
list->last->paircount++;
return found;
}
ppairtree_t initpairtree(ppairtree_t tree)
{
if (!tree)
tree = ECOMALLOC(sizeof(pairtree_t),"Cannot allocate pair tree");
tree->first=newpairlist(NULL,300);
tree->last=tree->first;
tree->tree=NULL;
tree->count=0;
return tree;
}

100
src/libecoprimer/queue.c Normal file
View File

@ -0,0 +1,100 @@
/*
* queue.c
*
* Created on: 14 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
pqueue_t newQueue(pqueue_t queue, uint32_t size)
{
if (!queue)
queue = ECOMALLOC(sizeof(queue_t),"Cannot allocate queue structure");
queue->size=0;
resizeQueue(queue,size);
return queue;
}
pqueue_t resizeQueue(pqueue_t queue, uint32_t size)
{
queue->pop=0;
queue->push=0;
queue->empty=TRUE;
queue->full=FALSE;
if (!queue->size)
{
queue->count=ECOMALLOC(size * sizeof(uint32_t),
"Cannot allocate count queue array"
);
queue->words=ECOMALLOC(size * sizeof(word_t),
"Cannot allocate word queue array"
);
queue->size=size;
}
else if (size > queue->size)
{
queue->count=ECOREALLOC(queue->count,
size * sizeof(uint32_t),
"Cannot allocate count queue array"
);
queue->words=ECOREALLOC(queue->words,
size * sizeof(word_t),
"Cannot allocate word queue array"
);
queue->size=size;
}
return queue;
}
pqueue_t cleanQueue(pqueue_t queue)
{
if (queue->size)
{
if (queue->count)
ECOFREE(queue->count,"Free count queue");
if (queue->words)
ECOFREE(queue->words,"Free words queue");
}
queue->size=0;
return queue;
}
void push(pqueue_t queue, word_t word, uint32_t count)
{
ECO_ASSERT(!queue->full,"Queue is full");
queue->count[queue->push]=count;
queue->words[queue->push]=word;
queue->push++;
if (queue->push==queue->size)
queue->push=0;
queue->full=queue->push==queue->pop;
queue->empty=FALSE;
}
void pop(pqueue_t queue)
{
ECO_ASSERT(!queue->empty,"Queue is empty");
queue->pop++;
if (queue->pop==queue->size)
queue->pop=0;
queue->empty=queue->push==queue->pop;
queue->full=FALSE;
}

View File

@ -0,0 +1,59 @@
/*
* readdnadb.c
*
* Created on: 7 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
pecodnadb_t readdnadb(const char *name, ecotaxonomy_t *taxonomy, uint32_t *size,poptions_t options)
{
ecoseq_t *seq;
uint32_t buffsize=100;
pecodnadb_t db;
db = ECOMALLOC(buffsize*sizeof(ecoseq_t*),"I cannot allocate db memory");
for(seq=ecoseq_iterator(name), *size=0;
seq;
seq=ecoseq_iterator(NULL)
)
{
if (isExampleTaxon(taxonomy,seq->taxid,options) ||
isCounterExampleTaxon(taxonomy,seq->taxid,options))
{
if (*size==buffsize)
{
buffsize*=2;
db = ECOREALLOC(db,buffsize*sizeof(ecoseq_t*),"I cannot allocate db memory");
}
db[*size]=seq;
(*size)++;
}
else
{
delete_ecoseq(seq);
}
};
db = ECOREALLOC(db,(*size)*sizeof(ecoseq_t*),"I cannot allocate db memory");
return db;
}
void printSeqTest(pecodnadb_t seqdb,uint32_t seqdbsize)
{
uint32_t i;
char ch[11];
ch [10] = '\0';
for (i=0; i < seqdbsize; i++)
{
strncpy (ch, seqdb[i]->SQ, 10);
fprintf (stderr, "seq %d = %s\n", i, ch);
}
exit (0);
}

View File

@ -0,0 +1,266 @@
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@file smoothsort.c
* @brief Smoothsort implementation
*
* Smoothsort is a in-place sorting algorithm with performance of O(NlogN)
* in worst case and O(n) in best case.
*
* @sa <a href="http://www.enterag.ch/hartwig/order/smoothsort.pdf">
* "Smoothsort, an alternative for sorting in-situ", E.D. Dijkstra, EWD796a</a>,
* &lt;http://www.enterag.ch/hartwig/order/smoothsort.pdf&gt;.
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*/
#include <stdlib.h> /* FB for NULL */
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <inttypes.h> /* <EC> add sto switch from size_t to uint32_t */
/** Description of current stretch */
typedef struct {
uint32_t b, c; /**< Leonardo numbers */
unsigned long long p; /**< Concatenation codification */
} stretch;
/** Description of array */
typedef struct
{
void *m;
int (*less)(void *m, uint32_t a, uint32_t b);
void (*swap)(void *m, uint32_t a, uint32_t b);
} array;
static inline uint32_t stretch_up(stretch s[1])
{
uint32_t next;
s->p >>= 1;
next = s->b + s->c + 1, s->c = s->b, s->b = next;
return next;
}
static inline uint32_t stretch_down(stretch s[1], unsigned bit)
{
uint32_t next;
s->p <<= 1, s->p |= bit;
next = s->c, s->c = s->b - s->c - 1, s->b = next;
return next;
}
#if DEBUG_SMOOTHSORT
static char const *binary(unsigned long long p)
{
static char binary[65];
int i;
if (p == 0)
return "0";
binary[64] = 0;
for (i = 64; p; p >>= 1)
binary[--i] = "01"[p & 1];
return binary + i;
}
#else
#define DEBUG(x) ((void)0)
#endif
/**
* Sift the root of the stretch.
*
* The low values are sifted up (towards index 0) from root.
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of current stretch
*/
static void sift(array const *array, uint32_t r, stretch s)
{
while (s.b >= 3) {
uint32_t r2 = r - s.b + s.c;
if (!array->less(array->m, r - 1, r2)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r))
break;
DEBUG(("\tswap(%p @%zu <=> @%zu)\n", array, r, r2));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
}
}
/** Trinkle the roots of the given stretches
*
* @param array description of array to sort
* @param r root of the stretch
* @param s description of stretches to concatenate
*/
static void trinkle(array const *array, uint32_t r, stretch s)
{
DEBUG(("trinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
while (s.p != 0) {
uint32_t r2, r3;
while ((s.p & 1) == 0)
stretch_up(&s);
if (s.p == 1)
break;
r3 = r - s.b;
if (array->less(array->m, r3, r))
break;
s.p--;
if (s.b < 3) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r3, s.b));
array->swap(array->m, r, r3); r = r3;
continue;
}
r2 = r - s.b + s.c;
if (array->less(array->m, r2, r - 1)) {
r2 = r - 1;
stretch_down(&s, 0);
}
if (array->less(array->m, r2, r3)) {
DEBUG(("swap(%p [%zu]=[%zu])\n", array, r, r3));
array->swap(array->m, r, r3); r = r3;
continue;
}
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r2, s.b));
array->swap(array->m, r, r2); r = r2;
stretch_down(&s, 0);
break;
}
sift(array, r, s);
}
/** Trinkles the stretches when the adjacent stretches are already trusty.
*
* @param array description of array to sort
* @param r root of the stretch
* @param stretch description of stretches to trinkle
*/
static void semitrinkle(array const *array, uint32_t r, stretch s)
{
uint32_t r1 = r - s.c;
DEBUG(("semitrinkle(%p, %zu, (%u, %s))\n", array, r, s.b, binary(s.p)));
if (array->less(array->m, r, r1)) {
DEBUG(("\tswap(%p @%zu <=> @%zu b=%u)\n", array, r, r1, s.b));
array->swap(array->m, r, r1);
trinkle(array, r1, s);
}
}
/** Sort array using smoothsort.
*
* Sort @a N elements from array @a base starting with index @a r with smoothsort.
*
* @param base pointer to array
* @param r lowest index to sort
* @param N number of elements to sort
* @param less comparison function returning nonzero if m[a] < m[b]
* @param swap swapper function exchanging elements m[a] and m[b]
*/
void su_smoothsort(void *base, uint32_t r, uint32_t N,
int (*less)(void *m, uint32_t a, uint32_t b),
void (*swap)(void *m, uint32_t a, uint32_t b))
{
stretch s = { 1, 1, 1 };
uint32_t q;
array const array[1] = {{ base, less, swap }};
assert(less && swap);
if (base == NULL || N <= 1 || less == NULL || swap == NULL)
return;
DEBUG(("\nsmoothsort(%p, %zu)\n", array, nmemb));
for (q = 1; q != N; q++, r++, s.p++) {
DEBUG(("loop0 q=%zu, b=%u, p=%s \n", q, s.b, binary(s.p)));
if ((s.p & 7) == 3) {
sift(array, r, s), stretch_up(&s), stretch_up(&s);
}
else /* if ((s.p & 3) == 1) */ { assert((s.p & 3) == 1);
if (q + s.c < N)
sift(array, r, s);
else
trinkle(array, r, s);
while (stretch_down(&s, 0) > 1)
;
}
}
trinkle(array, r, s);
for (; q > 1; q--) {
s.p--;
DEBUG(("loop1 q=%zu: b=%u p=%s\n", q, s.b, binary(s.p)));
if (s.b <= 1) {
while ((s.p & 1) == 0)
stretch_up(&s);
--r;
}
else /* if b >= 3 */ {
if (s.p) semitrinkle(array, r - (s.b - s.c), s);
stretch_down(&s, 1);
semitrinkle(array, --r, s);
stretch_down(&s, 1);
}
}
}

View File

@ -0,0 +1,51 @@
/*
* sortmatch.c
*
* Created on: 15 d<>c. 2008
* Author: coissac
*/
/*
* sortword.c
*
*
* Created on: 6 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
#include <math.h>
void su_smoothsort(void *base, uint32_t r, uint32_t N,
int (*less)(void *m, uint32_t a, uint32_t b),
void (*swap)(void *m, uint32_t a, uint32_t b));
static int less(void *m, uint32_t a, uint32_t b);
static void swap(void *m, uint32_t a, uint32_t b);
void sortmatch(pprimermatch_t table,uint32_t N)
{
su_smoothsort((void*)table,0,N,less,swap);
}
int less(void *m, uint32_t a, uint32_t b)
{
pprimermatch_t t;
t = (pprimermatch_t)m;
return t[a].position <= t[b].position;
}
void swap(void *m, uint32_t a, uint32_t b)
{
primermatch_t tmp;
pprimermatch_t t;
t = (pprimermatch_t)m;
tmp = t[a];
t[a]= t[b];
t[b]= tmp;
}

View File

@ -0,0 +1,44 @@
/*
* sortword.c
*
*
* Created on: 6 nov. 2008
* Author: coissac
*/
#include "ecoprimer.h"
#include <math.h>
void su_smoothsort(void *base, uint32_t r, uint32_t N,
int (*less)(void *m, uint32_t a, uint32_t b),
void (*swap)(void *m, uint32_t a, uint32_t b));
static int less(void *m, uint32_t a, uint32_t b);
static void swap(void *m, uint32_t a, uint32_t b);
void sortword(pword_t table,uint32_t N)
{
su_smoothsort((void*)table,0,N,less,swap);
}
int less(void *m, uint32_t a, uint32_t b)
{
pword_t t;
t = (pword_t)m;
return WORD(t[a]) <= WORD(t[b]);
}
void swap(void *m, uint32_t a, uint32_t b)
{
word_t tmp;
pword_t t;
t = (pword_t)m;
tmp = t[a];
t[a]= t[b];
t[b]= tmp;
}

View File

@ -0,0 +1,312 @@
/*
* strictprimers.c
*
* Created on: 7 nov. 2008
* Author: coissac
*/
#define _GNU_SOURCE
#include "ecoprimer.h"
#include <string.h>
#include <math.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdio.h>
#ifndef RUSAGE_SELF
#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN -1
#endif
static double timeval_subtract (struct timeval *x, struct timeval *y);
/* Subtract the `struct timeval' values X and Y,
Return elapsed secondes as a double. */
double timeval_subtract (struct timeval *x, struct timeval *y)
{
struct timeval result;
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result.tv_sec = x->tv_sec - y->tv_sec;
result.tv_usec = x->tv_usec - y->tv_usec;
return (double)result.tv_sec + (double)result.tv_usec/1e6;
}
pwordcount_t initCountTable(pwordcount_t table, uint32_t wordsize, uint32_t circular, uint32_t doublestrand,uint32_t seqQuorum,ecoseq_t *seq,int32_t *neededWords,uint32_t neededWordCount)
{
uint32_t i;
uint32_t buffsize;
//wordcount_t t;
if (!table)
table = ECOMALLOC(sizeof(wordcount_t),"Cannot allocate memory for word count structure");
table->words=NULL;
table->size =0;
table->outseqcount=0;
table->inseqcount=0;
table->strictcount =0;
if (seq)
{
table->words = ecoHashSequence(NULL,wordsize,circular,doublestrand,seq,&buffsize,neededWords,neededWordCount,seqQuorum);
table->size = ecoCompactHashSequence(table->words,buffsize);
table->inseqcount=1;
table->strictcount =ECOMALLOC((table->size*sizeof(uint32_t)),
"Cannot allocate memory for word count table"
);
for (i=0; i < table->size; i++) table->strictcount[i]=1;
}
return table;
}
void addSeqToWordCountTable(pwordcount_t table, uint32_t wordsize, uint32_t circular, uint32_t doublestrand,uint32_t exampleCount,uint32_t seqQuorum,ecoseq_t *seq,int32_t *neededWords,uint32_t neededWordCount)
{
uint32_t buffersize;
pword_t newtable;
uint32_t newsize;
uint32_t i;
buffersize = table->size + ecoWordCount(wordsize,circular,seq);
table->words = ECOREALLOC(table->words,buffersize*sizeof(word_t),
"\n\nCannot allocate memory to extend word table" );
/*
* newtable is a pointer on the memory planed to be used for the new sequence (ecoWordCount new hash codes max)
*/
newtable = table->words + table->size;
// DEBUG_LOG("Words = %x (%u) new = %x", table->words,table->size,newtable);
(void)ecoHashSequence(newtable,wordsize,circular,doublestrand,seq,&newsize,neededWords,neededWordCount,seqQuorum);
// DEBUG_LOG("new seq wordCount : %d",newsize);
/*
* at this stage, new hash codes have been added in the table but the table is not sorted
*/
newsize = ecoCompactHashSequence(newtable,newsize);
/*
* new hash codes have now been sorted BUT the whole table is not.
* MULTIWORDS have been tagged (and compacted)
*/
// DEBUG_LOG("compacted wordCount : %d",newsize);
buffersize = table->size + newsize;
/*
* buffersize is now set to the REAL size used by the table (but the memory chunck may be larger)
*/
// resize the count buffer
table->inseqcount++;
//fprintf (stderr, "\nOldAddress: %x", table->strictcount);
table->strictcount = ECOREALLOC(table->strictcount,(buffersize+5000)*sizeof(uint32_t),
"Cannot allocate memory to extend example word count table");
//fprintf (stderr, " NewAddress: %x\n", table->strictcount);
for (i=table->size; i < buffersize; i++)
table->strictcount[i]=1;
/*
* new words in the table are set to a count of ONE
*/
// Now we have to merge in situ the two tables
ecomerge(table,table->size,newsize,exampleCount - table->inseqcount,seqQuorum);
// DEBUG_LOG("Dictionnary size : %d",table->size);
}
pwordcount_t lookforStrictPrimer(pecodnadb_t database, uint32_t seqdbsize,
uint32_t exampleCount,poptions_t options)
{
struct rusage start;
struct rusage usage;
double seconde;
char *logfilename;
FILE *logfile;
uint32_t i, j;
bool_t first=TRUE;
pwordcount_t strictprimers=NULL;
uint64_t totallength=0;
uint32_t sequenceQuorum = (uint32_t)floor((float)exampleCount * options->strict_quorum);
int32_t *neededWords;
uint32_t neededWordCount;
fprintf(stderr,"Filtering... ");
if (options->filtering)
neededWords = filteringSeq(database,seqdbsize,exampleCount,options,&neededWordCount,(int32_t)sequenceQuorum);
else
{
neededWordCount=0;
neededWords=NULL;
}
if (options->statistics)
{
asprintf(&logfilename,"ecoprimer_%d.log",getpid());
logfile = fopen(logfilename,"w");
fprintf(logfile,"# seq\tlength\tsize\ttime\tspeed\n");
fclose(logfile);
}
fprintf(stderr," Primers should be at least present in %d/%d example sequences\n",sequenceQuorum,exampleCount);
strictprimers = initCountTable(NULL,options->primer_length,
options->circular,
options->doublestrand,
0,
NULL,NULL,0);
getrusage(RUSAGE_SELF,&start);
for (i=0;i<seqdbsize;i++)
{
if (database[i]->isexample && database[i]->SQ_length > options->primer_length)
{
if (first)
{
strictprimers = initCountTable(strictprimers,options->primer_length,
options->circular,
options->doublestrand,
sequenceQuorum,
database[i],neededWords,neededWordCount);
first=FALSE;
}
else
{
// uint32_t s;
// s = strictprimers->size;
// DEBUG_LOG("stack size : %u",s);
addSeqToWordCountTable(strictprimers,options->primer_length,
options->circular,
options->doublestrand,
exampleCount,
sequenceQuorum,
database[i],neededWords,neededWordCount);
};
totallength+=database[i]->SQ_length;
getrusage(RUSAGE_SELF,&usage);
if (options->statistics)
{
asprintf(&logfilename,"ecoprimer_%d.log",getpid());
logfile = fopen(logfilename,"a");
seconde = timeval_subtract(&(usage.ru_utime),&(start.ru_utime)) +
timeval_subtract(&(usage.ru_stime),&(start.ru_stime));
fprintf(logfile,"%d\t%llu\t%llu\t%8.3f\t%8.3e\n",i,
(long long unsigned)totallength,
strictprimers->size*(sizeof(int64_t)+sizeof(int32_t)),
seconde,seconde/(double)totallength);
fclose(logfile);
}
}
else
strictprimers->outseqcount++;
fprintf(stderr," Indexed sequences %5d/%5d : considered words %-10llu \r",
(int32_t)i+1,(int32_t)seqdbsize,
(long long unsigned)strictprimers->size);
// DEBUG_LOG("First word : %s ==> %d",ecoUnhashWord(strictprimers->words[0],18),strictprimers->incount[0])
// DEBUG_LOG("Second word : %s ==> %d",ecoUnhashWord(strictprimers->words[1],18),strictprimers->incount[1])
}
strictprimers->strictcount = ECOREALLOC(strictprimers->strictcount,
sizeof(uint32_t)*strictprimers->size,
"Cannot reallocate strict primer count table");
strictprimers->words = ECOREALLOC(strictprimers->words,
sizeof(word_t)*strictprimers->size,
"Cannot reallocate strict primer table");
if (neededWords){
ECOFREE(neededWords,"Clean needed word table");
}
//TR: Somehow for some primers strictcount value is extremely large hence invalid
//we need to remove these primers from the list
j = strictprimers->size+1;
for (i=0; i<strictprimers->size; i++)
{
if (strictprimers->strictcount[i] > seqdbsize)
{
if (j == (strictprimers->size+1))
j = i;
}
if (j < i && strictprimers->strictcount[i] <= seqdbsize)
{
strictprimers->words[j] = strictprimers->words[i];
strictprimers->strictcount[j] = strictprimers->strictcount[i];
j++;
}
}
if (j < strictprimers->size)
{
strictprimers->size = j;
strictprimers->strictcount = ECOREALLOC(strictprimers->strictcount,
sizeof(uint32_t)*strictprimers->size,
"Cannot reallocate strict primer count table");
strictprimers->words = ECOREALLOC(strictprimers->words,
sizeof(word_t)*strictprimers->size,
"Cannot reallocate strict primer table");
}
return strictprimers;
}
uint32_t filterMultiStrictPrimer(pwordcount_t strictprimers)
{
uint32_t i;
uint32_t w;
for (i=0,w=0;i < strictprimers->size;i++)
{
if (w < i)
{
strictprimers->words[w]=strictprimers->words[i];
strictprimers->strictcount[w]=strictprimers->strictcount[i];
}
if (! ISMULTIWORD(strictprimers->words[w]))
w++;
}
strictprimers->size=w;
strictprimers->strictcount = ECOREALLOC(strictprimers->strictcount,
sizeof(uint32_t)*strictprimers->size,
"Cannot reallocate strict primer count table");
strictprimers->words = ECOREALLOC(strictprimers->words,
sizeof(word_t)*strictprimers->size,
"Cannot reallocate strict primer table");
return w;
}

378
src/libecoprimer/taxstats.c Normal file
View File

@ -0,0 +1,378 @@
/*
* taxstats.c
*
* Created on: 12 mars 2009
* Author: coissac
*/
#include <search.h>
//void tdestroy (void *root, void (*free_node)(void *nodep));
#include "ecoprimer.h"
static int cmptaxon(const void *t1, const void* t2);
void **tree_root = NULL;
int delete_passes = 0;
void delete_twalkaction (const void *node, VISIT order, int level)
{
switch (order)
{
case preorder:
delete_passes++;
break;
case postorder:
delete_passes++;
break;
case endorder:
delete_passes++;
break;
case leaf:
if (tree_root)
tdelete (node, tree_root,cmptaxon);
delete_passes++;
break;
}
}
void free_tree_nodes (void *tree)
{
while (1)
{
delete_passes = 0;
twalk (tree, delete_twalkaction);
if (delete_passes <= 1) break;
}
}
static int cmptaxon(const void *t1, const void* t2)
{
const size_t taxid1=(size_t)t1;
const size_t taxid2=(size_t)t2;
// fprintf(stderr,"==> counted taxid1 : %d\n",taxid1);
// fprintf(stderr,"==> counted taxid2 : %d\n",taxid2);
if (taxid1 < taxid2)
return -1;
if (taxid1 > taxid2)
return +1;
return 0;
}
int32_t counttaxon(int32_t taxid)
{
static void* taxontree=NULL;
static int32_t taxoncount=0;
// fprintf(stderr,"counted taxid : %d taxontree %p\n",taxid,taxontree);
if (taxid==-1)
{
if (taxontree)
{
tree_root = (void **)&taxontree;
//free_tree_nodes (taxontree);
ECOFREE(taxontree,"Free taxon tree");
tree_root = NULL;
}
taxontree=NULL;
taxoncount=0;
return 0;
}
if ((taxid > 0) && ((!taxontree) || (!tfind((void*)((size_t)taxid),&taxontree,cmptaxon))))
{
tsearch((void*)((size_t)taxid),&taxontree,cmptaxon);
taxoncount++;
}
return taxoncount;
}
int32_t getrankdbstats(pecodnadb_t seqdb, uint32_t seqdbsize, ecotaxonomy_t *taxonomy,
poptions_t options)
{
uint32_t i;
ecotx_t *taxon;
ecotx_t *tmptaxon;
counttaxon(-1);
options->intaxa = 0;
for (i=0;i<seqdbsize;i++)
{
taxon = &(taxonomy->taxons->taxon[seqdb[i]->taxid]);
seqdb[i]->isexample=isExampleTaxon(taxonomy,seqdb[i]->taxid,options);
tmptaxon = eco_findtaxonatrank(taxon,
options->taxonrankidx);
// fprintf(stderr,"Taxid : %d %p\n",taxon->taxid,tmptaxon);
if (tmptaxon)
{
// fprintf(stderr,"orig : %d trans : %d\n",taxon->taxid,
// tmptaxon->taxid);
seqdb[i]->ranktaxonid=tmptaxon->taxid;
if (seqdb[i]->isexample)
options->intaxa = counttaxon(tmptaxon->taxid);
}
else
seqdb[i]->ranktaxonid=-1;
}
counttaxon(-1);
options->outtaxa = 0;
for (i=0;i<seqdbsize;i++)
{
if (seqdb[i]->ranktaxonid>=0 && !seqdb[i]->isexample)
options->outtaxa = counttaxon(seqdb[i]->ranktaxonid);
}
return options->outtaxa + options->intaxa;
}
float taxonomycoverage(ppair_t pair, poptions_t options, pecodnadb_t seqdb,uint32_t seqdbsize)
{
int32_t seqcount;
int32_t i;
int32_t incount=0;
int32_t outcount=0;
uint32_t j;
memset (pair->coveredSeqs, 0, seqdbsize*sizeof (int));
seqcount=pair->pcr.ampcount;
counttaxon(-1);
for (i=0; i < seqcount; i++)
if (pair->pcr.amplifias[i].sequence->isexample
&& pair->pcr.amplifias[i].sequence->ranktaxonid > 0 )
{
incount = counttaxon(pair->pcr.amplifias[i].sequence->ranktaxonid);
for (j=0; j<seqdbsize; j++)
if (pair->pcr.amplifias[i].sequence == seqdb[j])
{pair->coveredSeqs[j] = 1; break;}
}
counttaxon(-1);
for (i=0; i < seqcount; i++)
if (!pair->pcr.amplifias[i].sequence->isexample
&& pair->pcr.amplifias[i].sequence->ranktaxonid)
outcount = counttaxon(pair->pcr.amplifias[i].sequence->ranktaxonid);
pair->intaxa=incount;
pair->outtaxa=outcount;
pair->bc=(float)incount/options->intaxa;
return pair->bc;
}
/*
static int cmpamp(const void *ampf1, const void* ampf2)
{
int i;
int j = 0;
int incr = 1;
char cd1;
char cd2;
int chd = 0;
int len = 0;
pamptotaxon_t pampf1 = (pamptotaxon_t) ampf1;
pamptotaxon_t pampf2 = (pamptotaxon_t) ampf2;
if (pampf1->strand != pampf2->strand)
{
incr = -1;
j = pampf1->length - 1;
if (pampf2->strand)
{
pampf1 = (pamptotaxon_t) ampf2;
pampf2 = (pamptotaxon_t) ampf1;
chd = 1;
}
//j = pampf2->length - 1; should have been here and pampf2 instead of pampf1?
}
len = (pampf1->length <= pampf2->length)? pampf1->length: pampf2->length;
for (i = 0; i < len; i++, j += incr)
{
cd1 = pampf1->amplifia[i];
if (incr == -1)
cd2 = ecoComplementChar(pampf2->amplifia[j]);
else
cd2 = pampf2->amplifia[j];
if (cd1 < cd2) return chd ? 1: -1;
if (cd2 < cd1) return chd ? -1: 1;
}
if (pampf1->length > pampf2->length) return chd ? -1: 1;
if (pampf2->length > pampf1->length) return chd ? 1: -1;
return 0;
}*/
static int cmpamp(const void *ampf1, const void* ampf2)
{
int i;
char cd1;
char cd2;
int len = 0;
const char *ch1;
const char *ch2;
int incr1;
int incr2;
pamptotaxon_t pampf1 = (pamptotaxon_t) ampf1;
pamptotaxon_t pampf2 = (pamptotaxon_t) ampf2;
ch1 = pampf1->amplifia;
ch2 = pampf2->amplifia;
incr1 = 1;
incr2 = 1;
if (!pampf1->strand)
incr1 = -1;
if (!pampf2->strand)
incr2 = -1;
len = (pampf1->length <= pampf2->length)? pampf1->length: pampf2->length;
for (i = 0; i < len; i++)
{
cd1 = *ch1;
if (incr1 == -1)
cd1 = ecoComplementChar(*ch1);
cd2 = *ch2;
if (incr2 == -1)
cd2 = ecoComplementChar(*ch2);
if (cd1 < cd2) return -1;
if (cd2 < cd1) return 1;
ch1 += incr1;
ch2 += incr2;
}
if (pampf1->length > pampf2->length) return 1;
if (pampf2->length > pampf1->length) return -1;
return 0;
}
void twalkaction (const void *node, VISIT order, int level)
{
int32_t *taxid = (int32_t*)node;
//const size_t taxid=(size_t)node;
//printf ("\t%d:%p, ", *taxid, node);
counttaxon(*taxid);
}
int32_t gtxid;
void twalkaction2 (const void *node, VISIT order, int level)
{
int32_t *pt = (int32_t *) node;
gtxid = *pt;
}
void taxonomyspecificity (ppair_t pair, pecodnadb_t seqdb,uint32_t seqdbsize)
{
uint32_t i, j;
uint32_t ampfindex = 0;
int32_t taxid;
uint32_t wellidentifiedcount;
void *ampftree = NULL;
pamptotaxon_t pcurrentampf;
pamptotaxon_t *ptmp;
pamptotaxon_t ampfwithtaxtree = ECOMALLOC(sizeof(amptotaxon_t) * pair->pcr.ampcount,"Cannot allocate amplifia tree");
for (i = 0; i < pair->pcr.ampcount; i++)
{
/*populate taxon ids tree against each unique amplifia
i.e set of taxon ids for each amplifia*/
if (pair->pcr.amplifias[i].sequence->isexample)
{
ampfwithtaxtree[ampfindex].amplifia = pair->pcr.amplifias[i].amplifia;
ampfwithtaxtree[ampfindex].strand = pair->pcr.amplifias[i].strand;
ampfwithtaxtree[ampfindex].length = pair->pcr.amplifias[i].length;
pcurrentampf = &ampfwithtaxtree[ampfindex];
taxid = pair->pcr.amplifias[i].sequence->ranktaxonid;
ptmp = tfind((const void*)pcurrentampf, &ampftree, cmpamp);
if (ptmp == NULL)
{
pcurrentampf = &ampfwithtaxtree[ampfindex];
tsearch((void*)pcurrentampf,&ampftree,cmpamp);
ampfindex++;
}
else
pcurrentampf = *ptmp;
if (tfind((void*)((size_t)taxid), &(pcurrentampf->taxontree), cmptaxon) == NULL)
{
pcurrentampf->taxoncount++;
tsearch((void*)((size_t)taxid),&(pcurrentampf->taxontree),cmptaxon);
}
}
}
memset (pair->wellIdentifiedSeqs, 0, seqdbsize*sizeof (int));
//counttaxon(-1);
for (i = 0; i < ampfindex; i++)
{
if (ampfwithtaxtree[i].taxoncount > 1)
{
//printf ("\nampfwithtaxtree[i].taxoncount: %d\n", ampfwithtaxtree[i].taxoncount);
//twalk(ampfwithtaxtree[i].taxontree, twalkaction);
}
//TR 5/9/10 - added code for well identified seqs
else if(ampfwithtaxtree[i].taxoncount == 1) /*well identified*/
{
gtxid = -1;
twalk(ampfwithtaxtree[i].taxontree, twalkaction2);
if (gtxid != -1)
{
for (j = 0; j < seqdbsize; j++)
if (seqdb[j]->ranktaxonid == gtxid
&& seqdb[j]->isexample
&&(pair->p1->directCount[j] > 0
|| pair->p1->reverseCount[j] > 0)
&& (pair->p2->directCount[j] > 0
|| pair->p2->reverseCount[j] > 0))
{
pair->wellIdentifiedSeqs[j] = 1;
}
}
}
}
//printf ("\n");
counttaxon(-1);
wellidentifiedcount = 0;
for (j = 0; j < seqdbsize; j++)
if (pair->wellIdentifiedSeqs[j] == 1)
counttaxon(seqdb[j]->ranktaxonid);
wellidentifiedcount = counttaxon(-2);
//pair->notwellidentifiedtaxa = counttaxon(-2);
pair->notwellidentifiedtaxa = (pair->intaxa-wellidentifiedcount); //counttaxon(-2);
//pair->bs = ((float)pair->intaxa - (float)pair->notwellidentifiedtaxa) / pair->intaxa;
pair->bs = ((float)wellidentifiedcount) / (float)pair->intaxa;
ECOFREE (ampfwithtaxtree, "Free amplifia table");
}

View File

@ -1,14 +1,12 @@
SOURCES = KMRK.c \
KMRK_mask.c \
KMRK_merge_seeds.c \
KMRK_Seeds.c
SOURCES = nnparams.c \
thermostats.c
SRCS=$(SOURCES)
OBJECTS= $(patsubst %.c,%.o,$(SOURCES))
LIBFILE= libKMRK.a
LIBFILE= libthermo.a
RANLIB= ranlib

609
src/libthermo/nnparams.c Normal file
View File

@ -0,0 +1,609 @@
/*
* nnparams.cpp
* PHunterLib
*
* Nearest Neighbor Model / Parameters
*
* Created by Tiayyba Riaz on 7/2/09.
*
*/
#include <memory.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include"nnparams.h"
double forbidden_entropy;
char bpencoder[] = { 1, // A
0, // b
2, // C
0,0,0, // d, e, f
3, // G
0,0,0,0,0,0,0,0,0,0,0,0, // h,i,j,k,l,m,n,o,p,q,r,s
4,0, // T,U
0,0,0,0,0}; // v,w,x,y,z
double nparam_GetInitialEntropy(PNNParams nparm)
{
return -5.9f+nparm->rlogc;
}
//Retrieve Enthalpy for given NN-Pair from parameter table
double nparam_GetEnthalpy(PNNParams nparm, char x0, char x1, char y0, char y1)
{
return ndH(x0,x1,y0,y1); //xx, yx are already numbers
}
//Retrieve Entropy for given NN-Pair from parameter table
double nparam_GetEntropy(PNNParams nparm, char x0, char x1, char y0, char y1)
{
//xx and yx are already numbers
char nx0=x0;//nparam_convertNum(x0);
char nx1=x1;//nparam_convertNum(x1);
char ny0=y0;//nparam_convertNum(y0);
char ny1=y1;//nparam_convertNum(y1);
double answer = ndS(nx0,nx1,ny0,ny1);
/*Salt correction Santalucia*/
if (nparm->saltMethod == SALT_METHOD_SANTALUCIA) {
if(nx0!=5 && 1<= nx1 && nx1<=4) {
answer += 0.5*nparm->kfac;
}
if(ny1!=5 && 1<= ny0 && ny0<=4) {
answer += 0.5*nparm->kfac;
}
}
/*Salt correction Owczarzy*/
if (nparm->saltMethod == SALT_METHOD_OWCZARZY) {
double logk = log(nparm->kplus);
answer += ndH(nx0,nx1,ny0,ny1)*((4.29 * nparm->gcContent-3.95)*0.00001*logk+ 0.0000094*logk*logk);
}
return answer;
}
/* PURPOSE: Return melting temperature TM for given entropy and enthalpy
* Assuming a one-state transition and using the formula
* TM = dH / (dS + R ln(Ct/4))
* entropy = dS + R ln Ct/4 (must already be included!)
* enthaklpy = dH
* where
* dH = enthalpy
* dS = entropy
* R = Boltzmann factor
* Ct = Strand Concentration
*
* PARAMETERS:
* entrypy and enthalpy
*
* RETURN VALUE:
* temperature
*/
double nparam_CalcTM(double entropy,double enthalpy)
{
double tm = 0; // absolute zero - return if model fails!
if (enthalpy>=forbidden_enthalpy) //||(entropy==-cfact))
return 0;
if (entropy<0) // avoid division by zero and model errors!
{
tm = enthalpy/entropy;// - kfac; //LKFEB
if (tm<0)
return 0;
}
return tm;
}
void nparam_InitParams(PNNParams nparm, double c1, double c2, double kp, int sm)
{
nparm->Ct1 = c1;
nparm->Ct2 = c2;
nparm->kplus = kp;
int maxCT = 1;
if(nparm->Ct2 > nparm->Ct1)
{
maxCT = 2;
}
double ctFactor;
if(nparm->Ct1 == nparm->Ct2)
{
ctFactor = nparm->Ct1/2;
}
else if (maxCT == 1)
{
ctFactor = nparm->Ct1-nparm->Ct2/2;
}
else
{
ctFactor = nparm->Ct2-nparm->Ct1/2;
}
nparm->rlogc = R * log(ctFactor);
forbidden_entropy = nparm->rlogc;
nparm->kfac = 0.368 * log (nparm->kplus);
nparm->saltMethod = sm;
int x,y,a,b; // variables used as counters...
// Set all parameters to zero!
memset(nparm->dH,0,sizeof(nparm->dH));
memset(nparm->dS,0,sizeof(nparm->dS));
// Set all X-/Y-, -X/Y- and X-/-Y so, that TM will be VERY small!
for (x=1;x<=4;x++)
{
for (y=1;y<=4;y++)
{
ndH(0,x,y,0)=forbidden_enthalpy;
ndS(0,x,y,0)=forbidden_entropy;
ndH(x,0,0,y)=forbidden_enthalpy;
ndS(x,0,0,y)=forbidden_entropy;
ndH(x,0,y,0)=forbidden_enthalpy;
ndS(x,0,y,0)=forbidden_entropy;
// forbid X-/Y$ and X$/Y- etc., i.e. terminal must not be paired with gap!
ndH(x,5,y,0)=forbidden_enthalpy;
ndS(x,5,y,0)=forbidden_entropy;
ndH(x,0,y,5)=forbidden_enthalpy;
ndS(x,0,y,5)=forbidden_entropy;
ndH(5,x,0,y)=forbidden_enthalpy;
ndS(5,x,0,y)=forbidden_entropy;
ndH(0,x,5,y)=forbidden_enthalpy;
ndS(0,x,5,y)=forbidden_entropy;
// forbid X$/-Y etc.
ndH(x,5,0,y)=forbidden_enthalpy;
ndS(x,5,0,y)=forbidden_entropy;
ndH(x,0,5,y)=forbidden_enthalpy;
ndS(x,0,5,y)=forbidden_entropy;
ndH(5,x,y,0)=forbidden_enthalpy;
ndS(5,x,y,0)=forbidden_entropy;
ndH(0,x,y,5)=forbidden_enthalpy;
ndS(0,x,y,5)=forbidden_entropy;
}
// also, forbid x-/-- and --/x-, i.e. no two inner gaps paired
ndH(x,0,0,0)=forbidden_enthalpy;
ndS(x,0,0,0)=forbidden_entropy;
ndH(0,0,x,0)=forbidden_enthalpy;
ndS(0,0,x,0)=forbidden_entropy;
// x-/-$
ndH(x,0,0,5)=forbidden_enthalpy;
ndS(x,0,0,5)=forbidden_entropy;
ndH(5,0,0,x)=forbidden_enthalpy;
ndS(5,0,0,x)=forbidden_entropy;
ndH(0,5,x,0)=forbidden_enthalpy;
ndS(x,0,0,5)=forbidden_entropy;
ndH(0,x,5,0)=forbidden_enthalpy;
ndS(0,x,5,0)=forbidden_entropy;
}
// forbid --/--
ndH(0,0,0,0)=forbidden_enthalpy;
ndS(0,0,0,0)=forbidden_entropy;
ndH(5,0,0,0)=forbidden_enthalpy;
ndS(5,0,0,0)=forbidden_entropy;
ndH(0,0,5,0)=forbidden_enthalpy;
ndS(0,0,5,0)=forbidden_entropy;
ndH(0,5,5,0)=forbidden_enthalpy;
ndS(0,5,5,0)=forbidden_entropy;
// Interior loops (double Mismatches)
#define iloop_entropy -0.97f
#define iloop_enthalpy 0.0f
for (x=1; x<=4; x++)
for (y=1; y<=4; y++)
for (a=1; a<=4; a++)
for (b=1; b<=4; b++)
// AT and CG pair, and as A=1, C=2, G=3, T=4 this means
// we have Watson-Crick pairs if (x+a==5) and (y+b)==5.
if (!((x+a==5)||(y+b==5)))
{
// No watson-crick-pair, i.e. double mismatch!
// set enthalpy/entropy to loop expansion!
ndH(x,y,a,b) = iloop_enthalpy;
ndS(x,y,a,b) = iloop_entropy;
}
// xy/-- and --/xy (Bulge Loops of size > 1)
#define bloop_entropy -1.3f
#define bloop_enthalpy 0.0f
for (x=1; x<=4; x++)
for (y=1; y<=4; y++)
{
ndH(x,y,0,0) = bloop_enthalpy;
ndS(x,y,0,0) = bloop_entropy;
ndH(0,0,x,y) = bloop_enthalpy;
ndS(0,0,x,y) = bloop_entropy;
}
// x-/ya abd xa/y- as well as -x/ay and ax/-y
// bulge opening and closing parameters with
// adjacent matches / mismatches
// obulge_mism and cbulge_mism chosen so high to avoid
// AAAAAAAAA
// T--G----T
// being better than
// AAAAAAAAA
// TG------T
#define obulge_match_H (-2.66f * 1000)
#define obulge_match_S -14.22f
#define cbulge_match_H (-2.66f * 1000)
#define cbulge_match_S -14.22f
#define obulge_mism_H (0.0f * 1000)
#define obulge_mism_S -6.45f
#define cbulge_mism_H 0.0f
#define cbulge_mism_S -6.45f
for (x=1; x<=4; x++)
for (y=1; y<=4; y++)
for (a=1; a<=4; a++)
{
if (x+y==5) // other base pair matches!
{
ndH(x,0,y,a)=obulge_match_H; // bulge opening
ndS(x,0,y,a)=obulge_match_S;
ndH(x,a,y,0)=obulge_match_H;
ndS(x,a,y,0)=obulge_match_S;
ndH(0,x,a,y)=cbulge_match_H; // bulge closing
ndS(0,x,a,y)=cbulge_match_S;
ndH(a,x,0,y)=cbulge_match_H;
ndS(a,x,0,y)=cbulge_match_S;
}
else
{ // mismatch in other base pair!
ndH(x,0,y,a)=obulge_mism_H; // bulge opening
ndS(x,0,y,a)=obulge_mism_S;
ndH(x,a,y,0)=obulge_mism_H;
ndS(x,a,y,0)=obulge_mism_S;
ndH(0,x,a,y)=cbulge_mism_H; // bulge closing
ndS(0,x,a,y)=cbulge_mism_S;
ndH(a,x,0,y)=cbulge_mism_H;
ndS(a,x,0,y)=cbulge_mism_S;
}
}
// Watson-Crick pairs (note that only ten are unique, as obviously
// 5'-AG-3'/3'-TC-5' = 5'-CT-3'/3'-GA-5' etc.
ndH(1,1,4,4)=-7.6f*1000; ndS(1,1,4,4)=-21.3f; // AA/TT 04
ndH(1,2,4,3)=-8.4f*1000; ndS(1,2,4,3)=-22.4f; // AC/TG adapted GT/CA
ndH(1,3,4,2)=-7.8f*1000; ndS(1,3,4,2)=-21.0f; // AG/TC adapted CT/GA
ndH(1,4,4,1)=-7.2f*1000; ndS(1,4,4,1)=-20.4f; // AT/TA 04
ndH(2,1,3,4)=-8.5f*1000; ndS(2,1,3,4)=-22.7f; // CA/GT 04
ndH(2,2,3,3)=-8.0f*1000; ndS(2,2,3,3)=-19.9f; // CC/GG adapted GG/CC
ndH(2,3,3,2)=-10.6f*1000; ndS(2,3,3,2)=-27.2f; // CG/GC 04
ndH(2,4,3,1)=-7.8f*1000; ndS(2,4,3,1)=-21.0f; // CT/GA 04
ndH(3,1,2,4)=-8.2f*1000; ndS(3,1,2,4)=-22.2f; // GA/CT 04
ndH(3,2,2,3)=-9.8f*1000; ndS(3,2,2,3)=-24.4f; // GC/CG 04
ndH(3,3,2,2)=-8.0f*1000; ndS(3,3,2,2)=-19.9f; // GG/CC 04
ndH(3,4,2,1)=-8.4f*1000; ndS(3,4,2,1)=-22.4f; // GT/CA 04
ndH(4,1,1,4)=-7.2f*1000; ndS(4,1,1,4)=-21.3f; // TA/AT 04
ndH(4,2,1,3)=-8.2f*1000; ndS(4,2,1,3)=-22.2f; // TC/AG adapted GA/CT
ndH(4,3,1,2)=-8.5f*1000; ndS(4,3,1,2)=-22.7f; // TG/AC adapted CA/GT
ndH(4,4,1,1)=-7.6f*1000; ndS(4,4,1,1)=-21.3f; // TT/AA adapted AA/TT
// A-C Mismatches (Values for pH 7.0)
ndH(1,1,2,4)=7.6f*1000; ndS(1,1,2,4)=20.2f; // AA/CT
ndH(1,1,4,2)=2.3f*1000; ndS(1,1,4,2)=4.6f; // AA/TC
ndH(1,2,2,3)=-0.7f*1000; ndS(1,2,2,3)=-3.8f; // AC/CG
ndH(1,2,4,1)=5.3f*1000; ndS(1,2,4,1)=14.6f; // AC/TA
ndH(1,3,2,2)=0.6f*1000; ndS(1,3,2,2)=-0.6f; // AG/CC
ndH(1,4,2,1)=5.3f*1000; ndS(1,4,2,1)=14.6f; // AT/CA
ndH(2,1,1,4)=3.4f*1000; ndS(2,1,1,4)=8.0f; // CA/AT
ndH(2,1,3,2)=1.9f*1000; ndS(2,1,3,2)=3.7f; // CA/GC
ndH(2,2,1,3)=5.2f*1000; ndS(2,2,1,3)=14.2f; // CC/AG
ndH(2,2,3,1)=0.6f*1000; ndS(2,2,3,1)=-0.6f; // CC/GA
ndH(2,3,1,2)=1.9f*1000; ndS(2,3,1,2)=3.7f; // CG/AC
ndH(2,4,1,1)=2.3f*1000; ndS(2,4,1,1)=4.6f; // CT/AA
ndH(3,1,2,2)=5.2f*1000; ndS(3,1,2,2)=14.2f; // GA/CC
ndH(3,2,2,1)=-0.7f*1000; ndS(3,2,2,1)=-3.8f; // GC/CA
ndH(4,1,1,2)=3.4f*1000; ndS(4,1,1,2)=8.0f; // TA/AC
ndH(4,2,1,1)=7.6f*1000; ndS(4,2,1,1)=20.2f; // TC/AA
// C-T Mismatches
ndH(1,2,4,4)=0.7f*1000; ndS(1,2,4,4)=0.2f; // AC/TT
ndH(1,4,4,2)=-1.2f*1000; ndS(1,4,4,2)=-6.2f; // AT/TC
ndH(2,1,4,4)=1.0f*1000; ndS(2,1,4,4)=0.7f; // CA/TT
ndH(2,2,3,4)=-0.8f*1000; ndS(2,2,3,4)=-4.5f; // CC/GT
ndH(2,2,4,3)=5.2f*1000; ndS(2,2,4,3)=13.5f; // CC/TG
ndH(2,3,4,2)=-1.5f*1000; ndS(2,3,4,2)=-6.1f; // CG/TC
ndH(2,4,3,2)=-1.5f*1000; ndS(2,4,3,2)=-6.1f; // CT/GC
ndH(2,4,4,1)=-1.2f*1000; ndS(2,4,4,1)=-6.2f; // CT/TA
ndH(3,2,2,4)=2.3f*1000; ndS(3,2,2,4)=5.4f; // GC/CT
ndH(3,4,2,2)=5.2f*1000; ndS(3,4,2,2)=13.5f; // GT/CC
ndH(4,1,2,4)=1.2f*1000; ndS(4,1,2,4)=0.7f; // TA/CT
ndH(4,2,2,3)=2.3f*1000; ndS(4,2,2,3)=5.4f; // TC/CG
ndH(4,2,1,4)=1.2f*1000; ndS(4,2,1,4)=0.7f; // TC/AT
ndH(4,3,2,2)=-0.8f*1000; ndS(4,3,2,2)=-4.5f; // TG/CC
ndH(4,4,2,1)=0.7f*1000; ndS(4,4,2,1)=0.2f; // TT/CA
ndH(4,4,1,2)=1.0f*1000; ndS(4,4,1,2)=0.7f; // TT/AC
// G-A Mismatches
ndH(1,1,3,4)=3.0f*1000; ndS(1,1,3,4)=7.4f; // AA/GT
ndH(1,1,4,3)=-0.6f*1000; ndS(1,1,4,3)=-2.3f; // AA/TG
ndH(1,2,3,3)=0.5f*1000; ndS(1,2,3,3)=3.2f; // AC/GG
ndH(1,3,3,2)=-4.0f*1000; ndS(1,3,3,2)=-13.2f; // AG/GC
ndH(1,3,4,1)=-0.7f*1000; ndS(1,3,4,1)=-2.3f; // AG/TA
ndH(1,4,3,1)=-0.7f*1000; ndS(1,4,3,1)=-2.3f; // AT/GA
ndH(2,1,3,3)=-0.7f*1000; ndS(2,1,3,3)=-2.3f; // CA/GG
ndH(2,3,3,1)=-4.0f*1000; ndS(2,3,3,1)=-13.2f; // CG/GA
ndH(3,1,1,4)=0.7f*1000; ndS(3,1,1,4)=0.7f; // GA/AT
ndH(3,1,2,3)=-0.6f*1000; ndS(3,1,2,3)=-1.0f; // GA/CG
ndH(3,2,1,3)=-0.6f*1000; ndS(3,2,1,3)=-1.0f; // GC/AG
ndH(3,3,1,2)=-0.7f*1000; ndS(3,3,1,2)=-2.3f; // GG/AC
ndH(3,3,2,1)=0.5f*1000; ndS(3,3,2,1)=3.2f; // GG/CA
ndH(3,4,1,1)=-0.6f*1000; ndS(3,4,1,1)=-2.3f; // GT/AA
ndH(4,1,1,3)=0.7f*1000; ndS(4,1,1,3)=0.7f; // TA/AG
ndH(4,3,1,1)=3.0f*1000; ndS(4,3,1,1)=7.4f; // TG/AA
// G-T Mismatches
ndH(1,3,4,4)=1.0f*1000; ndS(1,3,4,4)=0.9f; // AG/TT
ndH(1,4,4,3)=-2.5f*1000; ndS(1,4,4,3)=-8.3f; // AT/TG
ndH(2,3,3,4)=-4.1f*1000; ndS(2,3,3,4)=-11.7f; // CG/GT
ndH(2,4,3,3)=-2.8f*1000; ndS(2,4,3,3)=-8.0f; // CT/GG
ndH(3,1,4,4)=-1.3f*1000; ndS(3,1,4,4)=-5.3f; // GA/TT
ndH(3,2,4,3)=-4.4f*1000; ndS(3,2,4,3)=-12.3f; // GC/TG
ndH(3,3,2,4)=3.3f*1000; ndS(3,3,2,4)=10.4f; // GG/CT
ndH(3,3,4,2)=-2.8f*1000; ndS(3,3,4,2)=-8.0f; // GG/TC
// ndH(3,3,4,4)=5.8f*1000; ndS(3,3,4,4)=16.3f; // GG/TT
ndH(3,4,2,3)=-4.4f*1000; ndS(3,4,2,3)=-12.3f; // GT/CG
ndH(3,4,4,1)=-2.5f*1000; ndS(3,4,4,1)=-8.3f; // GT/TA
// ndH(3,4,4,3)=4.1f*1000; ndS(3,4,4,3)=9.5f; // GT/TG
ndH(4,1,3,4)=-0.1f*1000; ndS(4,1,3,4)=-1.7f; // TA/GT
ndH(4,2,3,3)=3.3f*1000; ndS(4,2,3,3)=10.4f; // TC/GG
ndH(4,3,1,4)=-0.1f*1000; ndS(4,3,1,4)=-1.7f; // TG/AT
ndH(4,3,3,2)=-4.1f*1000; ndS(4,3,3,2)=-11.7f; // TG/GC
// ndH(4,3,3,4)=-1.4f*1000; ndS(4,3,3,4)=-6.2f; // TG/GT
ndH(4,4,1,3)=-1.3f*1000; ndS(4,4,1,3)=-5.3f; // TT/AG
ndH(4,4,3,1)=1.0f*1000; ndS(4,4,3,1)=0.9f; // TT/GA
// ndH(4,4,3,3)=5.8f*1000; ndS(4,4,3,3)=16.3f; // TT/GG
// A-A Mismatches
ndH(1,1,1,4)=4.7f*1000; ndS(1,1,1,4)=12.9f; // AA/AT
ndH(1,1,4,1)=1.2f*1000; ndS(1,1,4,1)=1.7f; // AA/TA
ndH(1,2,1,3)=-2.9f*1000; ndS(1,2,1,3)=-9.8f; // AC/AG
ndH(1,3,1,2)=-0.9f*1000; ndS(1,3,1,2)=-4.2f; // AG/AC
ndH(1,4,1,1)=1.2f*1000; ndS(1,4,1,1)=1.7f; // AT/AA
ndH(2,1,3,1)=-0.9f*1000; ndS(2,1,3,1)=-4.2f; // CA/GA
ndH(3,1,2,1)=-2.9f*1000; ndS(3,1,2,1)=-9.8f; // GA/CA
ndH(4,1,1,1)=4.7f*1000; ndS(4,1,1,1)=12.9f; // TA/AA
// C-C Mismatches
ndH(1,2,4,2)=0.0f*1000; ndS(1,2,4,2)=-4.4f; // AC/TC
ndH(2,1,2,4)=6.1f*1000; ndS(2,1,2,4)=16.4f; // CA/CT
ndH(2,2,2,3)=3.6f*1000; ndS(2,2,2,3)=8.9f; // CC/CG
ndH(2,2,3,2)=-1.5f*1000; ndS(2,2,3,2)=-7.2f; // CC/GC
ndH(2,3,2,2)=-1.5f*1000; ndS(2,3,2,2)=-7.2f; // CG/CC
ndH(2,4,2,1)=0.0f*1000; ndS(2,4,2,1)=-4.4f; // CT/CA
ndH(3,2,2,2)=3.6f*1000; ndS(3,2,2,2)=8.9f; // GC/CC
ndH(4,2,1,2)=6.1f*1000; ndS(4,2,1,2)=16.4f; // TC/AC
// G-G Mismatches
ndH(1,3,4,3)=-3.1f*1000; ndS(1,3,4,3)=-9.5f; // AG/TG
ndH(2,3,3,3)=-4.9f*1000; ndS(2,3,3,3)=-15.3f; // CG/GG
ndH(3,1,3,4)=1.6f*1000; ndS(3,1,3,4)=3.6f; // GA/GT
ndH(3,2,3,3)=-6.0f*1000; ndS(3,2,3,3)=-15.8f; // GC/GG
ndH(3,3,2,3)=-6.0f*1000; ndS(3,3,2,3)=-15.8f; // GG/CG
ndH(3,3,3,2)=-4.9f*1000; ndS(3,3,3,2)=-15.3f; // GG/GC
ndH(3,4,3,1)=-3.1f*1000; ndS(3,4,3,1)=-9.5f; // GT/GA
ndH(4,3,1,3)=1.6f*1000; ndS(4,3,1,3)=3.6f; // TG/AG
// T-T Mismatches
ndH(1,4,4,4)=-2.7f*1000; ndS(1,4,4,4)=-10.8f; // AT/TT
ndH(2,4,3,4)=-5.0f*1000; ndS(2,4,3,4)=-15.8f; // CT/GT
ndH(3,4,2,4)=-2.2f*1000; ndS(3,4,2,4)=-8.4f; // GT/CT
ndH(4,1,4,4)=0.2f*1000; ndS(4,1,4,4)=-1.5f; // TA/TT
ndH(4,2,4,3)=-2.2f*1000; ndS(4,2,4,3)=-8.4f; // TC/TG
ndH(4,3,4,2)=-5.0f*1000; ndS(4,3,4,2)=-15.8f; // TG/TC
ndH(4,4,1,4)=0.2f*1000; ndS(4,4,1,4)=-1.5f; // TT/AT
ndH(4,4,4,1)=-2.7f*1000; ndS(4,4,4,1)=-10.8f; // TT/TA
// Dangling Ends
ndH(5,1,1,4)=-0.7f*1000; ndS(5,1,1,4)=-0.8f; // $A/AT
ndH(5,1,2,4)=4.4f*1000; ndS(5,1,2,4)=14.9f; // $A/CT
ndH(5,1,3,4)=-1.6f*1000; ndS(5,1,3,4)=-3.6f; // $A/GT
ndH(5,1,4,4)=2.9f*1000; ndS(5,1,4,4)=10.4f; // $A/TT
ndH(5,2,1,3)=-2.1f*1000; ndS(5,2,1,3)=-3.9f; // $C/AG
ndH(5,2,2,3)=-0.2f*1000; ndS(5,2,2,3)=-0.1f; // $C/CG
ndH(5,2,3,3)=-3.9f*1000; ndS(5,2,3,3)=-11.2f; // $C/GG
ndH(5,2,4,3)=-4.4f*1000; ndS(5,2,4,3)=-13.1f; // $C/TG
ndH(5,3,1,2)=-5.9f*1000; ndS(5,3,1,2)=-16.5f; // $G/AC
ndH(5,3,2,2)=-2.6f*1000; ndS(5,3,2,2)=-7.4f; // $G/CC
ndH(5,3,3,2)=-3.2f*1000; ndS(5,3,3,2)=-10.4f; // $G/GC
ndH(5,3,4,2)=-5.2f*1000; ndS(5,3,4,2)=-15.0f; // $G/TC
ndH(5,4,1,1)=-0.5f*1000; ndS(5,4,1,1)=-1.1f; // $T/AA
ndH(5,4,2,1)=4.7f*1000; ndS(5,4,2,1)=14.2f; // $T/CA
ndH(5,4,3,1)=-4.1f*1000; ndS(5,4,3,1)=-13.1f; // $T/GA
ndH(5,4,4,1)=-3.8f*1000; ndS(5,4,4,1)=-12.6f; // $T/TA
ndH(1,5,4,1)=-2.9f*1000; ndS(1,5,4,1)=-7.6f; // A$/TA
ndH(1,5,4,2)=-4.1f*1000; ndS(1,5,4,2)=-13.0f; // A$/TC
ndH(1,5,4,3)=-4.2f*1000; ndS(1,5,4,3)=-15.0f; // A$/TG
ndH(1,5,4,4)=-0.2f*1000; ndS(1,5,4,4)=-0.5f; // A$/TT
ndH(1,1,5,4)=0.2f*1000; ndS(1,1,5,4)=2.3f; // AA/$T
ndH(1,1,4,5)=-0.5f*1000; ndS(1,1,4,5)=-1.1f; // AA/T$
ndH(1,2,5,3)=-6.3f*1000; ndS(1,2,5,3)=-17.1f; // AC/$G
ndH(1,2,4,5)=4.7f*1000; ndS(1,2,4,5)=14.2f; // AC/T$
ndH(1,3,5,2)=-3.7f*1000; ndS(1,3,5,2)=-10.0f; // AG/$C
ndH(1,3,4,5)=-4.1f*1000; ndS(1,3,4,5)=-13.1f; // AG/T$
ndH(1,4,5,1)=-2.9f*1000; ndS(1,4,5,1)=-7.6f; // AT/$A
ndH(1,4,4,5)=-3.8f*1000; ndS(1,4,4,5)=-12.6f; // AT/T$
ndH(2,5,3,1)=-3.7f*1000; ndS(2,5,3,1)=-10.0f; // C$/GA
ndH(2,5,3,2)=-4.0f*1000; ndS(2,5,3,2)=-11.9f; // C$/GC
ndH(2,5,3,3)=-3.9f*1000; ndS(2,5,3,3)=-10.9f; // C$/GG
ndH(2,5,3,4)=-4.9f*1000; ndS(2,5,3,4)=-13.8f; // C$/GT
ndH(2,1,5,4)=0.6f*1000; ndS(2,1,5,4)=3.3f; // CA/$T
ndH(2,1,3,5)=-5.9f*1000; ndS(2,1,3,5)=-16.5f; // CA/G$
ndH(2,2,5,3)=-4.4f*1000; ndS(2,2,5,3)=-12.6f; // CC/$G
ndH(2,2,3,5)=-2.6f*1000; ndS(2,2,3,5)=-7.4f; // CC/G$
ndH(2,3,5,2)=-4.0f*1000; ndS(2,3,5,2)=-11.9f; // CG/$C
ndH(2,3,3,5)=-3.2f*1000; ndS(2,3,3,5)=-10.4f; // CG/G$
ndH(2,4,5,1)=-4.1f*1000; ndS(2,4,5,1)=-13.0f; // CT/$A
ndH(2,4,3,5)=-5.2f*1000; ndS(2,4,3,5)=-15.0f; // CT/G$
ndH(3,5,2,1)=-6.3f*1000; ndS(3,5,2,1)=-17.1f; // G$/CA
ndH(3,5,2,2)=-4.4f*1000; ndS(3,5,2,2)=-12.6f; // G$/CC
ndH(3,5,2,3)=-5.1f*1000; ndS(3,5,2,3)=-14.0f; // G$/CG
ndH(3,5,2,4)=-4.0f*1000; ndS(3,5,2,4)=-10.9f; // G$/CT
ndH(3,1,5,4)=-1.1f*1000; ndS(3,1,5,4)=-1.6f; // GA/$T
ndH(3,1,2,5)=-2.1f*1000; ndS(3,1,2,5)=-3.9f; // GA/C$
ndH(3,2,5,3)=-5.1f*1000; ndS(3,2,5,3)=-14.0f; // GC/$G
ndH(3,2,2,5)=-0.2f*1000; ndS(3,2,2,5)=-0.1f; // GC/C$
ndH(3,3,5,2)=-3.9f*1000; ndS(3,3,5,2)=-10.9f; // GG/$C
ndH(3,3,2,5)=-3.9f*1000; ndS(3,3,2,5)=-11.2f; // GG/C$
ndH(3,4,5,1)=-4.2f*1000; ndS(3,4,5,1)=-15.0f; // GT/$A
ndH(3,4,2,5)=-4.4f*1000; ndS(3,4,2,5)=-13.1f; // GT/C$
ndH(4,5,1,1)=0.2f*1000; ndS(4,5,1,1)=2.3f; // T$/AA
ndH(4,5,1,2)=0.6f*1000; ndS(4,5,1,2)=3.3f; // T$/AC
ndH(4,5,1,3)=-1.1f*1000; ndS(4,5,1,3)=-1.6f; // T$/AG
ndH(4,5,1,4)=-6.9f*1000; ndS(4,5,1,4)=-20.0f; // T$/AT
ndH(4,1,5,4)=-6.9f*1000; ndS(4,1,5,4)=-20.0f; // TA/$T
ndH(4,1,1,5)=-0.7f*1000; ndS(4,1,1,5)=-0.7f; // TA/A$
ndH(4,2,5,3)=-4.0f*1000; ndS(4,2,5,3)=-10.9f; // TC/$G
ndH(4,2,1,5)=4.4f*1000; ndS(4,2,1,5)=14.9f; // TC/A$
ndH(4,3,5,2)=-4.9f*1000; ndS(4,3,5,2)=-13.8f; // TG/$C
ndH(4,3,1,5)=-1.6f*1000; ndS(4,3,1,5)=-3.6f; // TG/A$
ndH(4,4,5,1)=-0.2f*1000; ndS(4,4,5,1)=-0.5f; // TT/$A
ndH(4,4,1,5)=2.9f*1000; ndS(4,4,1,5)=10.4f; // TT/A$
return;
}
int nparam_CountGCContent(char * seq ) {
int lseq = strlen(seq);
int k;
double count = 0;
for( k=0;k<lseq;k++) {
if (seq[k] == 'G' || seq[k] == 'C' ) {
count+=1;
}
}
return count;
}
void nparam_CleanSeq (const char* inseq, char* outseq, int len)
{
int seqlen = strlen (inseq);
int i, j;
if (len != 0)
seqlen = len;
outseq[0]='x';
for (i = 0, j = 0; i < seqlen && outseq[0]; i++,j++)
{
switch (inseq[i])
{
case 'a':
case '\0':
case 'A':
outseq[j] = 'A'; break;
case 'c':
case '\1':
case 'C':
outseq[j] = 'C'; break;
case 'g':
case '\2':
case 'G':
outseq[j] = 'G'; break;
case 't':
case '\3':
case 'T':
outseq[j] = 'T'; break;
default:
outseq[0]=0;
}
}
outseq[j] = '\0';
}
//Calculate TM for given sequence against its complement
double nparam_CalcSelfTM(PNNParams nparm, const char* seq, size_t len)
{
double thedH = 0;
//double thedS = nparam_GetInitialEntropy(nparm);
double thedS = -5.9f+nparm->rlogc;
double mtemp;
char c1;
char c2;
char c3;
char c4;
unsigned int i;
char nseq[50];
const char *useq = seq;
nparam_CleanSeq (seq, nseq, len);
useq = nseq;
for ( i=1;i<len;i++)
{
c1 = GETREVCODE(useq[i-1]); //nparam_getComplement(seq[i-1],1);
c2 = GETREVCODE(useq[i]); //nparam_getComplement(seq[i],1);
c3 = GETNUMCODE(useq[i-1]);
c4 = GETNUMCODE(useq[i]);
thedH += nparm->dH[(uint8_t) c3][(uint8_t)c4][(uint8_t)c1][(uint8_t)c2];//nparam_GetEnthalpy(nparm, c3,c4,c1,c2);
thedS += nparam_GetEntropy(nparm, c3,c4,c1,c2);
}
//printf("------------------\n");
mtemp = nparam_CalcTM(thedS,thedH);
//fprintf(stderr,"Enthalpy: %f, entropy: %f, seq: %s rloc=%f\n", thedH, thedS, useq, nparm->rlogc);
//exit (0);
return mtemp;
}
double nparam_CalcTwoTM(PNNParams nparm, const char* seq1, const char* seq2, size_t len)
{
double thedH = 0;
//double thedS = nparam_GetInitialEntropy(nparm);
double thedS = -5.9f+nparm->rlogc;
double mtemp;
char c1;
char c2;
char c3;
char c4;
unsigned int i;
char nseq1[50];
char nseq2[50];
char *useq1;
char *useq2;
nparam_CleanSeq (seq1, nseq1, len);
useq1 = nseq1;
nparam_CleanSeq (seq2, nseq2, len);
useq2 = nseq2;
//fprintf (stderr,"Primer : %s\n",useq);
for ( i=1;i<len;i++)
{
c1 = GETREVCODE(useq2[i-1]); //nparam_getComplement(seq[i-1],1);
c2 = GETREVCODE(useq2[i]); //nparam_getComplement(seq[i],1);
c3 = GETNUMCODE(useq1[i-1]);
c4 = GETNUMCODE(useq1[i]);
//fprintf (stderr,"Primer : %s %f %f %d %d, %d %d %f\n",useq,thedH,thedS,(int)c3,(int)c4,(int)c1,(int)c2,nparam_GetEnthalpy(nparm, c3,c4,c1,c2));
thedH += nparm->dH[(uint8_t)c3][(uint8_t)c4][(uint8_t)c1][(uint8_t)c2];//nparam_GetEnthalpy(nparm, c3,c4,c1,c2);
thedS += nparam_GetEntropy(nparm, c3,c4,c1,c2);
}
//fprintf(stderr,"------------------\n");
mtemp = nparam_CalcTM(thedS,thedH);
//if (mtemp == 0)
//{
// fprintf(stderr,"Enthalpy: %f, entropy: %f, seq: %s\n", thedH, thedS, useq);
//exit (0);
//}
return mtemp;
}
double calculateMeltingTemperatureBasic (char * seq) {
int gccount;
double temp;
int seqlen;
seqlen = strlen (seq);
gccount = nparam_CountGCContent (seq);
temp = 64.9 + 41*(gccount - 16.4)/seqlen;
return temp;
}

67
src/libthermo/nnparams.h Normal file
View File

@ -0,0 +1,67 @@
/*
* nnparams.h
* PHunterLib
*
* Nearest Neighbor Model Parameters
*
* Created by Tiayyba Riaz on 02/07/09.
*
*/
#ifndef NNPARAMS_H_
#define NNPARAMS_H_
#include <math.h>
#include <string.h>
#include <stdint.h>
//#include "../libecoprimer/ecoprimer.h"
// following defines to simplify coding...
#define ndH(a,b,c,d) nparm->dH[(uint8_t) a][(uint8_t) b][(uint8_t) c][(uint8_t) d]
#define ndS(a,b,c,d) nparm->dS[(uint8_t) a][(uint8_t) b][(uint8_t) c][(uint8_t) d]
#define forbidden_enthalpy 1000000000000000000.0f
#define R 1.987f
#define SALT_METHOD_SANTALUCIA 1
#define SALT_METHOD_OWCZARZY 2
#define DEF_CONC_PRIMERS 0.0000008
#define DEF_CONC_SEQUENCES 0
#define DEF_SALT 0.05
#define GETNUMCODE(a) bpencoder[a - 'A']
#define GETREVCODE(a) 5-bpencoder[a - 'A']
extern double forbidden_entropy;
extern char bpencoder[]; // v,w,x,y,z
typedef struct CNNParams_st
{
double Ct1;
double Ct2;
double rlogc;
double kplus;
double kfac;
int saltMethod;
double gcContent;
double new_TM;
double dH[6][6][6][6]; // A-C-G-T + gap + initiation (dangling end, $ sign)
double dS[6][6][6][6];
}CNNParams, * PNNParams;
void nparam_InitParams(PNNParams nparm, double c1, double c2, double kp, int sm);
int nparam_CountGCContent(char * seq );
double nparam_GetEntropy(PNNParams nparm, char x0, char x1, char y0, char y1);
double nparam_GetEnthalpy(PNNParams nparm, char x0, char x1, char y0, char y1);
double nparam_CalcTM(double entropy,double enthalpy);
double nparam_CalcSelfTM(PNNParams nparm, const char* seq, size_t len);
double nparam_CalcTwoTM(PNNParams nparm, const char* seq1, const char* seq2, size_t len);
double nparam_GetInitialEntropy(PNNParams nparm) ;
double calculateMeltingTemperatureBasic (char * seq);
//void getThermoProperties (ppair_t* pairs, size_t count, poptions_t options);
#endif

113
src/libthermo/thermostats.c Normal file
View File

@ -0,0 +1,113 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "thermostats.h"
word_t extractSite(char* sequence, size_t begin, size_t length, bool_t strand)
{
char *c;
char *start;
uint32_t l;
word_t site = 0;
start=sequence+begin;
if (!strand)
start+=length-1;
for (c=start,
l=0;
l<length;
l++,
c+=(strand)? 1:-1)
site = (site << 2) | ((strand)? (*c):(~*c)&3);
return site;
}
void getThermoProperties (ppair_t* pairs, size_t count, poptions_t options)
{
size_t i, j;
uint32_t bp1,bp2;
word_t w1;
word_t w2;
bool_t strand;
char *sq;
char prmrd[50];
char prmrr[50];
double mtemp;
for (i = 0; i < count; i++)
{
w1 = pairs[i]->p1->word;
w2 = pairs[i]->p2->word;
if (!pairs[i]->asdirect1)
w1=ecoComplementWord(w1,options->primer_length);
if (!pairs[i]->asdirect2)
w2=ecoComplementWord(w2,options->primer_length);
strncpy(prmrd,ecoUnhashWord(w1, options->primer_length),options->primer_length);
strncpy(prmrr,ecoUnhashWord(w2, options->primer_length),options->primer_length);
prmrd[options->primer_length]=0;
prmrr[options->primer_length]=0;
pairs[i]->p1temp = nparam_CalcSelfTM (options->pnparm, prmrd, options->primer_length) - 273.0;
pairs[i]->p2temp = nparam_CalcSelfTM (options->pnparm, prmrr, options->primer_length) - 273.0;
pairs[i]->p1mintemp = 100;
pairs[i]->p2mintemp = 100;
for (j = 0; j < pairs[i]->pcr.ampcount; j++)
if (pairs[i]->pcr.amplifias[j].sequence->isexample)
{
sq = pairs[i]->pcr.amplifias[j].sequence->SQ;
strand = pairs[i]->pcr.amplifias[j].strand;
bp1 = pairs[i]->pcr.amplifias[j].begin - options->primer_length;
bp2 = pairs[i]->pcr.amplifias[j].end + 1;
if (!strand)
{
uint32_t tmp;
tmp=bp1;
bp1=bp2;
bp2=tmp;
}
// printf("%s : %s, %c",prmrd,
// ecoUnhashWord(extractSite(sq,bp1,options->primer_length,strand),options->primer_length),
// "rd"[strand]);
mtemp = nparam_CalcTwoTM(options->pnparm,
prmrd,
ecoUnhashWord(extractSite(sq,bp1,options->primer_length,strand),options->primer_length),
options->primer_length) - 273.0;
// printf(" %4.2f %4.2f\n",pairs[i]->p1temp,mtemp);
if (mtemp < pairs[i]->p1mintemp)
pairs[i]->p1mintemp = mtemp;
// printf("%s : %s, %c\n",prmrr,ecoUnhashWord(extractSite(sq,bp2,options->primer_length,!strand),options->primer_length),
// "rd"[strand]);
//
mtemp = nparam_CalcTwoTM(options->pnparm,
prmrr,
ecoUnhashWord(extractSite(sq,bp2,options->primer_length,!strand),options->primer_length),
options->primer_length) - 273.0;
if (mtemp < pairs[i]->p2mintemp)
pairs[i]->p2mintemp = mtemp;
}
if (w2 < w1)
{
mtemp = pairs[i]->p1temp;
pairs[i]->p1temp = pairs[i]->p2temp;
pairs[i]->p2temp = mtemp;
mtemp = pairs[i]->p1mintemp;
pairs[i]->p1mintemp = pairs[i]->p2mintemp;
pairs[i]->p2mintemp = mtemp;
}
}
}

View File

@ -0,0 +1,9 @@
#ifndef THERMOSTATS_H_
#define THERMOSTATS_H_
#include "../libecoprimer/ecoprimer.h"
void getThermoProperties (ppair_t* pairs, size_t count, poptions_t options);
word_t extractSite(char* sequence, size_t begin, size_t length, bool_t strand);
#endif

View File

@ -1,31 +0,0 @@
/**
*
* J Jr SantaLucia.
* A uni<6E>ed view of polymer, dumbbell, and oligonucleotide
* dna nearest-neighbor thermodynamics.
* Proc Natl Acad Sci U S A, 95(4):1460<36>1465, 1998 Feb 17.
*/
//Nearest-neighbor sequence
//(5'-3'/5'-3') deltaH deltaS
// kcal/mol cal/(mol<6F>K)
//AA/TT -7.9 -22.2
//AG/CT -7.8 -21.0
//AT/AT -7.2 -20.4
//AC/GT -8.4 -22.4
//GA/TC -8.2 -22.2
//GG/CC -8.0 -19.9
//GC/GC -9.8 -24.4
//TA/TA -7.2 -21.3
//TG/CA -8.5 -22.7
//CG/CG -10.6 -27.2
//Terminal A-T base pair 2.3 4.1
//Terminal G-C base pair 0.1 -2.8
float nearestNeighborTm(const char *oligo,float probe,float target)
{
}

696
tools/ecoPCRFormat.py Executable file
View File

@ -0,0 +1,696 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import re
import gzip
import struct
import sys
import time
import getopt
import zlib
_dbenable = False
#####
#
#
# Generic file function
#
#
#####
def universalOpen(file):
if isinstance(file, str):
if file.endswith('.gz'):
if sys.version_info[0] < 3:
rep = gzip.open(file)
else:
rep = gzip.open(file, 'rt', encoding='latin-1')
else:
rep = open(file, 'r')
else:
rep = file
return rep
def universalTell(file):
if hasattr(file, 'myfileobj'): # Python 3 gzip
return file.myfileobj.tell()
elif hasattr(file, 'fileobj'): # Python 2 gzip
return file.fileobj.tell()
return file.tell()
def fileSize(file):
if hasattr(file, 'myfileobj'): # Python 3 gzip
f = file.myfileobj
elif hasattr(file, 'fileobj'): # Python 2 gzip
f = file.fileobj
else:
f = file
if not hasattr(f, 'fileno'):
return None
pos = f.tell()
f.seek(0, 2)
length = f.tell()
f.seek(pos, 0)
return length
def progressBar(pos, max_size, reset=False, delta=[]):
if reset:
del delta[:]
if not delta:
delta.append(time.time())
delta.append(time.time())
delta[1] = time.time()
elapsed = delta[1] - delta[0]
if max_size is None:
sys.stderr.write('\rReaded sequences : %d ' % pos)
sys.stderr.flush()
return
percent = float(pos) / max_size * 100 if max_size > 0 else 0
if percent > 0:
remain = elapsed / percent * (100 - percent)
remain_str = time.strftime('%H:%M:%S', time.gmtime(int(remain)))
else:
remain_str = '?'
bar_length = 50
filled = int(percent / 2)
bar = '#' * filled
bar += '|/-\\'[pos % 4]
bar += ' ' * (bar_length - filled - 1)
sys.stderr.write('\r%5.1f %% |%s] remain : %s' % (percent, bar, remain_str))
sys.stderr.flush()
#####
#
#
# NCBI Dump Taxonomy reader
#
#
#####
class endLessIterator(object):
def __init__(self, endedlist):
self.endedlist = endedlist
self.index = 0
def __iter__(self):
return self
def next(self): # Python 2
if self.index < len(self.endedlist):
item = self.endedlist[self.index]
self.index += 1
return item
else:
return self.endedlist[-1]
__next__ = next # Python 3 compatibility
class ColumnFile(object):
def __init__(self, stream, sep=None, strip=True, types=None):
if isinstance(stream, str):
self._stream = open(stream)
else:
try:
iter(stream)
self._stream = stream
except TypeError:
raise ValueError('stream must be string or an iterator')
self._delimiter = sep
self._strip = strip
self._types = types
@staticmethod
def str2bool(x):
val = x.strip()[0].upper()
if val in 'T1Y':
return True
elif val in 'F0N':
return False
raise ValueError("Invalid boolean value: %s" % x)
def __iter__(self):
return self
def next(self): # Python 2
ligne = next(self._stream)
data = ligne.split(self._delimiter)
if self._strip:
data = [x.strip() for x in data]
if self._types:
typed_data = []
for i, val in enumerate(data):
if i < len(self._types):
t = self._types[i]
if t is bool:
typed_data.append(self.str2bool(val))
else:
typed_data.append(t(val))
else:
typed_data.append(val)
return typed_data
return data
__next__ = next # Python 3 compatibility
def bsearchTaxon(taxonomy, taxid):
taxCount = len(taxonomy)
begin = 0
end = taxCount
oldcheck = -1
check = int(begin + (end - begin) / 2)
while check != oldcheck and check < taxCount and taxonomy[check][0] != taxid:
if taxonomy[check][0] < taxid:
begin = check
else:
end = check
oldcheck = check
check = int(begin + (end - begin) / 2)
if check < taxCount and taxonomy[check][0] == taxid:
return check
return None
def readNodeTable(file):
file = universalOpen(file)
nodes = ColumnFile(file,
sep='|',
types=(int, int, str,
str, str, bool,
int, bool, int,
bool, bool, bool, str))
print("Reading taxonomy dump file...", file=sys.stderr)
sys.stderr.flush()
taxonomy = []
for n in nodes:
taxonomy.append([n[0], n[2], n[1]])
print("List all taxonomy rank...", file=sys.stderr)
sys.stderr.flush()
ranks = list(set(x[1] for x in taxonomy))
ranks.sort()
rank_dict = {rank: idx for idx, rank in enumerate(ranks)}
print("Sorting taxons...", file=sys.stderr)
sys.stderr.flush()
taxonomy.sort(key=lambda x: x[0])
print("Indexing taxonomy...", file=sys.stderr)
sys.stderr.flush()
index = {}
for i, t in enumerate(taxonomy):
index[t[0]] = i
print("Indexing parent and rank...", file=sys.stderr)
sys.stderr.flush()
for t in taxonomy:
t[1] = rank_dict[t[1]]
t[2] = index.get(t[2], None)
return taxonomy, rank_dict, index
def nameIterator(file):
file = universalOpen(file)
names = ColumnFile(file,
sep='|',
types=(int, str, str, str))
for row in names:
if len(row) >= 4:
taxid, name, unique, classname = row[:4]
yield taxid, name, classname
def mergedNodeIterator(file):
file = universalOpen(file)
merged = ColumnFile(file,
sep='|',
types=(int, int, str))
for row in merged:
if len(row) >= 2:
taxid, current = row[:2]
yield taxid, current
def deletedNodeIterator(file):
file = universalOpen(file)
deleted = ColumnFile(file,
sep='|',
types=(int, str))
for row in deleted:
if row:
taxid = row[0]
yield taxid
def readTaxonomyDump(taxdir):
taxonomy, ranks, index = readNodeTable(taxdir + '/nodes.dmp')
# Initialize scientific name as empty string for each taxon
for tx in taxonomy:
tx.append("") # Add fourth element: scientific name (empty at start)
print("Adding scientific name...", file=sys.stderr)
sys.stderr.flush()
alternativeName = []
for taxid, name, classname in nameIterator(taxdir + '/names.dmp'):
idx = index.get(taxid, None)
if idx is not None:
# Clean and ensure ASCII only
name_clean = ''.join(c for c in name if ord(c) < 128)
alternativeName.append((name_clean, classname, idx))
if classname == 'scientific name':
taxonomy[idx][3] = name_clean
print("Adding taxid alias...", file=sys.stderr)
sys.stderr.flush()
for taxid, current in mergedNodeIterator(taxdir + '/merged.dmp'):
if current in index:
index[taxid] = index[current]
print("Adding deleted taxid...", file=sys.stderr)
sys.stderr.flush()
for taxid in deletedNodeIterator(taxdir + '/delnodes.dmp'):
index[taxid] = None
return taxonomy, ranks, alternativeName, index
#####
#
#
# Genbank/EMBL sequence reader
#
#
#####
def entryIterator(file):
file = universalOpen(file)
rep = []
ligne = file.readline()
while ligne:
rep.append(ligne)
if ligne == '//\n':
yield ''.join(rep)
rep = []
ligne = file.readline()
if rep:
yield ''.join(rep)
def fastaEntryIterator(file):
file = universalOpen(file)
rep = []
ligne = file.readline()
while ligne:
if ligne.startswith('>') and rep:
yield ''.join(rep)
rep = []
rep.append(ligne)
ligne = file.readline()
if rep:
yield ''.join(rep)
_cleanSeq = re.compile(r'[\s\d]') # More efficient
def cleanSeq(seq):
return _cleanSeq.sub('', seq)
# GenBank patterns
_gbParseID = re.compile(r'(?<=^LOCUS {7})[^ ]+(?= )', re.MULTILINE)
_gbParseDE = re.compile(r'(?<=^DEFINITION {2}).+?\. *$', re.MULTILINE | re.DOTALL)
_gbParseSQ = re.compile(r'(?<=^ORIGIN).+?(?=^//$)', re.MULTILINE | re.DOTALL)
_gbParseTX = re.compile(r'(?<= /db_xref="taxon:)[0-9]+(?=")')
def genbankEntryParser(entry):
Id_match = _gbParseID.findall(entry)
Id = Id_match[0] if Id_match else "UNKNOWN_ID"
De_match = _gbParseDE.findall(entry)
De = ' '.join(De_match[0].split()) if De_match else ""
Sq_match = _gbParseSQ.findall(entry)
Sq = cleanSeq(Sq_match[0].upper()) if Sq_match else ""
Tx_match = _gbParseTX.findall(entry)
Tx = int(Tx_match[0]) if Tx_match else None
# Clean and ensure ASCII only
Id = ''.join(c for c in Id if ord(c) < 128)
De = ''.join(c for c in De if ord(c) < 128)
return {'id': Id, 'taxid': Tx, 'definition': De, 'sequence': Sq}
# EMBL patterns
_emblParseID = re.compile(r'(?<=^ID {3})[^ ]+(?=;)', re.MULTILINE)
_emblParseDE = re.compile(r'(?<=^DE {3}).+?\. *$', re.MULTILINE | re.DOTALL)
_emblParseSQ = re.compile(r'(?<=^ ).+?(?=^//$)', re.MULTILINE | re.DOTALL)
_emblParseTX = re.compile(r'(?<= /db_xref="taxon:)[0-9]+(?=")')
def emblEntryParser(entry):
Id_match = _emblParseID.findall(entry)
Id = Id_match[0] if Id_match else "UNKNOWN_ID"
De_match = _emblParseDE.findall(entry)
De = ' '.join(De_match[0].replace('\nDE ', ' ').split()) if De_match else ""
Sq_match = _emblParseSQ.findall(entry)
Sq = cleanSeq(Sq_match[0].upper()) if Sq_match else ""
Tx_match = _emblParseTX.findall(entry)
Tx = int(Tx_match[0]) if Tx_match else None
# Clean and ensure ASCII only
Id = ''.join(c for c in Id if ord(c) < 128)
De = ''.join(c for c in De if ord(c) < 128)
return {'id': Id, 'taxid': Tx, 'definition': De, 'sequence': Sq}
# FASTA processing
_fastaSplit = re.compile(r';\W*')
def parseFasta(seq):
lines = seq.split('\n')
if not lines:
return "", "", "", {}
header = lines[0].strip()
if header.startswith('>'):
header = header[1:]
parts = header.split(None, 1)
seq_id = parts[0] if parts else ""
description = parts[1] if len(parts) > 1 else ""
fields = _fastaSplit.split(description) if description else []
info = {}
other_desc = []
for field in fields:
if '=' in field:
key, val = field.split('=', 1)
info[key.strip()] = val.strip()
else:
other_desc.append(field)
definition = ' '.join(other_desc)
sequence = ''.join(x.strip() for x in lines[1:]).upper()
# Clean and ensure ASCII only
seq_id = ''.join(c for c in seq_id if ord(c) < 128)
definition = ''.join(c for c in definition if ord(c) < 128)
return seq_id, sequence, definition, info
def fastaEntryParser(entry):
seq_id, sequence, definition, info = parseFasta(entry)
Tx = info.get('taxid', None)
if Tx is not None:
try:
Tx = int(Tx)
except ValueError:
Tx = None
return {'id': seq_id, 'taxid': Tx, 'definition': definition, 'sequence': sequence}
def sequenceIteratorFactory(entryParser, entryIterator):
def sequenceIterator(file):
for entry in entryIterator(file):
yield entryParser(entry)
return sequenceIterator
#####
#
#
# Binary writer (CORRECTED VERSION)
#
#
#####
def ecoSeqPacker(sq):
# Ensure sequence is ASCII uppercase
sequence = ''.join(c for c in sq['sequence'] if ord(c) < 128).upper()
seq_bytes = sequence.encode('ascii')
compactseq = zlib.compress(seq_bytes, 9)
cptseqlength = len(compactseq)
# Clean definition to pure ASCII
definition = ''.join(c for c in sq['definition'] if ord(c) < 128)
de_bytes = definition.encode('ascii')
delength = len(de_bytes)
# Clean ID to pure ASCII and pad to 20 bytes
seq_id = ''.join(c for c in sq['id'] if ord(c) < 128)
seq_id_bytes = seq_id.encode('ascii')
if len(seq_id_bytes) > 20:
seq_id_bytes = seq_id_bytes[:20]
else:
seq_id_bytes = seq_id_bytes.ljust(20, b'\0')
# Calculate total size (4 bytes for each integer + data lengths)
totalSize = 4 + 20 + 4 + 4 + 4 + delength + cptseqlength
# Pack with correct byte order and field order
packed = struct.pack('>I', totalSize)
packed += struct.pack('>I', sq['taxid'])
packed += seq_id_bytes
packed += struct.pack('>I', delength)
packed += struct.pack('>I', len(sequence))
packed += struct.pack('>I', cptseqlength)
packed += de_bytes
packed += compactseq
return packed
def ecoTaxPacker(tx):
# Clean name to pure ASCII
name_clean = ''.join(c for c in tx[3] if ord(c) < 128)
name_bytes = name_clean.encode('ascii')
namelength = len(name_bytes)
totalSize = 4 + 4 + 4 + 4 + namelength
packed = struct.pack('>I', totalSize)
packed += struct.pack('>I', tx[0]) # taxid
packed += struct.pack('>I', tx[1]) # rank index
packed += struct.pack('>I', tx[2]) # parent index
packed += struct.pack('>I', namelength)
packed += name_bytes
return packed
def ecoRankPacker(rank):
# Clean rank to pure ASCII
rank_clean = ''.join(c for c in rank if ord(c) < 128)
rank_bytes = rank_clean.encode('ascii')
namelength = len(rank_bytes)
packed = struct.pack('>I', namelength)
packed += rank_bytes
return packed
def ecoNamePacker(name):
# Clean name and class to pure ASCII
name_clean = ''.join(c for c in name[0] if ord(c) < 128)
class_clean = ''.join(c for c in name[1] if ord(c) < 128)
name_bytes = name_clean.encode('ascii')
class_bytes = class_clean.encode('ascii')
namelength = len(name_bytes)
classlength = len(class_bytes)
totalSize = 4 + 4 + 4 + 4 + namelength + classlength
packed = struct.pack('>I', totalSize)
packed += struct.pack('>I', 1 if name[1] == 'scientific name' else 0)
packed += struct.pack('>I', namelength)
packed += struct.pack('>I', classlength)
packed += struct.pack('>I', name[2]) # taxon index
packed += name_bytes
packed += class_bytes
return packed
def ecoSeqWriter(file, input_file, taxindex, parser):
output = open(file, 'wb')
input_stream = universalOpen(input_file)
inputsize = fileSize(input_stream)
entries = parser(input_stream)
seqcount = 0
skipped = []
# Write placeholder for sequence count
output.write(struct.pack('>I', 0))
progressBar(0, inputsize, reset=True)
for entry in entries:
if entry['taxid'] is not None:
try:
# Convert to integer taxid
taxid_int = int(entry['taxid'])
# Lookup in taxindex
entry['taxid'] = taxindex.get(taxid_int, None)
except (ValueError, TypeError):
entry['taxid'] = None
if entry['taxid'] is not None:
seqcount += 1
packed = ecoSeqPacker(entry)
output.write(packed)
else:
skipped.append(entry['id'])
# Update progress
if inputsize is not None:
where = universalTell(input_stream)
progressBar(where, inputsize)
else:
progressBar(seqcount, seqcount + 1) # Fake progress
sys.stderr.write(" Readed sequences : %d \r" % seqcount)
sys.stderr.flush()
print("\n", file=sys.stderr)
# Update sequence count at beginning of file
output.seek(0)
output.write(struct.pack('>I', seqcount))
output.close()
return skipped
def ecoTaxWriter(file, taxonomy):
output = open(file, 'wb')
output.write(struct.pack('>I', len(taxonomy)))
for tx in taxonomy:
output.write(ecoTaxPacker(tx))
output.close()
def ecoRankWriter(file, ranks):
output = open(file, 'wb')
rank_list = sorted(ranks.keys())
output.write(struct.pack('>I', len(rank_list)))
for rank in rank_list:
output.write(ecoRankPacker(rank))
output.close()
def ecoNameWriter(file, names):
output = open(file, 'wb')
output.write(struct.pack('>I', len(names)))
# Sort case-insensitive
names.sort(key=lambda x: x[0].lower())
for name in names:
output.write(ecoNamePacker(name))
output.close()
def ecoDBWriter(prefix, taxonomy, seqFileNames, parser):
ecoRankWriter(prefix + '.rdx', taxonomy[1])
ecoTaxWriter(prefix + '.tdx', taxonomy[0])
ecoNameWriter(prefix + '.ndx', taxonomy[2])
filecount = 0
for filename in seqFileNames:
filecount += 1
outfile = "%s_%03d.sdx" % (prefix, filecount)
print("\nProcessing:", filename, file=sys.stderr)
skipped = ecoSeqWriter(outfile, filename, taxonomy[3], parser)
if skipped:
print("\nSkipped entries without valid taxonomy:", file=sys.stderr)
for sid in skipped:
print(sid, file=sys.stderr)
else:
print("All entries processed successfully", file=sys.stderr)
def ecoParseOptions(arguments):
opt = {
'prefix': 'ecodb',
'taxdir': 'taxdump',
'parser': sequenceIteratorFactory(genbankEntryParser, entryIterator)
}
try:
o, filenames = getopt.getopt(arguments,
'ht:T:n:gfe',
['help',
'taxonomy=',
'taxonomy_db=',
'name=',
'genbank',
'fasta',
'embl'])
except getopt.GetoptError as err:
print(str(err), file=sys.stderr)
printHelp()
sys.exit(2)
for name, value in o:
if name in ('-h', '--help'):
printHelp()
sys.exit()
elif name in ('-t', '--taxonomy'):
opt['taxdir'] = value
elif name in ('-n', '--name'):
opt['prefix'] = value
elif name in ('-g', '--genbank'):
opt['parser'] = sequenceIteratorFactory(genbankEntryParser, entryIterator)
elif name in ('-f', '--fasta'):
opt['parser'] = sequenceIteratorFactory(fastaEntryParser, fastaEntryIterator)
elif name in ('-e', '--embl'):
opt['parser'] = sequenceIteratorFactory(emblEntryParser, entryIterator)
else:
raise ValueError('Unknown option: %s' % name)
return opt, filenames
def printHelp():
print("-----------------------------------")
print(" ecoPCRFormat.py")
print("-----------------------------------")
print("Converts sequence databases to ecoPCR format")
print("Usage: ecoPCRFormat.py [options] <files>")
print("Options:")
print(" -e, --embl Input in EMBL format")
print(" -f, --fasta Input in FASTA format")
print(" -g, --genbank Input in GenBank format (default)")
print(" -h, --help Show this help message")
print(" -n NAME, --name=NAME Database prefix (default: ecodb)")
print(" -t DIR, --taxonomy=DIR Taxonomy directory (default: taxdump)")
print("-----------------------------------")
if __name__ == '__main__':
try:
opt, filenames = ecoParseOptions(sys.argv[1:])
if not filenames:
print("Error: No input files specified", file=sys.stderr)
printHelp()
sys.exit(1)
print("Loading taxonomy...", file=sys.stderr)
taxonomy = readTaxonomyDump(opt['taxdir'])
print("Processing sequence files...", file=sys.stderr)
ecoDBWriter(opt['prefix'], taxonomy, filenames, opt['parser'])
print("Database creation complete", file=sys.stderr)
except Exception as e:
print("Error: " + str(e), file=sys.stderr)
import traceback
traceback.print_exc()
sys.exit(1)