Compare commits
82 Commits
kmr-versio
...
master
Author | SHA1 | Date | |
---|---|---|---|
d4fa8b43a4 | |||
b7552200bd | |||
791aeb0ef9 | |||
1e3f82bb51 | |||
f1ef2caae6 | |||
680cc4d7a2 | |||
09f3e19f32 | |||
08debff2ac | |||
e16e9bfa0c | |||
7fbea9d63f | |||
9a9fb383ad | |||
8c1668faa4 | |||
92826de147 | |||
73236c72a8 | |||
eb8d44528d | |||
2b3a331602 | |||
a75191bbe6 | |||
3cfbf8ba42 | |||
efb4fba78c | |||
66c0511f09 | |||
ea1ca1b6d9 | |||
58a65f7ff4 | |||
4315aecbf0 | |||
aedee0c154 | |||
9e36754fef | |||
9262e954cf | |||
1f5a30b0df | |||
19887e9a46 | |||
e77c6e5339 | |||
4c9c8382fe | |||
5d8103f4b4 | |||
ca1e9d8899 | |||
dd08d73dda | |||
e483b17e18 | |||
396d6e2028 | |||
3f488baa6f | |||
fd13788289 | |||
82d5e21471 | |||
0f4f2a74fe | |||
b3d6acae76 | |||
89576b96fa | |||
9e6b924c92 | |||
2737cf0606 | |||
6f5f2a16f3 | |||
088b5c09d0 | |||
f1f8562918 | |||
1911880bb9 | |||
494791d133 | |||
79cadf0809 | |||
419bda966d | |||
455bf63949 | |||
b625941d72 | |||
ba26734e9b | |||
50c26e81b9 | |||
e79738e170 | |||
91753ace82 | |||
f142d0e904 | |||
b4d8842f31 | |||
1cae92e963 | |||
3a617890ca | |||
40644bc85f | |||
c192908469 | |||
b0521a7e15 | |||
b7c1640042 | |||
5dc55c7f53 | |||
04ee4e531c | |||
b092497eaf | |||
6624181788 | |||
81ada091bf | |||
c5a430ea80 | |||
c308fb2edc | |||
796274d746 | |||
c36bc5e838 | |||
313dd59f5a | |||
e869d6daed | |||
93b327285a | |||
e3d922e103 | |||
b8af5dd65f | |||
4f9d76f0f2 | |||
b5b0ca7e9d | |||
64838c1cdf | |||
6d8bb449d5 |
98
.cproject
98
.cproject
@ -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
15
.gitignore
vendored
Normal 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
|
60
.project
60
.project
@ -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
7
.pydevproject
Normal 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>
|
44
src/Makefile
44
src/Makefile
@ -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
|
||||
|
1021
src/ecoprimer.c
1021
src/ecoprimer.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
|
1009
src/libKMRK/KMRK.c
1009
src/libKMRK/KMRK.c
File diff suppressed because it is too large
Load Diff
@ -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_
|
@ -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);
|
||||
};
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
|
||||
}
|
@ -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 */
|
@ -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));
|
||||
}
|
@ -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_*/
|
@ -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_ */
|
||||
|
@ -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 */
|
@ -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 */
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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) $@
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
|
||||
SOURCES = ecoapat.c \
|
||||
ecodna.c \
|
||||
SOURCES = ecodna.c \
|
||||
ecoError.c \
|
||||
ecoIOUtils.c \
|
||||
ecoMalloc.c \
|
||||
|
@ -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--;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
*/
|
||||
|
@ -17,3 +17,4 @@ int eco_is_taxid_included( ecotaxonomy_t *taxonomy,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
39
src/libecoprimer/Makefile
Normal 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) $@
|
1772
src/libecoprimer/PrimerSets.c
Normal file
1772
src/libecoprimer/PrimerSets.c
Normal file
File diff suppressed because it is too large
Load Diff
58
src/libecoprimer/PrimerSets.h
Normal file
58
src/libecoprimer/PrimerSets.h
Normal 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
478
src/libecoprimer/ahocorasick.c
Executable 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
43
src/libecoprimer/ahocorasick.h
Executable 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 */
|
||||
|
131
src/libecoprimer/amplifiatree.c
Normal file
131
src/libecoprimer/amplifiatree.c
Normal 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
120
src/libecoprimer/apat.h
Normal 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 */
|
||||
|
65
src/libecoprimer/apat_parse.c
Normal file
65
src/libecoprimer/apat_parse.c
Normal 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 */
|
||||
/* -------------------------------------------- */
|
155
src/libecoprimer/apat_search.c
Normal file
155
src/libecoprimer/apat_search.c
Normal 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);
|
||||
}
|
||||
|
237
src/libecoprimer/aproxpattern.c
Normal file
237
src/libecoprimer/aproxpattern.c
Normal 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,¶ms,&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,¶ms,&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
29
src/libecoprimer/debug.h
Normal 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_ */
|
366
src/libecoprimer/ecoprimer.h
Normal file
366
src/libecoprimer/ecoprimer.h
Normal 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_ */
|
14
src/libecoprimer/ecotype.h
Normal file
14
src/libecoprimer/ecotype.h
Normal 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_ */
|
222
src/libecoprimer/filtering.c
Normal file
222
src/libecoprimer/filtering.c
Normal 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;
|
||||
|
||||
}
|
64
src/libecoprimer/goodtaxon.c
Normal file
64
src/libecoprimer/goodtaxon.c
Normal 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;
|
||||
}
|
13
src/libecoprimer/hashencoder.h
Normal file
13
src/libecoprimer/hashencoder.h
Normal 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_ */
|
272
src/libecoprimer/hashsequence.c
Normal file
272
src/libecoprimer/hashsequence.c
Normal 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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
7
src/libecoprimer/mapping.c
Normal file
7
src/libecoprimer/mapping.c
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* mapping.c
|
||||
*
|
||||
* Created on: 25 nov. 2008
|
||||
* Author: coissac
|
||||
*/
|
||||
|
201
src/libecoprimer/merge.c
Normal file
201
src/libecoprimer/merge.c
Normal 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
460
src/libecoprimer/pairs.c
Normal 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
136
src/libecoprimer/pairtree.c
Normal 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
100
src/libecoprimer/queue.c
Normal 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;
|
||||
}
|
59
src/libecoprimer/readdnadb.c
Normal file
59
src/libecoprimer/readdnadb.c
Normal 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);
|
||||
}
|
266
src/libecoprimer/smothsort.c
Normal file
266
src/libecoprimer/smothsort.c
Normal 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>,
|
||||
* <http://www.enterag.ch/hartwig/order/smoothsort.pdf>.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
51
src/libecoprimer/sortmatch.c
Normal file
51
src/libecoprimer/sortmatch.c
Normal 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;
|
||||
}
|
||||
|
44
src/libecoprimer/sortword.c
Normal file
44
src/libecoprimer/sortword.c
Normal 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;
|
||||
}
|
||||
|
312
src/libecoprimer/strictprimers.c
Normal file
312
src/libecoprimer/strictprimers.c
Normal 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
378
src/libecoprimer/taxstats.c
Normal 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 = &fwithtaxtree[ampfindex];
|
||||
taxid = pair->pcr.amplifias[i].sequence->ranktaxonid;
|
||||
ptmp = tfind((const void*)pcurrentampf, &ftree, cmpamp);
|
||||
if (ptmp == NULL)
|
||||
{
|
||||
pcurrentampf = &fwithtaxtree[ampfindex];
|
||||
tsearch((void*)pcurrentampf,&ftree,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");
|
||||
|
||||
}
|
@ -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
609
src/libthermo/nnparams.c
Normal 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
67
src/libthermo/nnparams.h
Normal 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
113
src/libthermo/thermostats.c
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
9
src/libthermo/thermostats.h
Normal file
9
src/libthermo/thermostats.h
Normal 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
|
@ -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
696
tools/ecoPCRFormat.py
Executable 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)
|
||||
|
Reference in New Issue
Block a user